文章目录

  • 1、initMessageSource()
  • 2、initApplicationEventMulticaster()
  • 3、onRefresh()
  • 4、registerListeners()
  • 5、finishBeanFactoryInitialization(beanFactory)
  • 5.1、 DefaultListableBeanFactory#preInstantiateSingletons()
  • 6、finishRefresh()

Spring ioc容器创建过程(1)BeanFactory初始化spring ioc容器创建过程(2)invokeBeanFactoryPostProcessorsspring ioc容器创建过程(3)registerBeanPostProcessors

前三篇文章主要讲了beanFacctory的初始化,bean的后置处理器与beanFactory的后置处理器,这篇文章主要来分析下剩余部分。

1、initMessageSource()

这部分主要是用于spring国际化的功能,因为不常用就暂时不分析了。

2、initApplicationEventMulticaster()

看名字就知道了,这部分主要是来初始化spring的事件广播器的。这里主要用了设计模式的观察者模式,通过ApplicationEventMulticaster事件广播器实现了监听器的注册,通过ApplicationEvent抽象类和ApplicationListener接口,可以实现事件的处理。

/**
 * 如果用户自定义了事件广播器,那么使用用户自定义的事件广播器。
 * 如果用户没有自定义事件广播器,那么使用默认的ApplicationEventMulticaster即SimpleApplicationEventMulticaster。
 *
 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
 */
protected void initApplicationEventMulticaster() {
    //获取初始化好后的beanFactory
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //bean工厂是否有applicationEventMulticaster这个bean
   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 {
       //否则就创建SimpleApplicationEventMulticaster类作为aplicationEventMulticaster的Bean
       //SimpleApplicationEventMulticaster是aplicationEventMulticaster接口的一个实现
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
       beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
       if (this.logger.isTraceEnabled()) {
           this.logger.trace("No 'applicationEventMulticaster' bean, using [" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
       }
   }
}

可以推断, 当产生Spring 事件的时候会默认使用Simpl巳ApplicationEventMulticaster 的multicastEvent 来广播事件,遍历所有监昕器,并使用监昕器中的onApplicationEvent 方法来进行监昕器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器来决定。

3、onRefresh()

模板方法,留给子类实现,像springboot就实现了其方法作为tomcat容器的启动。

4、registerListeners()

2的过程已经初始化了spring的事件广播器,通过registerListeners可以去注册监听器。注册好监听器后,广播会将对应的事件传递给监听器。

/**
 * Add beans that implement ApplicationListener as listeners.
 * Doesn't affect other listeners, which can be added without being beans.
 */
protected void registerListeners() {
   // 手动注册的监听器绑定到广播器
   for (ApplicationListener<?> listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
   }
   //取到容器里面的所有的监听器的名称,绑定到广播器
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }
   // 如果存在早期应用事件就直接发布(同时就把earlyApplicationEvents该字段置为null)
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

5、finishBeanFactoryInitialization(beanFactory)

实例化所有单例的非懒加载的Bean,并完成依赖注入。

/**
 * Finish the initialization of this context's bean factory,
 * initializing all remaining singleton beans.
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // 初始化上下文的转换服务,ConversionService是一个类型转换接口,作用即处理自定义的转换类型
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }
   //主要用于注释属性值的解析
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }
   // 初始化 LoadTimeWeaverAwareBean 用于织入第三方模块,在 class 文件载入 JVM 的时候动态织入
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }
   //将临时类加载器设置为null
   beanFactory.setTempClassLoader(null);
   //冻结(缓存)所有的bean定义(ean definition),说明注册的bean 定义将不被修改或任何进一步的处理
   beanFactory.freezeConfiguration();
   //初始化剩下的单实例(非懒加载的)
   beanFactory.preInstantiateSingletons();
}

5.1、 DefaultListableBeanFactory#preInstantiateSingletons()

ApplicationContext 实现的默认行为就是在启动时将所有单例bean 提前进行实例化。提前实例化意味着作为初始化过程的一部分, ApplicationContext 实例会创建并配置所有的单例bean. 通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现。而这个实例化的过程就是在finishBeanFactorylnitialization 中完成的。这部分先简单过一下,下次开个专栏分析下。

@Override
public void preInstantiateSingletons() throws BeansException {
   if (logger.isTraceEnabled()) {
      logger.trace("Pre-instantiating singletons in " + this);
   }
   // 获取所有的beanName
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
   // 初始化所有的非懒加载的单例bean
   for (String beanName : beanNames) {
      //对bean定义进行合并,如bean中引入parent属性
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      // 不是抽象类,是单例的,不是懒加载的
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 如果是工厂Bean,那就会此工厂Bean放进去
         if (isFactoryBean(beanName)) {
            //如果是工厂bean,调用的时候再bean的名称前面添加前缀符号&
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
 
            //拿到对应的bean后再次判断bean是否是factoryBean
            if (bean instanceof FactoryBean) {
               FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged(
                        (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         // 非FactoryBean初始化
         else {
            getBean(beanName);
         }
      }
   }
   //再次遍历beanNames,对实现了SmartInitializingSingleton接口的类实现处理,会调用到该bean的afterSingletonsInstantiated()方法。
   //在单例bean加载完成后,做一些事情
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
               .tag("beanName", beanName);
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            //native方法  不用做权限检查
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
         smartInitialize.end();
      }
   }
}

6、finishRefresh()

/**
 * Finish the refresh of this context, invoking the LifecycleProcessor's
 * onRefresh() method and publishing the
 * {@link org.springframework.context.event.ContextRefreshedEvent}.
 */
@SuppressWarnings("deprecation")
protected void finishRefresh() {
   // Clear context-level resource caches (such as ASM metadata from scanning).
   clearResourceCaches();
   //初始化生命周期管理器LifecycleProcessor
   initLifecycleProcessor();
   //启动所有实现了Lifecycle接口的bean
   getLifecycleProcessor().onRefresh();
   //发布刷新完成事件
   publishEvent(new ContextRefreshedEvent(this));
   if (!IN_NATIVE_IMAGE) {
      LiveBeansView.registerApplicationContext(this);
   }
}

到这里基本上spring ioc容器的初始化就结束了。