1.1)自己写一个TulingApplicationListener 实现ApplicationListener 接口,并且把该组件加入到容器中.
@Component
public class TulingApplicationListener implements ApplicationListener {
//接受到消息,回调该方法
@Override
public void onApplicationEvent(ApplicationEvent event) { System.out.println("TulingApplicationListener 接受到了一个事件"+event);
}
}
public static void main(String[] args) { AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(MainConfig.class);
//手动发布一个事件
ctx.publishEvent(new ApplicationEvent("我手动发布了一个事件") {
@Override
public Object getSource() {
return super.getSource();
}
});
//容器关闭也发布事件
ctx.close();
}
测试结果: TulingApplicationListener 接受到了一个事件org.springframework.context.event.ContextRefreshedEvent[source=org.springframewo TulingApplicationListener 接受到了一个事件com.tuling.testapplicationlistener.MainClass$1[source=我手动发布了一个事件] TulingApplicationListener 接受到了一个事件org.springframework.context.event.ContextClosedEvent[source=org.springframework
源码解析:
i1>org.springframework.context.support.AbstractApplicationContext#refresh
i2>org.springframework.context.support.AbstractApplicationContext#initApplicationEventMulticaster(初 始化事件多播器)
i3>org.springframework.context.support.AbstractApplicationContext#registerListeners(把事件监听 器注册到多播器上去)
i2(初始化事件多播器源码解析)
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
/判断IOC容器中包含applicationEventMulticaster 事件多播器的Bean的name
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
/创建一个applicationEventMulticaster的bean放在IOC 容器中,bean的name 为applicationEventMulticaster
this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
/容器中不包含一个beanName 为applicationEventMulticaster的多播器组件
else {
//创建一个SimpleApplicationEventMulticaster 多播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//注册到容器中
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
i3:把容器中的监听器注册到多播器上去 源码解析
protected void registerListeners() {
//去容器中把applicationListener 捞取出来注册到多播器上去(系统的)
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//我们自己实现了ApplicationListener 的组件
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//在这里之前,我们早期想发布的事件 由于没有多播器没有发布,在这里我们总算有了自己的多播器,可以在这里发布早期堆积的事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
--------------------------------------------------------------------如何发布事件------------------------------------------------------
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType :
resolveDefaultEventType(event));
//获取到所有的监听器
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
//看spring 容器中是否支持线程池 异步发送事件
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else { //同步发送事件
invokeListener(listener, event);
}
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
//调用对于listener的onApplicationEvent事件
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;
}
}
}