// Initialize event multicaster for this context.
//初始化事件传播
initApplicationEventMulticaster();
a.初始化详解
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断容器中是否有applicationEventMulticaster事件传播
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//new 一个时间传播并注册到容器中
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() + "]");
}
}
}
2.添加监听器及发布(监听器必须实现ApplicationListener接口)
a.事件传播管理初始化后会扫描容器中实现了ApplicationListener接口的bean并注入到ApplicationEventMulticaster类中的applicationListeners容器中
// Check for listener beans and register them.
//注册监听器
registerListeners();
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
b.bean实例化时,属性注入之后调用ApplicationListenerDetector的postProcessAfterInitialization方法来添加实现了ApplicationListener接口的漏网之鱼
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
c.手动添加及发布事件
@org.junit.Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//1.无需注入直接new
ClassPathXmlApplicationContext classPathXmlApplicationContext =(ClassPathXmlApplicationContext)context;
classPathXmlApplicationContext.addApplicationListener(new ApplicationDemoListener());
SimpleApplicationEventMulticaster applicationEventMulticaster = (SimpleApplicationEventMulticaster)context.getBean("applicationEventMulticaster");
//2.手动添加,通过beanName的方式添加
applicationEventMulticaster.addApplicationListenerBean("ApplicationDemoListener");
//3.发布事件,在该方法中会获取listener,并调用
context.publishEvent(new ApplicationDemoEvent(""));
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
//调用listener的onApplicationEvent()
invokeListener(listener, event);
}
}
}
c.spring内部事件的发布会调用以下方法:
入口:
// Last step: publish corresponding event.
finishRefresh();
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
//实际仍然调用的是publishEvent()方法
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)