-- 以下内容均基于2.1.8.RELEASE版本

紧接着上一篇[(四)SpringBoot启动过程的分析-预处理ApplicationContext] (https://www.cnblogs.com/lukama/p/14583241.html), 本文将分析上下文容器准备完成之后开始执行刷新流程

  1. // SpringApplication.java
  2. private void refreshContext(ConfigurableApplicationContext context) {
  3. refresh(context);
  4. if (this.registerShutdownHook) {
  5. try {
  6. context.registerShutdownHook();
  7. }
  8. catch (AccessControlException ex) {
  9. // Not allowed in some environments.
  10. }
  11. }
  12. }
  13. // 真正的refresh方法在AbstractApplicationContext类中
  14. protected void refresh(ApplicationContext applicationContext) {
  15. Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
  16. ((AbstractApplicationContext) applicationContext).refresh();
  17. }
  18. // AbstractApplicationContext.java
  19. public void refresh() throws BeansException, IllegalStateException {
  20. synchronized (this.startupShutdownMonitor) {
  21. // Prepare this context for refreshing.
  22. prepareRefresh();
  23. // Tell the subclass to refresh the internal bean factory.
  24. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  25. // Prepare the bean factory for use in this context.
  26. prepareBeanFactory(beanFactory);
  27. try {
  28. // Allows post-processing of the bean factory in context subclasses.
  29. postProcessBeanFactory(beanFactory);
  30. // Invoke factory processors registered as beans in the context.
  31. invokeBeanFactoryPostProcessors(beanFactory);
  32. // Register bean processors that intercept bean creation.
  33. registerBeanPostProcessors(beanFactory);
  34. // Initialize message source for this context.
  35. initMessageSource();
  36. // Initialize event multicaster for this context.
  37. initApplicationEventMulticaster();
  38. // Initialize other special beans in specific context subclasses.
  39. onRefresh();
  40. // Check for listener beans and register them.
  41. registerListeners();
  42. // Instantiate all remaining (non-lazy-init) singletons.
  43. finishBeanFactoryInitialization(beanFactory);
  44. // Last step: publish corresponding event.
  45. finishRefresh();
  46. }
  47. catch (BeansException ex) {
  48. if (logger.isWarnEnabled()) {
  49. logger.warn("Exception encountered during context initialization - " +
  50. "cancelling refresh attempt: " + ex);
  51. }
  52. // Destroy already created singletons to avoid dangling resources.
  53. destroyBeans();
  54. // Reset 'active' flag.
  55. cancelRefresh(ex);
  56. // Propagate exception to caller.
  57. throw ex;
  58. }
  59. finally {
  60. // Reset common introspection caches in Spring's core, since we
  61. // might not ever need metadata for singleton beans anymore...
  62. resetCommonCaches();
  63. }
  64. }
  65. }

在refresh方法中清晰的划分了刷新容器的步骤。

prepareRefresh()

主要用于清除元数据Reader的缓存,设置应用程序启动的时间,设置应用程序的活动标记,初始化属性源。

  1. // AnnotationConfigServletWebServerApplicationContext.java
  2. protected void prepareRefresh() {
  3. this.scanner.clearCache();
  4. super.prepareRefresh();
  5. }
  6. // AbstractApplicationContext.java
  7. protected void prepareRefresh() {
  8. // 设置开始执行的时间和活动标记
  9. this.startupDate = System.currentTimeMillis();
  10. this.closed.set(false);
  11. this.active.set(true);
  12. if (logger.isDebugEnabled()) {
  13. if (logger.isTraceEnabled()) {
  14. logger.trace("Refreshing " + this);
  15. }
  16. else {
  17. logger.debug("Refreshing " + getDisplayName());
  18. }
  19. }
  20. // ①
  21. initPropertySources();
  22. // ②
  23. // Validate that all properties marked as required are resolvable:
  24. // see ConfigurablePropertyResolver#setRequiredProperties
  25. getEnvironment().validateRequiredProperties();
  26. // ③
  27. // Store pre-refresh ApplicationListeners...
  28. if (this.earlyApplicationListeners == null) {
  29. this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
  30. }
  31. else {
  32. // Reset local application listeners to pre-refresh state.
  33. this.applicationListeners.clear();
  34. this.applicationListeners.addAll(this.earlyApplicationListeners);
  35. }
  36. // Allow for the collection of early ApplicationEvents,
  37. // to be published once the multicaster is available...
  38. this.earlyApplicationEvents = new LinkedHashSet<>();
  39. }

① - 初始化属性资源

  1. // StandardServletEnvironment.java
  2. public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
  3. WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
  4. }
  5. // WebApplicationContextUtils.java
  6. public static void initServletPropertySources(MutablePropertySources sources,
  7. @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
  8. Assert.notNull(sources, "'propertySources' must not be null");
  9. String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME;
  10. // servletContext不为空且有相关配置的情况
  11. if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
  12. sources.replace(name, new ServletContextPropertySource(name, servletContext));
  13. }
  14. // servletConfig不为空且有相关配置的情况
  15. name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME;
  16. if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
  17. sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
  18. }
  19. }

在内部调用了WebApplicationContextUtils.initServletPropertySources方法,由名称可得知,它用于初始化Servlet的属性资源,在实际执行过程中分别根据ServletContext和ServletConfig的值来判定是否要将指定的配置包装为ServletContextPropertySource。在实际调试过程中他们的值都为空,也就是没有进行任何操作。

② - 检查必备属性,此处是用于检查哪些属性是必不可少的,例如可以设置"example.address"这个属性必须不为空。

③ - 重新对监听器排序

prepareBeanFactory(beanFactory)

  1. // AbstractApplicationContext.java
  2. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  3. // 设置类加载器
  4. // Tell the internal bean factory to use the context's class loader etc.
  5. beanFactory.setBeanClassLoader(getClassLoader());
  6. // 设置SpringEL表达式解析器
  7. beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  8. // 设置属性编辑器注册
  9. beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
  10. // ① 忽略指定的接口注入
  11. // Configure the bean factory with context callbacks.
  12. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  13. beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
  14. beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
  15. beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
  16. beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
  17. beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
  18. beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
  19. // 指定对特定接口注入时实际的注入对象,例如有某对象想要注入BeanFactory,则实际将会指定它注入的是当前设置的BeanFactory
  20. // BeanFactory interface not registered as resolvable type in a plain factory.
  21. // MessageSource registered (and found for autowiring) as a bean.
  22. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  23. beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  24. beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  25. beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  26. // 添加和移除ApplicationListener
  27. // Register early post-processor for detecting inner beans as ApplicationListeners.
  28. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
  29. //
  30. // Detect a LoadTimeWeaver and prepare for weaving, if found.
  31. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
  32. beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
  33. // Set a temporary ClassLoader for type matching.
  34. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  35. }
  36. // 注册默认环境对象
  37. // Register default environment beans.
  38. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
  39. beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  40. }
  41. // 注册系统配置对象
  42. if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
  43. beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  44. }
  45. // 注册系统环境对象
  46. if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
  47. beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  48. }
  49. }

① - 这里的忽略依赖接口,是指这些Aware接口的实现类在Spring中将会自动忽略接口实现类中和setter方法入参相同的类型,举例说明

  1. public interface EnvironmentAware extends Aware {
  2. void setEnvironment(Environment environment);
  3. }
  4. public class MyEnvironmentAware implements Environment {
  5. private Environment environment;
  6. @Overwired
  7. public void setEnvironment(Environment environment) {
  8. this.environment = environment;
  9. }
  10. }

示例中展示了如何使用EnvironmentAware接口来实现在自定义代码中获取Environment,上面所说的忽略,是指在Spring自动装配MyEnvironment这个类的时候,会自动忽略到setEnvironment方法中的Environment对象注入。

在忽略接口的第一行代码添加了一个ApplicationContextAwareProcessor,而它则是Spring框架统一来设置这些Aware接口实现类的处理器。

postProcessBeanFactory(beanFactory)

在当前AbstractApplicationContext类中的postProcessBeanFactory方法并未实现,由其子类实现。

  1. // AnnotationConfigServletWebServerApplicationContext.java
  2. // 实现一
  3. protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  4. // ①
  5. super.postProcessBeanFactory(beanFactory);
  6. // ②
  7. if (this.basePackages != null && this.basePackages.length > 0) {
  8. this.scanner.scan(this.basePackages);
  9. }
  10. // ③
  11. if (!this.annotatedClasses.isEmpty()) {
  12. this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
  13. }
  14. }

① - 调用父类的实现

  1. // ServletWebServerApplicationContext.java
  2. protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  3. // 添加用于处理WebApplicationContextServletContextAware接口的processor
  4. beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
  5. // 忽略ServletContextAware接口的注入
  6. beanFactory.ignoreDependencyInterface(ServletContextAware.class);
  7. registerWebApplicationScopes();
  8. }
  9. // 注册web应用的作用域
  10. public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
  11. @Nullable ServletContext sc) {
  12. beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
  13. beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
  14. if (sc != null) {
  15. ServletContextScope appScope = new ServletContextScope(sc);
  16. beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
  17. // Register as ServletContext attribute, for ContextCleanupListener to detect it.
  18. sc.setAttribute(ServletContextScope.class.getName(), appScope);
  19. }
  20. beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
  21. beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
  22. beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
  23. beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
  24. if (jsfPresent) {
  25. FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
  26. }
  27. }

② - 根据basePackage指定的位置进行扫描bean

③ - 根据注解来扫描指定的bean

invokeBeanFactoryPostProcessors()

主要用于调用BeanFactoryPostProcessors的实现

  1. protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  2. // 调用BeanFactoryPostProcessor
  3. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  4. // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
  5. // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
  6. if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
  7. beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
  8. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  9. }
  10. }

在调用BeanFactoryPostProcessor时,会首先调用BeanDefinitionRegistryPostProcessor, 因为后者是对前者的扩展,并且有可能在后者中又重新注册了前者的其他实例。由于PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法过长,这里直接写行内注释能够比较

直观的分析前后关系。

  1. public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  2. // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  3. // 已处理的Bean
  4. Set<String> processedBeans = new HashSet<>();
  5. // 判断当前的BeanFactory是否为一个Bean注册器,实际上就是代表同时实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor接口的实现
  6. // 对于同时实现两个接口的类,将先调用BeanDefinitionRegistryPostProcessor里面的方法,再调用BeanFactoryPostProcessor里面的方法
  7. // 在调用的时候又要区分是实现了PriorityOrdered还是Ordered接口。
  8. if (beanFactory instanceof BeanDefinitionRegistry) {
  9. // 转换为注册器
  10. BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  11. // 用于存放常规的BeanFactoryPostProcessor
  12. List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
  13. // 用于存放BeanFactoryPostProcessor的扩展BeanDefinitionRegistryPostProcessor,这里是一个汇总的列表
  14. List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
  15. // 遍历传入的BeanFactoryPostProcessor
  16. for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
  17. // 优先执行BeanFactoryPostProcessor的扩展类BeanDefinitionRegistryPostProcessor,它的优先级最高
  18. if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
  19. // 类型转换
  20. BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
  21. // 调用postProcessBeanDefinitionRegistry()方法,内部可能注册了Bean,也可能重新定义了一些普通的BeanFactoryPostProcessor
  22. registryProcessor.postProcessBeanDefinitionRegistry(registry);
  23. // 添加到已处理列表
  24. registryProcessors.add(registryProcessor);
  25. }
  26. else {
  27. // 对比上面if代码块会发现,这里没有作调用,直接先保存在常规列表内部,因为常规的Processor在调用的时候还有其他考虑,接着往下看便是
  28. regularPostProcessors.add(postProcessor);
  29. }
  30. }
  31. // 不要在这里初始化FactoryBean(请看清是FactoryBean,工厂类,不是类工厂(BeanFactory),他们有巨大的差异),需要保留所有的常规类未初始化,以便使用BeanFactoryPostProcessor对其处理
  32. // Do not initialize FactoryBeans here: We need to leave all regular beans
  33. // uninitialized to let the bean factory post-processors apply to them!
  34. // 根据BeanDefinitionRegistryPostProcessors 实现的接口划分为三类:实现了PriorityOrdered的、实现了Ordered的以及前面两者都没实现的
  35. // Separate between BeanDefinitionRegistryPostProcessors that implement
  36. // PriorityOrdered, Ordered, and the rest.
  37. // 保存当前将要处理的BeanDefinitionRegistryPostProcessor列表,每处理完一种分类的就清空
  38. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
  39. // 首先调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
  40. // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
  41. // 获取当前Bean工厂内部所有的,类型为BeanDefinitionRegistryPostProcessor.class的后处理器名称
  42. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  43. for (String ppName : postProcessorNames) {
  44. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  45. // 筛选出实现了PriorityOrdered接口的后处理器,放入当前处理列表
  46. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  47. // 同时放入已处理列表
  48. processedBeans.add(ppName);
  49. }
  50. }
  51. // 按照优先级排序
  52. sortPostProcessors(currentRegistryProcessors, beanFactory);
  53. // 添加实现了PriorityOrder接口的BeanDefinitionRegistryPostProcessor到它的汇总列表里面
  54. registryProcessors.addAll(currentRegistryProcessors);
  55. // 调用所有的BeanDefinitionRegistryPostProcessor实例的postProcessBeanDefinitionRegistry()方法
  56. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  57. // 清除内部的实现了PriorityOrder的BeanDefinitionRegistryPostProcessor
  58. currentRegistryProcessors.clear();
  59. // 上面是处理实现了PriorityOrdered接口的,这里处理实现了Ordered接口的, 为何这里又获取了一次postProcessorNames,前面不是才获取么?
  60. // 这里获取一次是因为前面处理的时候有可能又加入了新的BeanDefinitionRegistryPostProcessor
  61. // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
  62. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  63. for (String ppName : postProcessorNames) {
  64. if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
  65. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  66. processedBeans.add(ppName);
  67. }
  68. }
  69. sortPostProcessors(currentRegistryProcessors, beanFactory);
  70. registryProcessors.addAll(currentRegistryProcessors);
  71. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  72. // 清空上一步已经执行过的
  73. currentRegistryProcessors.clear();
  74. // 继续调用普通的BeanDefinitionRegistryPostProcessors
  75. // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
  76. boolean reiterate = true;
  77. while (reiterate) {
  78. reiterate = false;
  79. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  80. for (String ppName : postProcessorNames) {
  81. if (!processedBeans.contains(ppName)) {
  82. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  83. processedBeans.add(ppName);
  84. reiterate = true;
  85. }
  86. }
  87. sortPostProcessors(currentRegistryProcessors, beanFactory);
  88. registryProcessors.addAll(currentRegistryProcessors);
  89. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
  90. currentRegistryProcessors.clear();
  91. }
  92. // 最后调用普通的 BeanFactoryPostProcessor,
  93. // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
  94. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
  95. //因为BeanDefinitionRegistryPostProcessor也是继承了BeanFactoryPostProcessor,,也具有postProcessBeanFactory()方法的,所以也需要执行
  96. invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  97. }
  98. else {
  99. // 若不是BeanDefinitionRegistry,那就是直接实现了BeanFactoryPostProcessor
  100. // Invoke factory processors registered with the context instance.
  101. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
  102. }
  103. // 下面这部分逻辑就和上面套路一样,无非处理的是BeanFactoryPostProcessor罢了
  104. // Do not initialize FactoryBeans here: We need to leave all regular beans
  105. // uninitialized to let the bean factory post-processors apply to them!
  106. String[] postProcessorNames =
  107. beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
  108. // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
  109. // Ordered, and the rest.
  110. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
  111. List<String> orderedPostProcessorNames = new ArrayList<>();
  112. List<String> nonOrderedPostProcessorNames = new ArrayList<>();
  113. for (String ppName : postProcessorNames) {
  114. if (processedBeans.contains(ppName)) {
  115. // skip - already processed in first phase above
  116. }
  117. else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  118. priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
  119. }
  120. else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  121. orderedPostProcessorNames.add(ppName);
  122. }
  123. else {
  124. nonOrderedPostProcessorNames.add(ppName);
  125. }
  126. }
  127. // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
  128. sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
  129. invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
  130. // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
  131. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
  132. for (String postProcessorName : orderedPostProcessorNames) {
  133. orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  134. }
  135. sortPostProcessors(orderedPostProcessors, beanFactory);
  136. invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
  137. // Finally, invoke all other BeanFactoryPostProcessors.
  138. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
  139. for (String postProcessorName : nonOrderedPostProcessorNames) {
  140. nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  141. }
  142. invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  143. // Clear cached merged bean definitions since the post-processors might have
  144. // modified the original metadata, e.g. replacing placeholders in values...
  145. beanFactory.clearMetadataCache();
  146. }

小结

BeanFactoryPostProcessors是Spring框架中的一个很重要的扩展入口,通过它可以在Bean实例化之前进行一些修改,从类型上分为BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,在内部处理过程中,前者的优先级高于后者。与此同时,他们分别还会按照PriorityOrdered > Ordered > 默认

的优先级顺序来进行处理。了解他们执行顺序这点很重要,后续如有扩展需求就可以精准植入自己的逻辑。需要注意的是,这些处理器本身就是用于注册Bean,因此他们也可以注册和自己类型一样的扩展类。在使用的时候尤其要注意这点。例如在实现了PriorityOrdered的BeanDefinitionRegistryPostProcessor中

再注册一个实现了Ordered的BeanDefinitionRegistryPostProcessor,虽然这样没问题,但笔者认为这样代码隐藏过深。不利于后期维护。建议使用SPI机制来配置,简洁明了。

registerBeanPostProcessors()

主要用于调用BeanPostProcessors的实现,区别于上一个章节,本章节处理的是实例化过后的Bean。

  1. // AbstractApplicationContext.java
  2. protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  3. // 调用BeanPostProcessor
  4. PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
  5. }
  6. // PostProcessorRegistrationDelegate.java
  7. public static void registerBeanPostProcessors(
  8. ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
  9. // 获取所有的BeanPostProcessor名称
  10. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
  11. // Register BeanPostProcessorChecker that logs an info message when
  12. // a bean is created during BeanPostProcessor instantiation, i.e. when
  13. // a bean is not eligible for getting processed by all BeanPostProcessors.
  14. // 注册一个BeanPostProcessorChecker,当一个BeanPostProcessor在实例化期间创建一个Bean的时候,打印日志
  15. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
  16. beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
  17. // 按照优先级整理
  18. // 实现了PriorityOrdered接口的BeanPostProcessor集合
  19. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
  20. // 内部定义的BeanPostProcessor集合
  21. List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
  22. // 实现了Ordered接口的BeanPostProcessor名称集合
  23. List<String> orderedPostProcessorNames = new ArrayList<>();
  24. // 未实现排序优先级接口的BeanPostProcessor名称集合
  25. List<String> nonOrderedPostProcessorNames = new ArrayList<>();
  26. // 分别放入不同集合内
  27. for (String ppName : postProcessorNames) {
  28. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  29. BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
  30. priorityOrderedPostProcessors.add(pp);
  31. if (pp instanceof MergedBeanDefinitionPostProcessor) {
  32. internalPostProcessors.add(pp);
  33. }
  34. }
  35. else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  36. orderedPostProcessorNames.add(ppName);
  37. }
  38. else {
  39. nonOrderedPostProcessorNames.add(ppName);
  40. }
  41. }
  42. // 注册实现了PriorityOrdered接口的BeanPostProcessor
  43. // First, register the BeanPostProcessors that implement PriorityOrdered.
  44. sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
  45. registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
  46. // 注册实现了PriorityOrdered接口的BeanPostProcessor
  47. // Next, register the BeanPostProcessors that implement Ordered.
  48. List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
  49. for (String ppName : orderedPostProcessorNames) {
  50. BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
  51. orderedPostProcessors.add(pp);
  52. if (pp instanceof MergedBeanDefinitionPostProcessor) {
  53. internalPostProcessors.add(pp);
  54. }
  55. }
  56. sortPostProcessors(orderedPostProcessors, beanFactory);
  57. registerBeanPostProcessors(beanFactory, orderedPostProcessors);
  58. // 注册常规的BeanPostProcessor
  59. // Now, register all regular BeanPostProcessors.
  60. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
  61. for (String ppName : nonOrderedPostProcessorNames) {
  62. BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
  63. nonOrderedPostProcessors.add(pp);
  64. if (pp instanceof MergedBeanDefinitionPostProcessor) {
  65. internalPostProcessors.add(pp);
  66. }
  67. }
  68. registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
  69. // 重新注册所有的内部BeanPostProcessor
  70. // Finally, re-register all internal BeanPostProcessors.
  71. sortPostProcessors(internalPostProcessors, beanFactory);
  72. registerBeanPostProcessors(beanFactory, internalPostProcessors);
  73. // 注册ApplicationListenerDetector,它将在bean初始化完成之后检测是否为ApplicationListener,如果是则加入applicationListeners中
  74. // 在Bean销毁之前,提前从ApplicationEventMulticaster中删除
  75. // Re-register post-processor for detecting inner beans as ApplicationListeners,
  76. // moving it to the end of the processor chain (for picking up proxies etc).
  77. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
  78. }

initMessageSource()

初始化MessageSource,若当前上下文中未定义,则使用父类中的定义

  1. // AbstractApplicationContext.java
  2. protected void initMessageSource() {
  3. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  4. if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
  5. this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
  6. // Make MessageSource aware of parent MessageSource.
  7. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
  8. HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
  9. if (hms.getParentMessageSource() == null) {
  10. // Only set parent context as parent MessageSource if no parent MessageSource
  11. // registered already.
  12. hms.setParentMessageSource(getInternalParentMessageSource());
  13. }
  14. }
  15. if (logger.isTraceEnabled()) {
  16. logger.trace("Using MessageSource [" + this.messageSource + "]");
  17. }
  18. }
  19. else {
  20. // Use empty MessageSource to be able to accept getMessage calls.
  21. DelegatingMessageSource dms = new DelegatingMessageSource();
  22. dms.setParentMessageSource(getInternalParentMessageSource());
  23. this.messageSource = dms;
  24. beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
  25. if (logger.isTraceEnabled()) {
  26. logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
  27. }
  28. }
  29. }

initApplicationEventMulticaster()

主要用于设置事件发布器,若当前上下文没有定义ApplicationEventMulticaster 则使用 SimpleApplicationEventMulticaster

  1. // AbstractApplicationContext.java
  2. protected void initApplicationEventMulticaster() {
  3. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  4. if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
  5. this.applicationEventMulticaster =
  6. beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
  7. if (logger.isTraceEnabled()) {
  8. logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
  9. }
  10. }
  11. else {
  12. this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
  13. beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
  14. if (logger.isTraceEnabled()) {
  15. logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
  16. "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
  17. }
  18. }
  19. }

onRefresh()

当前类中没有实现,只是作为一个模板,将由子类来实现

  1. // AbstractApplicationContext.java
  2. protected void onRefresh() throws BeansException {
  3. // For subclasses: do nothing by default.
  4. }
  5. // ServletWebServerApplicationContext.java
  6. protected void onRefresh() {
  7. // 父类中仅仅设置了一下主题,无关紧要
  8. super.onRefresh();
  9. try {
  10. // 创建Web服务器
  11. createWebServer();
  12. }
  13. catch (Throwable ex) {
  14. throw new ApplicationContextException("Unable to start web server", ex);
  15. }
  16. }

创建Web服务器

这里只简单介绍一下它启动了内置的Web容器,Web容器的初始化后续会有单独篇章分析。

  1. private void createWebServer() {
  2. // ①
  3. WebServer webServer = this.webServer;
  4. // ②
  5. ServletContext servletContext = getServletContext();
  6. // ③
  7. if (webServer == null && servletContext == null) {
  8. ServletWebServerFactory factory = getWebServerFactory();
  9. this.webServer = factory.getWebServer(getSelfInitializer());
  10. }
  11. // ④
  12. else if (servletContext != null) {
  13. try {
  14. getSelfInitializer().onStartup(servletContext);
  15. }
  16. catch (ServletException ex) {
  17. throw new ApplicationContextException("Cannot initialize servlet context", ex);
  18. }
  19. }
  20. // ⑤
  21. initPropertySources();
  22. }

① - 当前应用的WEB服务器,也就是Servlet容器。

② - 当前应用的上下文,一个应用使用一个ServletContext来表示。

③ - 使用ServletWebServerFactory创建一个Servlet容器

④ - 手动配置上下文的接口。

⑤ - 初始化配置信息,实际上就是将环境信息中的'servletContextInitParams':StubPropertySource 转换为'servletContextInitParams': ServletContextPropertySource; 将 'servletConfigInitParams': StubPropertySource转换为'servletConfigInitParams':ServletConfigPropertySource

registerListeners()

主要用于将获取到的所有监听器委托给applicationEventMulticaster。

  1. protected void registerListeners() {
  2. // ①
  3. // Register statically specified listeners first.
  4. for (ApplicationListener<?> listener : getApplicationListeners()) {
  5. getApplicationEventMulticaster().addApplicationListener(listener);
  6. }
  7. // ②
  8. // Do not initialize FactoryBeans here: We need to leave all regular beans
  9. // uninitialized to let post-processors apply to them!
  10. String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
  11. for (String listenerBeanName : listenerBeanNames) {
  12. getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  13. }
  14. // ③
  15. // Publish early application events now that we finally have a multicaster...
  16. Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
  17. this.earlyApplicationEvents = null;
  18. if (earlyEventsToProcess != null) {
  19. for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
  20. getApplicationEventMulticaster().multicastEvent(earlyEvent);
  21. }
  22. }
  23. }

① - 将内部注册的监听器委托给广播器applicationEventMulticaster。

② - 检测BeanFactory内部的监听器

③ - 发布早期事件

finishBeanFactoryInitialization()

实例化剩下的所有单例Bean(非延迟加载的)

  1. // AbstractApplicationContext.java
  2. protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  3. // ①
  4. // Initialize conversion service for this context.
  5. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
  6. beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
  7. }
  8. // ②
  9. // Register a default embedded value resolver if no bean post-processor
  10. // (such as a PropertyPlaceholderConfigurer bean) registered any before:
  11. // at this point, primarily for resolution in annotation attribute values.
  12. if (!beanFactory.hasEmbeddedValueResolver()) {
  13. beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
  14. }
  15. // ③
  16. // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
  17. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
  18. for (String weaverAwareName : weaverAwareNames) {
  19. getBean(weaverAwareName);
  20. }
  21. // ④
  22. // Stop using the temporary ClassLoader for type matching.
  23. beanFactory.setTempClassLoader(null);
  24. // ⑤
  25. // Allow for caching all bean definition metadata, not expecting further changes.
  26. beanFactory.freezeConfiguration();
  27. // ⑤
  28. // Instantiate all remaining (non-lazy-init) singletons.
  29. beanFactory.preInstantiateSingletons();
  30. }

① - 判断是否有转换服务

② - 判断是否有占位符解析器

③ - 注册LoadTimeWeaverAware

④ - 停止使用临时的ClassLoader进行类型匹配,实际上它就是空值

⑤ - 冻结所有的BeanDefinition,通过configurationFrozen = true 和 frozenBeanDefinitionNames(包含所有的BeanDefinition)配合锁定

⑥ - 实例化剩下的所有单例Bean(非延迟加载的),其实就是从注册器缓存里面取出(DefaultSingletonBeanRegistry)

finishRefresh()

  1. // ServletWebServerApplicationContext.java
  2. @Override
  3. protected void finishRefresh() {
  4. // 父类执行finishRefresh
  5. super.finishRefresh();
  6. // 启动web容器
  7. WebServer webServer = startWebServer();
  8. if (webServer != null) {
  9. // 发布web容器启动完成事件
  10. publishEvent(new ServletWebServerInitializedEvent(webServer, this));
  11. }
  12. }
  13. // AbstractApplicationContext.java
  14. protected void finishRefresh() {
  15. // ① Clear context-level resource caches (such as ASM metadata from scanning).
  16. clearResourceCaches();
  17. // ② Initialize lifecycle processor for this context.
  18. initLifecycleProcessor();
  19. // ③ Propagate refresh to lifecycle processor first.
  20. getLifecycleProcessor().onRefresh();
  21. // ④ Publish the final event.
  22. publishEvent(new ContextRefreshedEvent(this));
  23. // ⑤ Participate in LiveBeansView MBean, if active.
  24. LiveBeansView.registerApplicationContext(this);
  25. }

① - 清除资源缓存

② - 初始化上下文生命周期

③ - 传播刷新动作至生命周期

④ - 发布上下文刷新完毕事件

⑤ - 构建当前Bean及其依赖关系的快照,设计用于Spring Tool Suite

resetCommonCaches()

主要用于清除Spring内部的缓存

  1. // AbstractApplicationContext.java
  2. protected void resetCommonCaches() {
  3. ReflectionUtils.clearCache();
  4. AnnotationUtils.clearCache();
  5. ResolvableType.clearCache();
  6. CachedIntrospectionResults.clearClassLoader(getClassLoader());
  7. }

(五)SpringBoot启动过程的分析-刷新ApplicationContext的更多相关文章

  1. (四)SpringBoot启动过程的分析-预处理ApplicationContext

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(三)SpringBoot启动过程的分析-创建应用程序上下文,本文将分析上下文创建完毕之后的下一步操作:预处理上下文容器. 预处理上下文 ...

  2. (三)SpringBoot启动过程的分析-创建应用程序上下文

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(二)SpringBoot启动过程的分析-环境信息准备,本文将分析环境准备完毕之后的下一步操作:ApplicationContext的创 ...

  3. (一)SpringBoot启动过程的分析-启动流程概览

    -- 以下内容均基于2.1.8.RELEASE版本 通过粗粒度的分析SpringBoot启动过程中执行的主要操作,可以很容易划分它的大流程,每个流程只关注重要操作为后续深入学习建立一个大纲. 官方示例 ...

  4. (二)SpringBoot启动过程的分析-环境信息准备

    -- 以下内容均基于2.1.8.RELEASE版本 由上一篇SpringBoot基本启动过程的分析可以发现在run方法内部启动SpringBoot应用时采用多个步骤来实现,本文记录启动的第二个环节:环 ...

  5. SpringBoot启动过程原理

    最近这两年springboot突然火起来了,那么我们就来看看springboot的运行原理. 一.springboot的三种启动方式: 1.运行带有main方法的2.通过命令 Java -jar命令3 ...

  6. Spring Boot 学习笔记一(SpringBoot启动过程)

    SpringBoot启动 Spring Boot通常有一个名为*Application的入口类,在入口类里有一个main方法,这个main方法其实就是一个标准的java应用的入口方法. 在main方法 ...

  7. U-Boot启动过程完全分析

    U-Boot启动过程完全分析 1.1       U-Boot工作过程 U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 硬件设备初始化 加载U-Boot第二阶段 ...

  8. Android应用程序组件Content Provider的启动过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6963418 通过前面的学习,我们知道在Andr ...

  9. Android系统默认Home应用程序(Launcher)的启动过程源代码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个 Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home ...

随机推荐

  1. RESTful 架构 && RESTful API

    RESTful 架构 && RESTful API REpresentational State Transfer (REST) 具象状态传输https://en.wikipedia. ...

  2. SVG viewBox & coordinate system

    SVG viewBox & coordinate system https://codepen.io/xgqfrms/pen/abOOrjp <html> <body> ...

  3. USDN代币的特点

    USDN是NGK公链发行的算法型稳定币,采用智能合约发行,通过智能合约的透明化,能够让市场USND持有者获得算法稳定的背书.USDN是一种锚定全球通用的代币,更是连接全球数字经济的通用数字代币.USD ...

  4. Java基础篇(04):日期与时间API用法详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.时间和日期 在系统开发中,日期与时间作为重要的业务因素,起到十分关键的作用,例如同一个时间节点下的数据生成,基于时间范围的各种数据统计和分 ...

  5. Mysql之用户认证授权管理

    概述 Mysql的认证采用账号密码方式,其中账号由两个部分组成:Host和User:Host为允许登录的客户端Ip,User为当前登录的用户名. 授权没有采用典型的RBAC(基于角色的访问控制),而是 ...

  6. C语言指针基本知识

    对程序进行编译的时候,系统会把变量分配在内存单位中,根据不同的变量类型,分配不同的字节大小.比如int整型变量分配4个字节,char字符型变量分配1个字节等等.被分配在内存的变量,可以通过地址去找到, ...

  7. 1047 Student List for Course ——PAT甲级真题

    1047 Student List for Course Zhejiang University has 40,000 students and provides 2,500 courses. Now ...

  8. CentOS7安装Kafka2.6.0

    1:下载 wget https://mirror.bit.edu.cn/apache/kafka/2.6.0/kafka_2.12-2.6.0.tgz 点击前往官网 2:解压 tar -zxvf ka ...

  9. Django框架admin后台管理和用户端静态文件

    目录 一.admin后台管理 1. 如何使用 2. 路由分发的本质 二.用户上传的静态文件的展示 1. media配置 2. 手动开设media接口 三.图片防盗链 一.admin后台管理 djang ...

  10. 高级FTP

      一.作业需求 1. 用户加密认证(已完成) 2. 多用户同时登陆(已完成) 3. 每个用户有自己的家目录且只能访问自己的家目录(已完成) 4. 对用户进行磁盘配额.不同用户配额可不同(已完成) 5 ...