从servlet到springboot(7) springboot启动 run方法解析之refresh---1

从这一节开始,我们将分析spring初始化中最重要的方法 refresh,spring中bean的初始化就,springboot的自动化配置都是在这一步中进行的。由于内容比较多,我们将分成好几节来讲

这个方法最终调用AbstractApplicationContext中的refresh方法,所以我们直接看这个方法

@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.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         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.
         registerListeners();

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

         // Last step: publish corresponding event.
         finishRefresh();
      }

一步一步来,

prepareRefresh();做了一些准备工作,跳过不分析

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();得到一个beanFactory,这里很明显是

DefalutListableBeanFactory

prepareBeanFactory(beanFactory);
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());
   }
}

代码还是比较多的,总结一下做了这些事情

设置beanFactory的ClassLoader为当前context的ClassLoader
设置ExpressionResolver为StandardBeanExpressionResolver
beanFactory增加一个默认的PropertyEditor,主要是对bean的属性等设置管理的一个工具
添加BeanPostProcessor为ApplicationContextAwareProcessor
添加EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware 到忽略自动装配的接口中,这部分如果有意向探究的可以参考这篇博文https://www.jianshu.com/p/3c7e0608ff1f,当spring将ApplicationContextAwareProcessor注册后,那么在invokeAwareInterfaces中直接,调用的Aware类已经不是普通的bean了,如ResourceLoaderAware,那么需要在spring做bean的依赖注入时忽略它们。
将BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext,当注册了依赖解析后,例如当注册了BeanFactory的解析依赖后,当bean的属性注入的时候,一旦检测到属性为beanFactory类型便会将beanFactory的实例注入进去
增加对aspectJ的支持
添加默认的系统环境bean

接着是postProcessBeanFactory方法

调用父类EmbeddedWebApplicationContext#postProcessBeanFactory方法.给beanFactory添加一个WebApplicationContextServletContextAwareProcessor类型的BeanPostProcessor,并添加了一个忽略装配的接口ServletContextAware.WebApplicationContextServletContextAwareProcessor继承了ServletContextAwareProcessor,而ServletContextAwareProcessor的postProcessBeforeInitialization方法代码已经做了ServletContextAware该做的事情.代码如下:

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(
    new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
1
2
3
4
5
6
如果AnnotationConfigEmbeddedWebApplicationContext中的basePackages大于零的话,就调用ClassPathBeanDefinitionScanner#scan.

如果AnnotationConfigEmbeddedWebApplicationContext中的annotatedClasses大于零的话,就调用AnnotatedBeanDefinitionReader#register.
对于当前的场景来说, basePackages, annotatedClasses 都是为null,因此是不会执行的.

看这个方法
invokeBeanFactoryPostProcessors 从名字上就可以看出这是激活继承BeanFactoryPostProcessor接口的实例的一些方法
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();

if (beanFactory instanceof BeanDefinitionRegistry) {
   BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
   List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
   List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
         new LinkedList<BeanDefinitionRegistryPostProcessor>();

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

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
   // Separate between BeanDefinitionRegistryPostProcessors that implement
   // PriorityOrdered, Ordered, and the rest.
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

   // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
   List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
         processedBeans.add(ppName);
      }
   }
   sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
   registryPostProcessors.addAll(priorityOrderedPostProcessors);
   invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

   // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
   for (String ppName : postProcessorNames) {
      if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
         processedBeans.add(ppName);
      }
   }
   sortPostProcessors(beanFactory, orderedPostProcessors);
   registryPostProcessors.addAll(orderedPostProcessors);
   invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

   // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
   boolean reiterate = true;
   while (reiterate) {
      reiterate = false;
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (!processedBeans.contains(ppName)) {
            BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
            registryPostProcessors.add(pp);
            processedBeans.add(ppName);
            pp.postProcessBeanDefinitionRegistry(registry);
            reiterate = true;
         }
      }
   }

   // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
   invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
   // Invoke factory processors registered with the context instance.
   invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
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.
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
   orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(beanFactory, orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
   nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();

方法比较长。归纳一下

遍历所有继承beanFactoryPostProcessor的实例,如果这个实例还继承了BeanDefinitionRegistryPostProcessor,那么会调用

postProcessBeanDefinitionRegistry方法并加入到registryPostProcessors集合中,如果没有继承就加入到regularPostProcessors集合中

如果实现了BeanDefinitionRegistryPostProcessor的接口集合中的元素还实现了PriorityOrdered接口,那么会被先实例化,然后添加到priorityOrderedPostProcessors集合中,这里实例化调用了beanFactory的getBean方法,这个是一个比较重要的方法,我们后面介绍。随后会排序,执行继承了priorityOrderedPostProcessors接口的postProcessBeanDefinitionRegistry方法。

 紧接着,实现了BeanDefinitionRegistryPostProcessor的接口集合中的元素还实现了Ordered,被添加到orderedPostProcessors集合中,这里同样调用getBean方法。然后接下去步骤和上一部一样

接下去用上两步同样的动作去做只实现了BeanDefinitionRegistryPostProcessor的接口的类

 接下去的代码和上面三步一样,只是执行的是继承了BeanFactoryPostProcessor接口的类,执行的是postProcessBeanFactory方法。

关于postProcessBeanFactory的方法,可以参考这篇博文https://blog.csdn.net/linuu/article/details/50853687

invokeBeanFactoryPostProcessors方法我们终于解析完了,接下去看registerBeanPostProcessors 这个方法
public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   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<BeanPostProcessor>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
   List<String> orderedPostProcessorNames = new ArrayList<String>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
   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(beanFactory, priorityOrderedPostProcessors);
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

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

   // Now, register all regular BeanPostProcessors.
   List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
   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(beanFactory, internalPostProcessors);
   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).
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

首先获取到继承BeanPostProcessor接口的所有类的名字,一共有下面7个

一共有这些

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);
   }
}

分别遍历全部继承BeanPostProcessor接口的类,根据不同情况,通过getBean方法实例化对象,加入到不同的集合中。

每个集合都排序一下,然后通过registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);方法把集合中装的对象加入到beanFactory(其实是DefaultListableBeanFactory) 中的成员变量beanPostProcessors集合中。

跳出回到refresh方法。

initMessageSource 方法是一个国际化方法,没什么好说的

猜你喜欢

转载自blog.csdn.net/m0_37139189/article/details/86312621
今日推荐