Spring容器创建过程


Spring启动入口

用多了SpringBoot,也许很多人已经忘了如何手动启动一个Spring容器,以下是一个最简单的启动方法:

public class Application {

	public static void main(String[] args) {
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext("net.javajun");
		Object userService = applicationContext.getBean("userService");
		System.out.println(userService);
	}
}

这里我们使用了AnnotationConfigApplicationContext这个实现。

很多博客教程中常用基于xml的ClassPathXmlApplicationContext,但如今SpringBoot时代,已经很少有人用xml了,且本文也想写一些和别人不一样的东西,因此使用了基于注解的Spring容器AnnotationConfigApplicationContext

从上面两三行代码可以看出,启动一个Spring容器,只需new AnnotationConfigApplicationContext即可,因此,Spring的整个启动过程就在AnnotationConfigApplicationContext的构造函数中。

常用的两个构造函数如下所示,可以传入包名,也可以传入具体的class:

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   this();
   register(componentClasses);
   refresh();
}

public AnnotationConfigApplicationContext(String... basePackages) {
   this();
   scan(basePackages);
   refresh();
}

以传入包名的构造方法为例,Spring启动包含两个步骤:

  1. 扫描bean
  2. refresh()

扫描bean

扫描bean,就是根据传入的包名,扫描所有的类,并封装到BeanDefinition中,它是调用了ClassPathBeanDefinitionScanner这个scanner进行扫描的,且在扫描过程中,将beanDefinition注册给beanFactory

public AnnotationConfigApplicationContext() {
   this.reader = new AnnotatedBeanDefinitionReader(this);
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

BeanDefinition是一个接口,从下图可以看出,BeanDefinition大致包含以下信息:

信息 说明
beanClass bean是哪个类
scope 单例 singleton,原型 prototype
lazyinit 是否懒加载
dependsOn 依赖的bean,不是指@autowire注入的bean
isPrimary 有多个实现时,指定优先使用的bean
其他

我们来看看ClassPathBeanDefinitionScanner具体是如何扫描bean的,找到doScan方法,代码中给出了注释,请仔细阅读

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
   Assert.notEmpty(basePackages, "At least one base package must be specified");
   Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
   // 遍历所有包名
   for (String basePackage : basePackages) {
      // 找到包中候选的component
      Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
      for (BeanDefinition candidate : candidates) {
         // 解析scope
         ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
         candidate.setScope(scopeMetadata.getScopeName());
         // 解析beanName
         String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
         if (candidate instanceof AbstractBeanDefinition) {
            // 为BeanDefinition设置一些默认属性
            // 不要被postProcess这个命名给骗了,这不是一个后置处理器
            postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
         }
         if (candidate instanceof AnnotatedBeanDefinition) {
            // 处理bean上的一些注解,如@Primary,如@Lazy
            AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
         }
         // 校验候选bean,如是否已存在,名称是否冲突
         if (checkCandidate(beanName, candidate)) {
            // BeanDefinition外层封装一层BeanDefinitionHolder
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
            definitionHolder =
                  AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            beanDefinitions.add(definitionHolder);
            // 将BeanDefinitionHolder注册给registry
            registerBeanDefinition(definitionHolder, this.registry);
         }
      }
   }
   return beanDefinitions;
}

从上面的代码可以看出,扫描的过程大致分为三步骤:

  1. 先找出所有候选的Component

  2. 解析出beanName,isPrimary等属性封装到BeanDefinition中

  3. 注册到registry中,此处的registry其实就是ApplicationContext,在创建scanner时传入的:

这里分享两个阅读源码的小技巧:

第一、看一个方法,要先看整体,根据命名猜测作用,不要一直深入从而陷入到细节

第二、善用debug功能

比如ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);这一行代码,你可能没法一眼看出它的作用。

点进去你会发现ScopeMetadataResolver是一个接口,接下去又得去找它的实现类,如果实现类很多,咱也不知道到底具体用的是哪个,这就陷入了细节。

此时正确的做法是设一个断点,如:

从截图中可以看到,那一行代码传入一个候选component,返回一个scope,那我们就知道了它的作用是解析scope,至于它具体使用的是哪个实现类根本不重要。

了解了扫描的的大致步骤,再带着好奇心进一步了解一些细节,比如findCandidateComponents,是如何找到候选component的。

找到该方法的具体实现,通过debug发现,该方法内部找到了我们所定义的类.class文件, 如下图所示:

值得一提的是,找出的所有.class文件,是包含没有@Component注解的普通类的,然后在isCandidateComponent()中通过判断是否有@Component注解来决定是否真正成为候选bean

至此,我们已经基本上了解的Spring扫描Bean的全过程

refresh

refresh是真正的进行bean的整个生命周期,该方法代码是由父类AbstractApplicationContext实现的,结构也十分清晰,具体请看注释:

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      // 准备工作,打印日志,标记一些状态
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      // 获得bean工厂
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      // 准备bean工厂,设置一些beanFactory属性
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         // 提供给子类的扩展点
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         // 执行BeanFactoryPostProcessor实现类的方法
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         // 注册BeanPostProcessors
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         // 国际化,不重要
         initMessageSource();

         // Initialize event multicaster for this context.
         // 初始化事件多播器
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         // 提供给子类的扩展点
         onRefresh();

         // Check for listener beans and register them.
         // 注册事件监听器-ApplicationListener
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         // 初始化所有非懒加载的bean
         // bean的创建过程都在该方法中
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         // 广播结束事件,容器创建完成
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         // 销毁bean
         destroyBeans();

         // Reset 'active' flag.
         // 重置状态
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

下面将依次解析上述的所有方法

prepareRefresh

这个方法比较简单,设置一下closed和active的状态,这两个属性都是AtomicBoolean类型,然后打印一些日志,初始化一些集合等

protected void prepareRefresh() {
   // Switch to active.
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);

   if (logger.isDebugEnabled()) {
      if (logger.isTraceEnabled()) {
         logger.trace("Refreshing " + this);
      }
      else {
         logger.debug("Refreshing " + getDisplayName());
      }
   }

   // Initialize any placeholder property sources in the context environment.
   initPropertySources();

   // Validate that all properties marked as required are resolvable:
   // see ConfigurablePropertyResolver#setRequiredProperties
   getEnvironment().validateRequiredProperties();

   // Store pre-refresh ApplicationListeners...
   if (this.earlyApplicationListeners == null) {
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
   }
   else {
      // Reset local application listeners to pre-refresh state.
      this.applicationListeners.clear();
      this.applicationListeners.addAll(this.earlyApplicationListeners);
   }

   // Allow for the collection of early ApplicationEvents,
   // to be published once the multicaster is available...
   this.earlyApplicationEvents = new LinkedHashSet<>();
}

obtainFreshBeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}

该方法很简单,第一行refreshBeanFactory()中,使用AtomicBoolean避免了refresh操作被多次调用

@Override
protected final void refreshBeanFactory() throws IllegalStateException {
   if (!this.refreshed.compareAndSet(false, true)) {
      throw new IllegalStateException(
            "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
   }
   this.beanFactory.setSerializationId(getId());
}

getBeanFactory()则是直接返回了事先创建好的ConfigurableListableBeanFactory

@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
   return this.beanFactory;
}

ConfigurableListableBeanFactory的创建是在父类GenericApplicationContext中创建,子类在被创建时,会自动调用父类的构造方法

public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

prepareBeanFactory

该方法中主要是给bean工厂设置一些属性,快速瞄一眼即可

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // BeanFactory interface not registered as resolvable type in a plain factory.
   // MessageSource registered (and found for autowiring) as a bean.
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // Register default environment beans.
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

postProcessBeanFactory

钩子方法,是一个空实现,子类可以重写该方法已达到扩展的目的

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

invokeBeanFactoryPostProcessors

从命名上就可以看到它的作用,执行beanFactory的后置处理器,其中重要代码就一行:

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

这行代码中,通过getBeanFactoryPostProcessors()拿到所有beanFactory的后置处理器,点进去发现它是直接返回:

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
   return this.beanFactoryPostProcessors;
}

然后我们继续找是什么时候添加后置处理器的,一顿操作猛如虎,最后居然发现,getBeanFactoryPostProcessors()根本没人调用,调用的地方都是测试类:

由此可见,addBeanFactoryPostProcessor()这个方法是给开发者调用的,用于手动添加beanFactory后置处理器。

大致使用方法如下:

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("postProcessBeanFactory");
	}
}

public class Application {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
		applicationContext.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
		applicationContext.scan("net.javajun");
		applicationContext.refresh();
	}
}

注意,这里自定义的MyBeanFactoryPostProcessor是没有@Component注解的

接下来我们重点看PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors的内部实现,这个方法代码比较多,我们分多段来看。

第一段,是执行BeanDefinition后置处理器BeanDefinitionRegistryPostProcessor,它是BeanFactoryPostProcessor的子类:

if (beanFactory instanceof BeanDefinitionRegistry) {
   BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
   // BeanFactory后置处理器
   List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
   // BeanDefinition 后置处理器
   List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

   for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
      if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
         BeanDefinitionRegistryPostProcessor registryProcessor =
               (BeanDefinitionRegistryPostProcessor) postProcessor;
         registryProcessor.postProcessBeanDefinitionRegistry(registry);
         registryProcessors.add(registryProcessor);
      }
      else {
         regularPostProcessors.add(postProcessor);
      }
   }
//...
//...
}

上面这段代码中,从手动添加的后置处理器中,找到BeanDefinition后置处理器和BeanFactory后置处理器,先保存到集合中,暂时不用。

第二段,从容器中找到BeanDefinition后置处理器,进行排序并调用

List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 找到实现了PriorityOrdered接口的BeanDefinition后置处理器
for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
// 后置处理器排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 执行BeanDefinition后置处理器,内部是遍历调用postProcessBeanDefinitionRegistry()
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// 找到实现了Ordered接口的BeanDefinition后置处理器
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
// 排序并执行
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

可以看出,实现了PriorityOrdered接口的BeanDefinition后置处理器优先被执行,然后执行实现了Ordered接口的后置处理器

最后继续执行其他的BeanDefinition后置处理器,代码如下:

// 继续其他的BeanDefinition后置处理器
boolean reiterate = true;
while (reiterate) {
   reiterate = false;
   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   for (String ppName : postProcessorNames) {
      // 过滤前面已经执行过的后置处理器
      if (!processedBeans.contains(ppName)) {
         currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
         processedBeans.add(ppName);
         reiterate = true;
      }
   }
   // 排序并执行
   sortPostProcessors(currentRegistryProcessors, beanFactory);
   registryProcessors.addAll(currentRegistryProcessors);
   invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
   currentRegistryProcessors.clear();
}

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 执行BeanDefinition后置处理器
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 执行BeanFactory后置处理器
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

注意:上面这段代码中,最后两行执行的是手动addBeanFactoryPostProcessor添加的BeanDefinition后置处理器和BeanFactory后置处理器。也就是前面第一段代码中,保存到集合里暂时没用的后置处理器

第三段,接下去要执行bean的BeanFactory后置处理器。下面的代码其实和上面的没有太大区别

// 找到BeanFactoryPostProcessor的bean name
String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 分别找出PriorityOrdered和Ordered的后置处理器
for (String ppName : postProcessorNames) {
   if (processedBeans.contains(ppName)) {
      // skip - already processed in first phase above
   }
   else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
   }
   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
      orderedPostProcessorNames.add(ppName);
   }
   else {
      nonOrderedPostProcessorNames.add(ppName);
   }
}

// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 排序并执行实现了PriorityOrdered的BeanFactory后置处理器
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 排序并执行实现了Ordered的BeanFactory后置处理器
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
   orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
// 执行其他的BeanFactory后置处理器
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
   nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

beanFactory.clearMetadataCache();

现在,咱们重新理一下整个流程:

  1. 遍历手动添加的后置处理器,保存到集合里
  2. 执行容器中的BeanDefinition后置处理器
    1. 实现了PriorityOrdered接口的优先进行排序并执行
    2. 然后排序并执行实现了Ordered接口的
    3. 最后执行其他的
  3. 执行第一步的BeanDefinition后置处理器和BeanFactory后置处理器
  4. 执行容器中的BeanFactory后置处理器
    1. 实现了PriorityOrdered接口的优先进行排序并执行
    2. 然后排序并执行实现了Ordered接口的
    3. 最后执行其他的

registerBeanPostProcessors

这个方法中,直接使用了PostProcessorRegistrationDelegate:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

从命名上看,是注册BeanPostProcessor,姑且大胆猜测一下,这个方法中只是找到所有的BeanPostProcessor,仅仅是注册,并没有执行。

且参考上面的BeanFactoryProcessor,是否也是按照PriorityOrdered -> Ordered -> 其他这个流程去走呢?

带着疑问继续看下去:

public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
   // 找到所有BeanPostProcessor bean name
   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   // Register BeanPostProcessorChecker that logs an info message when
   // a bean is created during BeanPostProcessor instantiation, i.e. when
   // a bean is not eligible for getting processed by all BeanPostProcessors.
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   // 用于记录日志的后置处理器
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   // PriorityOrdered, Ordered, 其他
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, register the BeanPostProcessors that implement PriorityOrdered.
   // 排序
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   // 遍历调用beanFactory.addBeanPostProcessor
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // Next, register the BeanPostProcessors that implement Ordered.
   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String ppName : orderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      orderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   // 排序
   sortPostProcessors(orderedPostProcessors, beanFactory);
   // 遍历调用beanFactory.addBeanPostProcessor
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // Now, register all regular BeanPostProcessors.
   // 其他未排序的后置处理器
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String ppName : nonOrderedPostProcessorNames) {
      BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
      nonOrderedPostProcessors.add(pp);
      if (pp instanceof MergedBeanDefinitionPostProcessor) {
         internalPostProcessors.add(pp);
      }
   }
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   // Finally, re-register all internal BeanPostProcessors.
   // 排序
   sortPostProcessors(internalPostProcessors, beanFactory);
   // 遍历调用beanFactory.addBeanPostProcessor
   registerBeanPostProcessors(beanFactory, internalPostProcessors);

   // Re-register post-processor for detecting inner beans as ApplicationListeners,
   // moving it to the end of the processor chain (for picking up proxies etc).
   // ApplicationListenerDetector后置处理器
   // 该处理器用于处理ApplicationListener监听器
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

与刚刚猜测的一致,BeanPostProcessor和之前的BeanFactoryPostProcessor十分相似,同样支持PriorityOrdered接口和Ordered接口。

且从最后一行可以发现,原来ApplicationListener也和BeanPostProcessor有关

initMessageSource

国际化相关,可以不看

initApplicationEventMulticaster

这个方法里比较简单,如果没有定义多播器,则默认使用SimpleApplicationEventMulticaster,且将该bean直接添加到单例池中

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.isTraceEnabled()) {
         logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   }
   else {
      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() + "]");
      }
   }
}

onRefresh

钩子方法,留给子类去扩展

protected void onRefresh() throws BeansException {
   // For subclasses: do nothing by default.
}

registerListeners

把ApplicationListener注册给多播器

protected void registerListeners() {
   // Register statically specified listeners first.
   // 获取ApplicationListener,注册给事件多播器
   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!
   // 获取ApplicationListener,注册给事件多播器
   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 (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

finishBeanFactoryInitialization

这个方法是重中之重,大部分bean都在这个方法中被创建。为什么是大部分呢?因为在前面的几个步骤中,有一些后置处理的bean其实已经的调用beanFactory.getBean()时就已经创建好了

该方法中,最重要的是最后一行beanFactory.preInstantiateSingletons(),其他不重要,大致瞄一眼即可:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   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));
   }

   // Register a default embedded value resolver if no BeanFactoryPostProcessor
   // (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   beanFactory.freezeConfiguration();

   // Instantiate all remaining (non-lazy-init) singletons.
   beanFactory.preInstantiateSingletons();
}

beanFactory.preInstantiateSingletons();中,会遍历所有的beanNames,然后挨个调用getBean尝试去获取bean。

bean的一切就始于getBean方法,当单例池中有这个bean,直接返回,如果没有,则进行创建。

如果是原型类型的bean,则会当场创建一个并返回

之前注册的BeanPostProcessor就是在这个过程中被调用

创建bean的过程比较复杂,涉及到了循环依赖,一级缓存,二级缓存,三级缓存等,因此单独写了一篇来讲解,请参考 Spring5源码(四):Bean的创建与循环依赖

finishRefresh

初始化LifecycleProcessor并执行onFresh,发布ContextRefreshedEvent事件。该方法不是很重要

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(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   LiveBeansView.registerApplicationContext(this);
}

总结

Spring容器启动流程大致如下:

  1. 扫描bean,封装到BeanDefinition
  2. 准备环境
  3. 执行BeanDefinition后置处理器
  4. 执行BeanFactory后置处理器
  5. 初始化多播器
  6. 注册监听器
  7. 遍历beanName,创建bean
文章作者: 周君
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 周君 !
评论