refresh 方法中的 initApplicationEventMulticaster、onRefresh、registerListeners
一个星期过去了,开心周末到来,又到了我们最喜欢的 spring 的解析环节,今天我们主要讲解三个方法,内容不会很多,请放心食用。
initApplicationEventMulticaster 方法
作用: 为 spring 初始化事件多播器
贴上代码:
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
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 + "]");
}
}
}
复制代码
初始化 ApplicationEventMulticaster。如果上下文中没有定义,则使用 SimpleApplicationEventMulticaster。
containsLocalBean:
public interface HierarchicalBeanFactory extends BeanFactory {
/**
* Return the parent bean factory, or {@code null} if there is none.
*/
BeanFactory getParentBeanFactory();
/**
* Return whether the local bean factory contains a bean of the given name,
* ignoring beans defined in ancestor contexts.
* <p>This is an alternative to {@code containsBean}, ignoring a bean
* of the given name from an ancestor bean factory.
* @param name the name of the bean to query
* @return whether a bean with the given name is defined in the local factory
* @see BeanFactory#containsBean
*/
boolean containsLocalBean(String name);
}
复制代码
返回本地 bean 工厂是否包含给定名称的 bean,忽略祖先上下文中定义的 bean。这是 containsBean 的替代方法,忽略来自祖先 bean 工厂的给定名称的 bean
也就是这个方法只会从当前的工厂中去查找 bean 不会去父工厂中去查询。
onRefresh 方法
初始化特定上下文子类中的其他特殊 bean
就是一个模版方法,用于给子类去扩展完成对其他特殊 bean 的初始化所使用,在 Spring Boot 中 ServletWebServerApplicationContext#onRefresh()是有重写这个方法的:
@Override
protected void onRefresh() {
// 调用 GenericWebApplicationContext 初始化主题功能
super.onRefresh();
try {
// 启动 Spring Boot 的嵌入式 Tomcat 服务器
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
复制代码
registerListeners 方法
检查侦听器 bean 并注册它们
protected void registerListeners() {
// Register statically specified listeners first.
//首先注册静态指定的监听器(是特殊的事件监听器,而不是配置中的bean),先通过getApplicationListeners方法获取到ApplicationListener的set的集合,然后通过addApplicationListener(listener)注册监听器。
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!
// 获取beanfactory中ApplicationListener类型的bean,但是不会实例化这些bean,为了让后置处理器可以感知到它们
// 再将这些bean注册到事件多播器中,真正完成事件的发布的时候是在bean的初始化过程中的后置处理器完成
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<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
复制代码
评论