Observer design pattern

It is better to understand the observer design pattern with subscriptions and publications. Why is that? Because the word listener sounds like an active thing, but actually a listener is a passive thing like we have an event source that publishes an event, and then the listener subscribes to that event and can do something. There are three objects involved: the event source, the event, and the listener. You can understand that when an event occurs, the listener is notified. Event source: Specifies the event source to which the current event belongsCopy the code

1. Observer design pattern

Features:

  • The observer holds a reference to the observer listening
  • The observed supports adding and deleting observers
  • Notifies observer of observed state change

The Observer implements Observer overrides the update method

  • When the observed changes, receive notification for specific action
  • Can be cancelled at any time
  • The observed needs the extends Observable

advantages

Loose coupling

  • The observer does not need to modify the observed code to add or delete, but simply calls the observed method to add or delete
  • The observed is only responsible for notifying the observer, but does not need to know how the observer handles the notification
  • The observer simply waits for the observed to be notified, and does not need to observe the details of the observed

Notice not missed

Due to passive acceptance, notifications of subject changes are normally not missed. Active acquisition, on the other hand, may cause some states to be missed due to timing issues.Copy the code

Implementation of the JDK in Java

Java has an API for observer mode

  • java.util.ObservableThis is a class that is inherited by the observer
  • java.util.observerThis is an interface that the observer implements

The importance of switches

  • You can filter notifications
  • Notice can be revoked
  • You can control notifications
public void move(a) {
    // This is the switch
    setChanged();
    // Invoke the corresponding observer
    notifyObservers();
}
Copy the code

2. Implementation in Spring

2.1 Events in Spring

Events by org. Springframework. Context. ApplicationEvent instance. This abstract class inheritance extends java.util.EventObject, and using the getSource method in EventObject, we can easily get the object for a given event that occurred. Here, there are two types of events

  1. Associated with the application context

    All of this type of event inherited from org. Springframework. Context. Event. ApplicationContextEvent class. They are applied in the org. Springframework. Context. ApplicationContext trigger event is the constructor of the incoming (ApplicationContext type parameters). In this way, we can get the events that occurred directly through the lifecycle of the application context: ContextStartedEvent is started when the context is started, ContextStoppedEvent is started when it stops, ContextRefreshedEvent is generated when the context is refreshed, and finally ContextClosedEvent is generated when the context is closed

  2. Associated with the Request request

    By the org. Springframework. Web. Context. Support. RequestHandledEvent instance, when the request is processed in the ApplicationContext, they are triggered.

2.2 How does Spring assign events to dedicated listeners?

The process to achieve by event broadcast, by the org. Springframework. Context. Event. ApplicationEventMulticaster said the implementation of the interface. This interface defines three methods:

  1. addApplicationListener()Adding a new listener ** : Two methods are defined to add a new listener: **addApplicationListener(ApplicationListener<? > listener)andAddApplicationListenerBean (String listenerBeanName). When the listener object is known, the first one can be applied. If we use the second, we need to get the bean name to the Listener object (Rely on finding DL) and then add it tolistenerIn the list
  2. RemoveApplicationListenerBean (String listenerBeanName) delete the listener: Add methods, we can by passing objects to remove a listener (* * removeApplicationListener (ApplicationListener
    listener)** or by passing the bean name. The third method, **removeAllListeners()**, is used to remove all registered listeners
  3. **multicastEvent(ApplicationEvent Event)** Sends events to registered listeners.

2.2.1 inheritanceApplicationEventMulticasterThe class of the interface

AbstractApplicationEventMulticaster, SimpleApplicationEventMulticaster, these two classes is very important, is the use of these two classes of springboot.

Source code analysis: This part of the source code analysis can be seen in this blog post: SpringBoot source code Analysis (a) ApplicationListener

3. Write your own listener

Write in Spring, because there is no change to the source, so write listener slightly changed.

  1. Test.java

    public class Test {
    	public static void main(String[] args) {
    		AnnotationConfigApplicationContext context =
    				new AnnotationConfigApplicationContext(App.class);
    
    		MailBean bean = context.getBean(MailBean.class);
    		// Publish a SpringMailEvent eventbean.sendMail(); }}Copy the code
  2. MailBean.java

    @Component
    public class MailBean {
    
    	@Autowired
    	ApplicationContext applicationContext;
    
    	public void sendMail(a) {
    		// ApplicationContext is also an event source.
    		// Publish an event
    		applicationContext.publishEvent(newSpringMailEvent(applicationContext)); }}Copy the code
  3. SpringMailEvent.java

    public class SpringMailEvent extends ApplicationEvent{
        // Can be the content of the event
        private String content;
    
        public SpringMailEvent(Object source) {
            super(source);
        }
    
        public String getContent(a) {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content; }}Copy the code
  4. SpringMailListener.java

    @Component
    public class SpringMailListener implements ApplicationListener<SpringMailEvent> {
    	@Override
    	public void onApplicationEvent(SpringMailEvent event) {
    		System.out.println("mail send========"); }}Copy the code