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); } } }
复制代码
评论