spring的publish-event-listener机制总结

spring提供了publish-event-listener机制还有异步任务机制,能很好的帮助我们解耦我们的应用跟代码的管理。

config类

@Configuration
@ComponentScan("。。。")
blic class AppletApiConfigure {
}

事件类,必须实现ApplicationEvent

public class MyEvent extends ApplicationEvent {     

	public MyEvent() {        
		super();         
	 }   
}

观察者,必须实现ApplicationListener,并指定泛型为我们的自定义事件

@Component
public class MyListener implements ApplicationListener<MyEvent> {    
	@Override    
	public void onApplicationEvent(MyEvent event) {        
		System.out.println(event.getMsg());    
	}
}

发布者,直接用我们的上下文对象进行发布,它继承了ApplicationEventPublisher

@Component
public class MyPublisher {    
	@Autowired    
	private ApplicationContext applicationContext;     
	public void publish() {        
		applicationContext.publishEvent(new MyEvent());   
	 }
}

相关源代码

package org.springframework.context;

@FunctionalInterface
public interface ApplicationEventPublisher {
    default void publishEvent(ApplicationEvent event) {
        this.publishEvent((Object)event);
    }

    void publishEvent(Object var1);
}

追踪到

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
   。。。
	
 	// Multicast right now if possible - or lazily once the multicaster is initialized
	if (this.earlyApplicationEvents != null) {
	   this.earlyApplicationEvents.add(applicationEvent);
	}
	else {
	   getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
	}
}

主要是

 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);

getApplicationEventMulticaster()

/**
 * Return the internal ApplicationEventMulticaster used by the context.
 * @return the internal ApplicationEventMulticaster (never {@code null})
 * @throws IllegalStateException if the context has not been initialized yet
 */
ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
   if (this.applicationEventMulticaster == null) {
      throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
            "call 'refresh' before multicasting events via the context: " + this);
   }
   return this.applicationEventMulticaster;
}

它其实就是返回当前类持有的ApplicationEventMulticaster这个接口的实现的引用,管理了我们的listener,并且可以向它们发布事件。
getApplicationEventMulticaster()返回的其实一个发布者,我们的容器applicationContext其实就是调用这个对象去发布事件
并且它管理了我们所有的listener。

multicastEvent(…)

@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);
      }
   }
}

getApplicationListeners(event, type),其实就是返回了当前对象所管理的监听了当前事件的listener,之后在调用listener的invokeListener(listener, event)方法。

invokeListener(…)

protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
   ErrorHandler errorHandler = getErrorHandler();
   if (errorHandler != null) {
      try {
         doInvokeListener(listener, event);
      }
      catch (Throwable err) {
         errorHandler.handleError(err);
      }
   }
   else {
      doInvokeListener(listener, event);
   }
}

doInvokeListener(listener, event);就是我们实现了applicationListener接口所实现的方法,整个过程是同步的

注解实现

@Component
public class MyListener{    
	@EventListener    
	public void onApplicationEvent(MyEvent event) {        
		System.out.println(event.getMsg());   
	 }    
 	@EventListener    
 	public void onApplicationEvent(MySecondEvent event) {        	
 		System.out.println(event.getMsg());   
 	 } }

异步实现

自定义一个ApplicationEventMulticaster

//需要注意的是,我们的名字一定要叫applicationEventMulticaster,否则不生效,回头看下源码就明白了
@Component(&quot;applicationEventMulticaster&quot)
public class MyMulticaster extends SimpleApplicationEventMulticaster {
    @Override
    protected Executor getTaskExecutor() {
        // 这里可以按实际需求进行线程池的配置
	return new SimpleAsyncTaskExecutor();	
    }
     /**
     * 这个方法主要配置错误处理,默认只会打一个警告级别的日志
     *
     * @return
     */
    @Override
    protected ErrorHandler getErrorHandler() {
        return (t -&gt; {
            System.out.println(&quot;出错了&quot;);
        });
    }
}

配置类上加注解@EnableAsync
方法上加@Async可以是部分方法异步执行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值