文章目录
4.3. 使用ApplicationEventPublisherAware注入
ContextStartedEvent
:容器启动的时候触发(start方法)ContextRefreshedEvent
:容器刷新的时候触发(onRefresh,在finisRefresh中调用)ContextStoppedEvent
:容器停止的时候触发(stop方法)ContextClosedEvent
:容器关闭的时候触发(close方法)ApplicationEvent
即可完成一个自定义的Spring事件/**
* 自定义事件,继承ApplicationEvent
*/
@Data
public class FirstEvent extends ApplicationEvent {
/**
* 需要携带的消息,可以是任意类型的数据,相当于传递数据
*/
private String message;
/**
* 构造方法
* @param source 事件发生的类
* @param message 携带的消息
*/
public FirstEvent(Object source,String message) {
super(source);
this.message=message;
}
}
ApplicationListener
接口@EventListener
注解/**
* 自定义一个监听器,实现ApplicationListener,指定的泛型就是需要监听的事件
* 监听ContextRefreshedEvent,当容器完成刷新的时候该监听器就会监听到并执行onApplicationEvent方法
*/
@Component
public class FirstListener implements ApplicationListener<ContextRefreshedEvent> {
/**
* 重载方法,被监听的事件触发了就会调用这个方法
* @param event 触发事件的对象
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("容器刷新的监听器启动了........");
System.out.println(event.getSource()+"---->"+event.getTimestamp()+"----"+event.getApplicationContext());
System.out.println(".........................................");
}
}
classes
:Class数组,指定需要监听的事件condition
:指定条件,默认监听/**
* 注解方式实现事件监听器
*/
@Component
public class CustomEventListener {
/**
* 使用@EventListener监听事件
* @param event 传入的事件源
*/
@EventListener(classes = {ApplicationEvent.class})
public void handlerContextRefreshEvent(ApplicationEvent event){
if (event instanceof ContextRefreshedEvent) {
ContextRefreshedEvent e=(ContextRefreshedEvent)event;
System.out.println("ContextRefreshedEvent启动了........");
System.out.println(event.getSource() + "---->" + event.getTimestamp() + "----" + e.getApplicationContext());
System.out.println(".........................................");
}else if(event instanceof ContextStartedEvent){
ContextStartedEvent e=(ContextStartedEvent)event;
System.out.println("ContextStartedEvent启动了........");
System.out.println(event.getSource() + "---->" + event.getTimestamp() + "----" + e.getApplicationContext());
System.out.println(".........................................");
}else if(event instanceof ContextStoppedEvent){
ContextStoppedEvent e=(ContextStoppedEvent)event;
System.out.println("ContextStoppedEvent启动了........");
System.out.println(event.getSource() + "---->" + event.getTimestamp() + "----" + e.getApplicationContext());
System.out.println(".........................................");
}else if(event instanceof ContextClosedEvent){
ContextClosedEvent e=(ContextClosedEvent)event;
System.out.println("ContextClosedEvent启动了........");
System.out.println(event.getSource() + "---->" + event.getTimestamp() + "----" + e.getApplicationContext());
System.out.println(".........................................");
}
}
/**
* 可以不指定classes,默认监听的是方法参数中的事件
* @param event 事件源
*/
@EventListener
public void handleFirstEvent(FirstEvent event){
System.out.println("firstEvent事件启动了,。。。。。。。。。");
System.out.println(event.getSource()+"---->"+event.getMessage());
}
}
ApplicationEventPublisher
,我们可以自定义自己的类,当然也可以使用spring现成的类ApplicationEventPublisher
的实现,我们可以直接注入使用。如下:
/**
* 自定义的事件发布器
*/
@Component
public class CustomPublisher {
/**
* 直接注入ApplicationEventPublisher
*/
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
/**
* 发布事件
* @param event 指定的事件
*/
public void publishEvent(ApplicationEvent event){
applicationEventPublisher.publishEvent(event);
}
}
@Test
public void test1(){
CustomPublisher customPublisher = applicationContext.getBean(CustomPublisher.class);
customPublisher.publishEvent(new FirstEvent(this,"启动自定义事件"));
}
/**
* 自定义的事件发布器,实现ApplicationEventPublisherAware接口
*/
@Component
public class CustomPublisher implements ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
/**
* 发布事件
* @param event 指定的事件
*/
public void publishEvent(ApplicationEvent event){
applicationEventPublisher.publishEvent(event);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher=applicationEventPublisher;
}
}
ApplicationEventMulticaster
】?AbstractApplicationEventMulticaster
、SimpleApplicationEventMulticaster
org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)
这个方法中,如下:@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//遍历事件监听器
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
//判断是否设置了Executor,如果存在,那么就异步执行
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
//否则的话,同步执行,调用invokeListener
invokeListener(listener, event);
}
}
}
/****************************************invokeListener******************************/
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
//如果有异常处理器,就try-catch执行
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
//如果有异常了,执行异常处理器的handleError方法
errorHandler.handleError(err);
}
}
else {
//没有异常处理器直接执行
doInvokeListener(listener, event);
}
}
/*******************************doInvokeListener****************************/
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
//此时真正调用监听器中的方法
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isDebugEnabled()) {
logger.debug("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
@Async
注解标注方法异步执行,不过需要在配置类上开启异步功能,使用@EnableAsync
注解,如下:Configuration
@ComponentScan(value = {"cn.tedu.demo"})
@EnableAsync
public class FirstConfig {
}
@Async
注解,使得事件异步执行/**
* 注解方式实现事件监听器
*/
@Component
public class CustomEventListener {
/**
* 可以不指定classes,默认监听的是方法参数中的事件
* @Async : 指定这个方法异步执行
* @param event 事件源
*/
@EventListener
@Async
public void handleFirstEvent(FirstEvent event){
System.out.println("firstEvent事件启动了,。。。。。。。。。");
System.out.println(event.getSource()+"---->"+event.getMessage());
}
}
SimpleApplicationEventMulticaster
,我们可以自己注入一个多播器直接使用即可。protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断ioc容器中是否存在id为applicationEventMulticaster事件多播器
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//直接使用ioc容器中的
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//新建一个,不过没有设置TaskExector
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)
】我们可以看出监听器的执行是先判断多播器中是否存在Executor
,如果存在,那么就单独开启一个线程执行,否则就同步执行,我们在初始化多播器的时候,可以为其设置一个Executor
,那么就可以异步执行了。@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
applicationEventMulticaster
,同时为其设置一个executor
/**
* 自定义一个事件多播器,用来管理监听器和执行监听器
* @return
*/
@Bean(name = "applicationEventMulticaster")
public ApplicationEventMulticaster applicationEventMulticaster(){
//事件多播器
SimpleApplicationEventMulticaster simpleApplicationEventMulticaster=new SimpleApplicationEventMulticaster();
//设置executor
SimpleAsyncTaskExecutor executor=new SimpleAsyncTaskExecutor();
simpleApplicationEventMulticaster.setTaskExecutor(executor);
//设置一个事件异常处理器,当监听器执行出现错误了会进行补救
simpleApplicationEventMulticaster.setErrorHandler(t->{
//这里可以针对不同的异常进行处理,在监听器中trycatch,不同执行抛出不同异常即可分类处理
System.out.println("监听事件执行报错了");
System.out.println(t.getMessage());
});
return simpleApplicationEventMulticaster;
}
refresh
方法中:initApplicationEventMulticaster()
:初始化事件多播器registerListeners();
:注册事件监听器finishRefresh()
方法中调用publishEvent(new ContextRefreshedEvent(this))
方法发布容器刷新事件。