Spring Events

1 Introduction:

As long as it is an event, it is an observer mode, and the Event in Spring is no exception. The main application is program decoupling, and the essence of implementation is in the form of broadcasting...not much nonsense

2 Spring's event implementation method:

Just inherit ApplicationEvent, but after Spring version 4.2, it is no longer mandatory to inherit ApplicationEvent, and non-Application subclasses will be encapsulated into PayloadApplicationEvent:

accomplish:

import org.springframework.context.ApplicationEvent;

public class MyEvent extends ApplicationEvent {
    //todo -----  
    private String msg;

    public MyEvent(Object source) {
        super(source);
    }

    public MyEvent(Object source,String msg) {
        super(source);
        this.msg=msg;
    }

    public String getMsg() {
        return msg;
    }
}

3 Push events:

Write an event push service to implement the ApplicationContextAwar interface, or implement the ApplicationEventPublisherAware interface, and push events according to business scenarios when needed:

accomplish:


@Service
public class EventProduceService implements ApplicationContextAware, ApplicationEventPublisherAware {
    //实现方式一
    private ApplicationContext applicationContext;
    //实现方式二
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 容器初始化时候会自动的填装该对象
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     *  容器初始化时候会自动的填装该对象
     * @param applicationEventPublisher
     */
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher=applicationEventPublisher;
    }


    /**
     * 实际业务中进行封装数据推送
     */
    public void sentEvent(){
        //方式一:applicationContext的推送Api可以以根据需要进行选择
        applicationContext.publishEvent(new MyEvent(this,"我是一颗小码农"));
        //方式二: applicationEventPublisher的推送Api可以以根据需要进行选择
        applicationEventPublisher.publishEvent(new MyEvent(this,"今天是20220804"));
    }
}

4 event listeners (processors):

Write the event handler and hand it over to Spring's ioc management. There are two ways to implement it.

(1) Annotate the corresponding event handler with the @EventListener annotation, and the handler will automatically identify the event type according to the parameter type

accomplish:

@Configuration
public class EventConfig {
    @EventListener
    public void doWithEvent(MyEvent myEvent) {
        System.out.println("事件消息是: "+myEvent.getMsg());
    }

   @EventListener
   public void doWithEvent(BEvent myEvent) {
       System.out.println("事件消息是: "+myEvent.getMsg());
   }

    @EventListener
    public void doWithEvent(CEvent myEvent) {
        System.out.println("事件消息是: "+myEvent.getMsg());
    }
}

(2) Implement the ApplicationListener<T> interface, and the processor will handle events according to the generic type

accomplish

@Component
public class EventHandler implements ApplicationListener<MyEvent> {

    @Override
    public void onApplicationEvent(MyEvent event) {
        //todo----
        System.out.println(event.getMsg());
    }
}

5 asynchronous events:

The events monitored by Spring by default are all synchronous. To implement asynchronous events, you need to enable asynchronous event support. Use the @EventListener annotation on the configuration class to enable asynchronous support, and then use the @Async annotation on the listener to mark it. Multiple events for the same event Processors can be sorted using the @Order annotation (the smaller the parameter, the higher the priority)

accomplish:


@Configuration
@EnableAsync
public class EventConfig {
    @Async
    @EventListener
    public void doWithEvent(MyEvent myEvent) {
        System.out.println("事件消息是: "+myEvent.getMsg());
    }
}


@Async//配置类已经开启异步支持
@Component
public class EventHandler implements ApplicationListener<MyEvent> {

    @Override
    public void onApplicationEvent(MyEvent event) {
        //todo----
        System.out.println(event.getMsg());
    }
}

6 Event exception handler (necessary processing if an exception occurs on the event consumer)

(1) Synchronous:

Write an exception handler to implement org.springframework.util.ErrorHandler

import org.springframework.stereotype.Component;
import org.springframework.util.ErrorHandler;

//同步方式异常处理器
@Component
public class DoExphandler implements ErrorHandler {
    /**
     * 只要在SimpleApplicationEventMulticaster设置这个异常处理器,
     * 事件消费方抛出异常就会触发这个方法中的异常,SimpleApplicationEventMulticaster.setErrorHandler(exphandler);
     */
    @Override
    public void handleError(Throwable e) {
        if (e instanceof RuntimeException) {
            //todo
        } else {
        }
    }
}

 Set the exception handler for consumer events in the SimpleApplicationEventMulticaster event broadcast

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class EventProduceService implements ApplicationContextAware, ApplicationEventPublisherAware {
    //实现方式一
    private ApplicationContext applicationContext;
    //实现方式二
    private ApplicationEventPublisher applicationEventPublisher;

    //事件推送类注入广播处理同步异常
    @Autowired
    private SimpleApplicationEventMulticaster saem;

    @Autowired
    private DoExphandler exphandler;


    /**
     * 容器初始化时候会自动的填装该对象
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 容器初始化时候会自动的填装该对象
     *
     * @param applicationEventPublisher
     */
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }



    public void sentEvent2(Object msg) {
        applicationContext.publishEvent(new MyEvent2((String) msg));
    }


    /**
     * 设置初始化的事件异常处理器
     */
    @PostConstruct
    public void  init(){
        saem.setErrorHandler(exphandler);
    }


}

(2) Asynchronous:

Write an asynchronous event handler exception class and implement the AsyncUncaughtExceptionHandler interface

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


@Component
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable ex,
                                        Method method,
                                        Object... params) {
        //todo,做相关处理
        ex.printStackTrace();
    }
}

Do asynchronous event exception configuration:

Implement the AsyncConfigurer interface


import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;

import java.util.concurrent.Executor;

@Configuration
public class AsyncConfig implements AsyncConfigurer {
    @Autowired
    private AsyncExceptionHandler asyncExceptionHandler;

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return asyncExceptionHandler;
    }

    @Override
    public Executor getAsyncExecutor() {
        System.out.println("getAsyncExecutor");
        return AsyncConfigurer.super.getAsyncExecutor();
    }
}

7 Events that come with java:

(1) Observer mode:

Function: decoupling, decoupling...others are nonsense

Pattern work idea: a observes b, after b makes certain actions, a will follow up the actions in time (as for what a does, it depends on what you need him to do)

Design idea: a responds according to the state changes of b. In general, multiple objects observe one object. At this time, the observed object b needs to perceive which objects are observing itself (set a collection to store these objects)

Observer: (the top-level interface has been made in java.util.Observer)

public  interface  MyObserver {
  void  update(ObserverHandler handler);
}

class MyObserverImp implements MyObserver{
  private int status;

  /**
   * 根据被观察者对象适应自身动作
   * @param handler 被观察者对象
   */
  @Override
  public void update(ObserverHandler handler) {
    status=((Handler)handler).getStatus();
  }

Observable: (java.util. Observable has been adapted)


interface ObserverHandler {
    //存储观察者,感知都有那些对象在观察
    List<MyObserver> list = new ArrayList<>();
}

class Handler implements ObserverHandler {
    private int status;

    public void setStatus(int status) {
        this.status = status;
        updateAllStatus();
    }

    public int getStatus() {
        return status;
    }

    public void updateAllStatus() {
        for (MyObserver myObserver : list) {
            myObserver.update(this);
        }
    }

    public void addObserver(MyObserver observer) {
        list.add(observer);
    }

    public void removeObserver(MyObserver observer) {
        list.remove(observer);
    }
}

(2) Java events:

Create event inheritance java.util.EventObject

public class UserEvent extends EventObject {

    public UserEvent(Object source) {
        super(source);
    }
}

class SendMessageEvent extends UserEvent {

    public SendMessageEvent(Object source) {
        super(source);
    }
}

class SendFileEvent extends UserEvent {

    public SendFileEvent(Object source) {
        super(source);
    }
}

Create event listener inheritance: java.util.EventListener

interface UserListener extends EventListener {
    static final ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();

    void doWithEvent(UserEvent event);
}

class Listener implements UserListener {

    @Override
    public void doWithEvent(UserEvent event) {
        if (event instanceof SendFileEvent) {
            System.out.println(event);
        } else if (event instanceof SendMessageEvent) {
            System.out.println(event);
        }
    }
}

Push event:


class SendEventHandler {

    private static UserListener listener = new Listener();

    public static void main(String[] args) {
        final SendMessageEvent sentMessage = new SendMessageEvent("发送事件");
        final SendFileEvent sendFile = new SendFileEvent("发送文件");
        listener.doWithEvent(sentMessage);
        listener.doWithEvent(sendFile);
    }
}

Guess you like

Origin blog.csdn.net/weixin_45874214/article/details/126167211