spring事件

2019-06-20  本文已影响0人  xzz4632

在spring容器中是通过ApplicationEvent类和ApplicationListener接口来处理事件的.如果某个bean实现了ApplicationListener接口并被部署到容器中, 那么每次对应的ApplicationEvent被发布到容器中时,都会通知该bean.这是典型的观察者模式.

spring的事件默认是同步的,即调用publisEvent()方法发布事件后, 它会处于阻塞状态, 直到onApplicationEvent接收到事件并处理完返回之后才会继续往下执行, 这种单线程同步的好处是可以进行事务管理.

事件的异步发布机制参数ApplicationEventMulticaster文档.

Spring提供的标准事件
Event 说明
ContextRefreshedEvent 当容器被实例化或refreshed时发布.如调用refresh()方法, 此处的实例化是指所有的bean都已被加载,后置处理器都被激活,所有单例bean都已被实例化, 所有的容器对象都已准备好可使用. 如果容器支持热重载,则refresh可以被触发多次(XmlWebApplicatonContext支持热刷新,而GenericApplicationContext则不支持)
ContextStartedEvent 当容器启动时发布,即调用start()方法, 已启用意味着所有的Lifecycle bean都已显式接收到了start信号
ContextStoppedEvent 当容器停止时发布,即调用stop()方法, 即所有的Lifecycle bean都已显式接收到了stop信号 , 关闭的容器可以通过start()方法重启
ContextClosedEvent 当容器关闭时发布,即调用close方法, 关闭意味着所有的单例bean都已被销毁.关闭的容器不能被重启或refresh
RequestHandledEvent 这只在使用spring的DispatcherServlet时有效,当一个请求被处理完成时发布

自定义事件

编程式自定义事件

编程式自定义事件分为以下几步:

a. 定义事件
/**
 * 继承ApplicationEvent接口
 */
public class BlackListEvent extends ApplicationEvent {

    private static final long serialVersionUID = -1089664438671641456L;

    private final String address;

    private final String content;
  
        // 构造方法中构建事件内容
    public BlackListEvent(Object source, String address, String content) {
        super(source);
        this.address = address;

        this.content = content;
    }

    public String getAddress() {
        return address;
    }

    public String getContent() {
        return content;
    }

    @Override
    public String toString() {
        return "BlackListEvent [address=" + address + ", content=" + content + "]";
    }

}
b. 定义事件发布逻辑
/**
 * 实现ApplicationEventPublisherAware, 获取ApplicationEventPublisher
 * 通过ApplicationEventPublisher对象来发布事件
 */
public class EmailService implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher publisher;

    private List<String> blackList;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {

        this.publisher = applicationEventPublisher;
    }

    public void sendEmail(String address, String content) {
        if (blackList.contains(address)) {
            System.out.println("=============发布事件=============");
            BlackListEvent event = new BlackListEvent(this, address, content);
            publisher.publishEvent(event);
            System.out.println(event);
            return;
        }
        
        System.out.println("=============发送邮件=============");
    }

    public List<String> getBlackList() {
        return blackList;
    }

    public void setBlackList(List<String> blackList) {
        this.blackList = blackList;
    }
}
c-1. 编程式定义事件监听器
/**
 * 实现ApplicationListener
 * 通过其泛型参数定义监听的事件的具体类型
 * 
 */
public class BlackListNotifier implements ApplicationListener<BlackListEvent> {

    private String notificationAddress;
    
    // 对接收到的事件进行处理
    @Override
    public void onApplicationEvent(BlackListEvent event) {
        
        System.out.println("=========收到消息=============");

        System.out.println(event);
    }
    
    public void setNotificationAddress(String notificationAddress) {
        this.notificationAddress = notificationAddress;
    }
    
    public String getNotificationAddress() {
        return this.notificationAddress;
    }

}
c-2. 注解方式定义事件监听器

在事件处理方法上添加@EventListener.用相应的事件作为参数

    @EventListener
    public void onApplicationEvent(BlackListEvent event) {
        
        System.out.println("=========注解式处理事件 : 收到消息=============");

        System.out.println(event);
    }
d. 注册事件监听器
    @Bean
    public BlackListNotifier blackListNotifier() {
        return new BlackListNotifier();
    }

@EventListener

@EventListener注解有三个参数:

@EventListener(condition = "#blEvent.content == 'foo'")
public void processBlackListEvent(BlackListEvent blEvent) {
    // notify appropriate parties via notificationAddress...
}

通过# + 事件参数名称引用事件, 即#blEvent表示事件blEvent. 通过事件的属性名可直接引用事件的属性.即上述事件中, 引用到了事件的content属性的值进行判断.

定义监听器的执行顺序

异步监听事件

@Async注解事件监听器.
注: 要开启对异步注解的支持.

xmlns:task="http://www.springframework.org/schema/task"

http://www.springframework.org/schema/task 
https://www.springframework.org/schema/task/spring-task.xsd 
上一篇 下一篇

猜你喜欢

热点阅读