Spring标准event和自定义event

廉价感情. 提交于 2020-01-19 02:25:07

Spring的事件同样是基于观察者模式,只要是观察者模式,就含有主题,主题,针对该主题的事件(事件),向主题发布事件的人(发布者),订阅主题并接收事件的人(订阅者)。

在Spring中,一般是这样玩的:
 如果一个类扩展了ApplicationEvent则它是一个针对某某主题的事件,该类中的source可以当作这个主题
 如果一个类实现了ApplicationListener接口,并将其注册为一个bean,它是一个订阅者
 如果一个类实现了ApplicationEventPublisherAware然后注册为bean,并调用了publishEvent,它是一个发布                      

从Spring4.2起,这个机制也被优化为只要在一个对象上增加事件注解,就可以使用事件机制,因为在这个对象被发布时,spring会将其包装成一个事件。

你可以自定义event,玩法如下:

这是一个针对主题source的事件
public class BlackListEvent extends ApplicationEvent {
    private final String address; private final String content;
    public BlackListEvent(Object source, String address, String content) { super(source);
        this.address = address; this.content = content;
    }
    // accessor and other methods...
}
订阅者
public class BlackListNotifier implements ApplicationListener<BlackListEvent> { 
    private String notificationAddress;
    public void setNotificationAddress(String notificationAddress) {                     
         this.notificationAddress = notificationAddress;
    }
    public void onApplicationEvent(BlackListEvent event) {
      // notify appropriate parties via notificationAddress...
    }
}
发布者
public class EmailService implements ApplicationEventPublisherAware {
    private List<String> blackList;
    private ApplicationEventPublisher publisher;
    public void setBlackList(List<String> blackList) { 
        this.blackList = blackList;
    }
    public void setApplicationEventPublisher(ApplicationEventPublisher publisher){
        this.publisher = publisher;
    }
    public void sendEmail(String address, String content) { 
        if (blackList.contains(address)) {
            publisher.publishEvent(new BlackListEvent(this, address, content)); return;
        }
        // send email...
    }
}
注册为bean
<bean id="emailService" class="example.EmailService">
<property name="blackList">
<list>
<value>known.spammer@example.org</value>
<value>known.hacker@example.org</value>
<value>john.doe@example.org</value>
</list>
</property>
</bean>
 
<bean id="blackListNotifier" class="example.BlackListNotifier">
<property name="notificationAddress" value="blacklist@example.org"/>
</bean>

可以发现 ApplicationListener 传入了一个泛型参数BlackListEvent以保证类型安全,其实你想注册多少个监听器就注册多少监听器,但你必须注意eventListeners会同步地接收事件,这表示publishEvent方法会被阻塞知道所有的监听器全部处理完事件。这种同步加单线程的模式的优点在于,当一个监听器接收到请求,它会在publisher的事务中执行。如果有必要使用另外的事件策略,请参考ApplicationEventMulticaster接口和SimpleApplicationEventMuticaster接口的用法

 

除此之外,Spring中还提供了一系列标准的事件:
 

Event

Explanation

ContextRefreshedEvent

Published when the ApplicationContext is initialized or refreshed (for example, by using the refresh() method on the ConfigurableApplicationContext interface). Here, “initialized” means that all beans are loaded, post-processor beans are detected and activated, singletons are pre-instantiated, and the ApplicationContext object is ready for use. As long as the context has not been closed, a refresh can be triggered multiple times, provided that the chosen ApplicationContext actually supports such “hot” refreshes. For example, XmlWebApplicationContext supports hot refreshes, but GenericApplicationContext does not.

ContextStartedEvent

Published when the ApplicationContext is started by using the start() method on the ConfigurableApplicationContext interface. Here, “started” means that all Lifecycle beans receive an explicit start signal. Typically, this signal is used to restart beans after an explicit stop, but it may also be used to start components that have not been configured for autostart (for example, components that have not already started on initialization).

ContextStoppedEvent

Published when the ApplicationContext is stopped by using the stop() method on the ConfigurableApplicationContext interface. Here, “stopped” means that all Lifecycle beans receive an explicit stop signal. A stopped context may be restarted through a start() call.

ContextClosedEvent

Published when the ApplicationContext is being closed by using the close() method on the ConfigurableApplicationContext interface or via a JVM shutdown hook. Here, "closed" means that all singleton beans will be destroyed. Once the context is closed, it reaches its end of life and cannot be refreshed or restarted.

RequestHandledEvent

A web-specific event telling all beans that an HTTP request has been serviced. This event is published after the request is complete. This event is only applicable to web applications that use Spring’s DispatcherServlet.

ServletRequestHandledEvent

A subclass of RequestHandledEvent that adds Servlet-specific context information.

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!