写点什么

Spring 系列之 IOC 容器实例化过程七

作者:王威07325
  • 2023-05-29
    上海
  • 本文字数:2124 字

    阅读完需:约 7 分钟

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


发布于: 刚刚阅读数: 2
用户头像

王威07325

关注

还未添加个人签名 2021-12-29 加入

还未添加个人简介

评论

发布
暂无评论
Spring系列之IOC容器实例化过程七_spring ioc_王威07325_InfoQ写作社区