前言
我们来到了SpringApplication#run方法的第9步,这步做的工作比较多.我们慢慢来.
分析
第9步执行的是如下代码:
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
// 注册一个关闭容器时的钩子函数
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}
2件事
- 调用AbstractApplicationContext#refresh 完成初始化.
注册一个关闭容器时的钩子函数,如果registerShutdownHook 为true的话,默认是true.
AbstractApplicationContext#refresh 代码如下:
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(); } 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. 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(); } } }
做了13件事:
- 调用 prepareRefresh 进行刷新的准备
- 初始化BeanFactory
- 对bean factory进行各种功能填充 @Qualifler与@Autowired就是在这一步骤增加支持
- 扩展点,postProcessBeanFactory 子类覆盖方法做额外的处理
- 激活各种BeanFactory处理器
- 注册拦截bean创建的bean处理器,这里只是注册,真正的调用是在getBean的时候
- 为上下文初始化MessageSource,即国际化处理
- 初始化ApplicationEventMulticaster,并放入ApplicationEventMulticaster bean中
- 扩展点,onRefresh,留个子类来初始化其他的bean
- 在所有注册的bean中查找listener beans,注册到消息广播器中
- 初始化剩下的单例(non-lazy-init)
- 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出contextRefreshEvent通知别人
- 清除缓存
我们分别来进行解析.
prepareRefresh 执行的是AnnotationConfigEmbeddedWebApplicationContext#prepareRefresh,代码如下:
protected void prepareRefresh() { this.scanner.clearCache(); super.prepareRefresh(); }
2件事:
清空ClassPathBeanDefinitionScanner的缓存.执行如下代码:
public void clearCache() { if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); } }
由于ClassPathBeanDefinitionScanner 中的metadataReaderFactory 是CachingMetadataReaderFactory的子类,因此会强转为CachingMetadataReaderFactory调用其clearCache.代码如下:
public void clearCache() { synchronized (this.metadataReaderCache) { this.metadataReaderCache.clear(); } }
清空class metadata 的缓存
调用其父类的AbstractApplicationContext的prepareRefresh方法.代码如下:
protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // Initialize any placeholder property sources in the context environment initPropertySources(); // Validate that all properties marked as required are resolvable // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); }
5件事
- 将startupDate设为当前时间,closed 设为false,active 设为true。
打印日志.如下:
[2m2017-12-25 15:53:15.384[0;39m [32m INFO[0;39m [35m53253[0;39m [2m—[0;39m [2m[ main][0;39m [36mationConfigEmbeddedWebApplicationContext[0;39m [2m:[0;39m Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@cb0755b: startup date [Mon Dec 25 15:53:09 CST 2017]; root of context hierarchy
调用 initPropertySources 这个方法,该方法是个扩展点,最终会调用GenericWebApplicationContext#initPropertySources,代码如下:
protected void initPropertySources() { ConfigurableEnvironment env = getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null); } }
最终会调用StandardServletEnvironment#initPropertySources方法.代码如下:
WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
调用
public static void initServletPropertySources( MutablePropertySources propertySources, ServletContext servletContext, ServletConfig servletConfig) { Assert.notNull(propertySources, "'propertySources' must not be null"); if (servletContext != null && propertySources.contains(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) && propertySources.get(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) { propertySources.replace(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME,new ServletContextPropertySource(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME, servletContext)); } if (servletConfig != null && propertySources.contains(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)&&propertySources.get(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) { propertySources.replace(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME,new ServletConfigPropertySource(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME, servletConfig)); } }
- 判断如果servletContext 不等null并且propertySources包含servletContextInitParams的定义并且是StubPropertySource的子类的话,就替换为ServletContextPropertySource.
- 判断如果servletConfig 不等于null 并且 propertySources 包含servletConfigInitParams的 定义并且是StubPropertySource的子类的话,就替换为ServletConfigPropertySource.
很明显,这里传入的servletContext, servletConfig都是null,因此不会执行.
获得Environment,检查是否存在 RequiredProperties 不存在的情况.当前获得的Environment为StandardServletEnvironment.其validateRequiredProperties实现如下:
public void validateRequiredProperties() throws MissingRequiredPropertiesException { this.propertyResolver.validateRequiredProperties(); }
调用
public void validateRequiredProperties() { MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException(); for (String key : this.requiredProperties) { if (this.getProperty(key) == null) { ex.addMissingRequiredProperty(key); } } if (!ex.getMissingRequiredProperties().isEmpty()) { throw ex; } }
很明显,这里通过遍历requiredProperties,尝试去获取,如果获取不到,就抛出MissingRequiredPropertiesException异常.
实例化earlyApplicationEvents .
接下来执行obtainFreshBeanFactory方法来初始化BeanFactory.代码如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
2件事:
调用refreshBeanFactory,初始化BeanFactory. 最终执行的是GenericApplicationContext#refreshBeanFactory,代码如下:
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()); }
2件事:
- 将refreshed设为true,如果设置失败,说明该方法重复调用了,抛出IllegalStateException.
为beanFactory设置SerializationId, 其id是由ContextIdApplicationContextInitializer#initialize 生成的,我们之前有分析过,生成的id如下:
application:test:8881
beanFactory#setSerializationId代码如下:
public void setSerializationId(String serializationId) { if (serializationId != null) { serializableFactories.put(serializationId, new WeakReference<DefaultListableBeanFactory>(this)); } else if (this.serializationId != null) { serializableFactories.remove(this.serializationId); } this.serializationId = serializationId; }
返回当前实体的BeanFactory属性,代码如下:
public final ConfigurableListableBeanFactory getBeanFactory() { return this.beanFactory; }
返回的是DefaultListableBeanFactory.
调用prepareBeanFactory方法.代码如下:
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 到忽略自动装配的接口中,当spring将ApplicationContextAwareProcessor注册后,那么在invokeAwareInterfaces中直接,调用的Aware类已经不是普通的bean了,如ResourceLoaderAware,那么需要在spring做bean的依赖注入时忽略它们。
- 将BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext,当注册了依赖解析后,例如当注册了BeanFactory的解析依赖后,当bean的属性注入的时候,一旦检测到属性为beanFactory类型便会将beanFactory的实例注入进去
- 增加对aspectJ的支持
- 添加默认的系统环境bean
执行扩展点–>postProcessBeanFactory 子类覆盖方法做额外的处理.最终执行的是AnnotationConfigEmbeddedWebApplicationContext#postProcessBeanFactory方法,代码如下:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.postProcessBeanFactory(beanFactory); if (this.basePackages != null && this.basePackages.length > 0) { this.scanner.scan(this.basePackages); } if (this.annotatedClasses != null && this.annotatedClasses.length > 0) { this.reader.register(this.annotatedClasses); } }
3件事:
调用父类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); }
如果AnnotationConfigEmbeddedWebApplicationContext中的basePackages大于零的话,就调用ClassPathBeanDefinitionScanner#scan.
- 如果AnnotationConfigEmbeddedWebApplicationContext中的annotatedClasses大于零的话,就调用AnnotatedBeanDefinitionReader#register.
对于当前的场景来说, basePackages, annotatedClasses 都是为null,因此是不会执行的.
激活各种BeanFactory处理器,执行如下代码:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
- 调用PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors.
- 如果beanFactory.getTempClassLoader() 等于null并且 beanFactory含有loadTimeWeaver的定义的话,就向beanFactory添加一个LoadTimeWeaverAwareProcessor,然后设置TempClassLoader 为 ContextTypeMatchClassLoader.
其中第一步获得的BeanFactoryPostProcessor 有如下:
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor, org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor, org.springframework.boot.context.config.ConfigFileApplicationListener$PropertySourceOrderingPostProcessor
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors 代码如下:
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 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> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } 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. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 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); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. 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(); // 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)) { 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. invokeBeanFactoryPostProcessors(registryProcessors, 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(priorityOrderedPostProcessors, beanFactory); 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(orderedPostProcessors, beanFactory); 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(); }
首先判断beanFactory 是否为BeanDefinitionRegistry 的实例
如果是的话,则遍历beanFactoryPostProcessors
- 如果beanFactoryPostProcessor 是BeanDefinitionRegistryPostProcessor子类的话,则调用其postProcessBeanDefinitionRegistry对BeanDefinitionRegistry进行处理,然后添加到registryProcessors中.
否则添加到regularPostProcessors中.
从beanFactory中获得实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的实例,添加到priorityOrderedPostProcessors中,排序后,调用invokeBeanDefinitionRegistryPostProcessors进行处理.
- 从beanFactory中获得实现了Ordered接口的BeanDefinitionRegistryPostProcessor的实例,添加到orderedPostProcessors中,排序后,调用invokeBeanDefinitionRegistryPostProcessors进行处理.
- 处理其它为处理过的BeanDefinitionRegistryPostProcessor.调用其postProcessBeanDefinitionRegistry,进行处理. 添加到registryPostProcessors,processedBeans中
- 依次遍历registryPostProcessors,regularPostProcessors,调用其postProcessBeanFactory进行处理.
- 如果不是,直接调用PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors进行处理.
对于当前场景, beanFactory 是 BeanDefinitionRegistry 的子类.因此为执行1.1
从beanFactory中获得BeanFactoryPostProcessor的Name.
对postProcessor进行分类
- 如果已经处理过了,则跳过
- 如果是PriorityOrdered的子类,则添加到priorityOrderedPostProcessors中
- 如果是Ordered的子类,则添加到orderedPostProcessorNames中
- 如果都不符合,则加入到nonOrderedPostProcessorNames
- 对添加到PriorityOrdered中的BeanFactoryPostProcessors 排序后调用invokeBeanFactoryPostProcessors进行处理
- 对添加到orderedPostProcessorNames中的name,从beanFactory中获取相应的实例后,添加到orderedPostProcessors,排序后调用invokeBeanFactoryPostProcessors进行处理
- 对添加到nonOrderedPostProcessorNames中的name,从beanFactory中获取相应的实例后,添加到nonOrderedPostProcessors,排序后调用invokeBeanFactoryPostProcessors进行处理
清空beanFactory中的Metadata的缓存.代码如下:
public void clearMetadataCache() { super.clearMetadataCache(); clearByTypeCache(); }
由于此时传入beanFactory是BeanDefinitionRegistry 的子类,因此为执行1.1 .同时传入的beanFactoryPostProcessors有如下3个:
ConfigurationWarningsApplicationContextInitializer, SharedMetadataReaderFactoryContextInitializer, PropertySourceOrderingPostProcessor
由于ConfigurationWarningsApplicationContextInitializer是BeanDefinitionRegistryPostProcessor的子类,因此会调用其postProcessBeanDefinitionRegistry,然后添加到registryProcessors中,其实现如下:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { for (Check check : this.checks) { String message = check.getWarning(registry); if (StringUtils.hasLength(message)) { warn(message); } } }
通过遍历其Check,进行检查,如果存在警告,则打印警告日志.
对于当前场景来说,checks 只有一个ComponentScanPackageCheck.因此为执行如下方法:public String getWarning(BeanDefinitionRegistry registry) { Set<String> scannedPackages = getComponentScanningPackages(registry); List<String> problematicPackages = getProblematicPackages(scannedPackages); if (problematicPackages.isEmpty()) { return null; } return "Your ApplicationContext is unlikely to " + "start due to a @ComponentScan of " + StringUtils.collectionToDelimitedString(problematicPackages, ", ") + "."; }
SharedMetadataReaderFactoryContextInitializer同样也是BeanDefinitionRegistryPostProcessor的子类,因此会加入到registryPostProcessors中.其实现如下:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { register(registry); configureConfigurationClassPostProcessor(registry); }
2件事
- 调用register,向registry注册了一个名为 org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory ,class为SharedMetadataReaderFactoryBean 的bean。
调用configureConfigurationClassPostProcessor,从registry获得org.springframework.context.annotation.internalConfigurationAnnotationProcessor的bean后,向其添加了一个 名为metadataReaderFactory ,对 org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory 的引用.代码如下:
private void configureConfigurationClassPostProcessor( BeanDefinitionRegistry registry) { try { BeanDefinition definition = registry.getBeanDefinition( AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME); definition.getPropertyValues().add("metadataReaderFactory", new RuntimeBeanReference(BEAN_NAME)); } catch (NoSuchBeanDefinitionException ex) { } }
PropertySourceOrderingPostProcessor则不是BeanDefinitionRegistryPostProcessor的子类,因此添加到regularPostProcessors中.
1.1.3 获得的实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessorde bean 有ConfigurationClassPostProcessor,其id为org.springframework.context.annotation.internalConfigurationAnnotationProcessor.在添加到registryProcessors后,会调用其postProcessBeanDefinitionRegistry方法.
这是一个核心,我们后续文章进行分析.1.1.4 获得实现Ordered接口的BeanDefinitionRegistryPostProcessor为0,因此也就不会执行
1.1.5 中首先获得BeanDefinitionRegistryPostProcessor的beanName,只有org.springframework.context.annotation.internalConfigurationAnnotationProcessor.由于该类已经处理过了–> 也就是ConfigurationClassPostProcessor,因此不会对其处理.
1.1.6 中registryPostProcessors有ConfigurationWarningsPostProcessor, SharedMetadataReaderFactoryContextInitializer, ConfigurationClassPostProcessor.因此会调用其postProcessBeanFactory进行处理.
ConfigurationWarningsPostProcessor,SharedMetadataReaderFactoryContextInitializer都是空实现.ConfigurationClassPostProcessor#postProcessBeanFactory代码如下:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { int factoryId = System.identityHashCode(beanFactory); if (this.factoriesPostProcessed.contains(factoryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + beanFactory); } this.factoriesPostProcessed.add(factoryId); if (!this.registriesPostProcessed.contains(factoryId)) { // BeanDefinitionRegistryPostProcessor hook apparently not supported... // Simply call processConfigurationClasses lazily at this point then. processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); } enhanceConfigurationClasses(beanFactory); beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory)); }
5件事
- 生成factoryId.
- 添加到factoriesPostProcessed中
- 如果registriesPostProcessed 不包含factoryId,则意味着没有对其进行处理,则对其进行处理.这里已经对其处理过了,因此不会执行.
对beanFactory进行增强.代码如下:
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) { Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<String, AbstractBeanDefinition>(); for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); // 1.通过检查BeanDefinition中的configurationClass 是否为full 来进行判断 if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) { // 1.1 如果beanDef 不是AbstractBeanDefinition的子类,则抛出异常 if (!(beanDef instanceof AbstractBeanDefinition)) { throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass"); } // 1.2 如果beanFactory中已经有了beanName 定义的bean 并且log 的日志级别为warn的话,则打印日志 else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) { logger.warn("Cannot enhance @Configuration bean definition '" + beanName + "' since its singleton instance has been created too early. The typical cause " + "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + "return type: Consider declaring such methods as 'static'."); } // 1.3 加入到configBeanDefs 中 configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } } // 2. 如果configBeanDefs 为空,直接return if (configBeanDefs.isEmpty()) { // nothing to enhance -> return immediately return; } ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer(); for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) { AbstractBeanDefinition beanDef = entry.getValue(); // If a @Configuration class gets proxied, always proxy the target class // 3.1 设置preserveTargetClass属性为true beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); try { // Set enhanced subclass of the user-specified bean class Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader); // 3.2 对其进行增强 Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader); if (configClass != enhancedClass) { if (logger.isDebugEnabled()) { logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " + "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName())); } // 3.3 如果增强成功的话,则设置BeanClass为增强后的Class beanDef.setBeanClass(enhancedClass); } } catch (Throwable ex) { throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex); } } }
通过遍历beanFactory中注册的beanName.如果BeanDefinition中的configurationClass 为full.
- 如果beanDef 不是AbstractBeanDefinition的子类,则抛出异常
- 如果beanFactory中已经有了beanName 定义的bean 并且log 的日志级别为warn的话,则打印日志
- 添加到configBeanDefs中.
- 如果configBeanDefs 为空,直接return
- 遍历configBeanDefs,设置preserveTargetClass属性为true.调用ConfigurationClassEnhancer#enhance 对其进行增强,如果增强成功的话,则设置BeanClass为增强后的Class.
- 添加一个BeanPostProcessor–>ImportAwareBeanPostProcessor
1.1.6 中regularPostProcessors 只有一个PropertySourceOrderingPostProcessor,其postProcessBeanFactory代码如下:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { reorderSources(this.context.getEnvironment()); }
调用
private void reorderSources(ConfigurableEnvironment environment) { ConfigurationPropertySources .finishAndRelocate(environment.getPropertySources()); PropertySource<?> defaultProperties = environment.getPropertySources() .remove(DEFAULT_PROPERTIES); if (defaultProperties != null) { environment.getPropertySources().addLast(defaultProperties); } }
2件事:
- 从environment中的PropertySources 删除applicationConfigurationProperties
- 从PropertySources删除defaultProperties,如果删除成功的话,就添加到environment的最后.对于当前来说,PropertySources是不存在defaultProperties的
我们回到PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors中的第2步,从beanFactory中获得BeanFactoryPostProcessor的name如下:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor, propertySourcesPlaceholderConfigurer, org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.store, preserveErrorControllerTargetClassPostProcessor
其中实现了PriorityOrdered接口的有PropertySourcesPlaceholderConfigurer,因此会调用其postProcessBeanFactory方法,代码如下:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (this.propertySources == null) { this.propertySources = new MutablePropertySources(); if (this.environment != null) { this.propertySources.addLast( new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) { @Override public String getProperty(String key) { return this.source.getProperty(key); } } ); } try { PropertySource<?> localPropertySource = new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties()); if (this.localOverride) { this.propertySources.addFirst(localPropertySource); } else { this.propertySources.addLast(localPropertySource); } } catch (IOException ex) { throw new BeanInitializationException("Could not load properties", ex); } } processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources)); this.appliedPropertySources = this.propertySources; }
3件事
- 如果propertySources为null的话,就实例化MutablePropertySources,如果environment 不为null的话,就向propertySources添加一个 名为 environmentProperties 的 PropertySource,实例化 name 为 localProperties 的PropertiesPropertySource
调用processProperties 处理Placeholder. 代码如下:
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, final ConfigurablePropertyResolver propertyResolver) throws BeansException { // 1. 设置propertyResolver的属性 // 设置Placeholder 前缀为 ${ propertyResolver.setPlaceholderPrefix(this.placeholderPrefix); // 设置Placeholder 后缀为 } propertyResolver.setPlaceholderSuffix(this.placeholderSuffix); // 设置 ValueSeparator 为 : propertyResolver.setValueSeparator(this.valueSeparator); // 2. 实例化StringValueResolver StringValueResolver valueResolver = new StringValueResolver() { @Override public String resolveStringValue(String strVal) { String resolved = (ignoreUnresolvablePlaceholders ? propertyResolver.resolvePlaceholders(strVal) : propertyResolver.resolveRequiredPlaceholders(strVal)); if (trimValues) { resolved = resolved.trim(); } return (resolved.equals(nullValue) ? null : resolved); } }; // 3. 进行处理 doProcessProperties(beanFactoryToProcess, valueResolver); }
3件事
- 设置propertyResolver的属性,设置Placeholder 前缀为 ${,设置Placeholder 后缀为 },设置 ValueSeparator 为 :
- 实例化StringValueResolver
调用doProcessProperties进行处理.代码如下:
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, StringValueResolver valueResolver) { // 1. 实例化BeanDefinitionVisitor BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver); // 2. 获得beanFactoryToProcess中的BeanDefinitionNames String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames(); for (String curName : beanNames) { // Check that we're not parsing our own bean definition, // to avoid failing on unresolvable placeholders in properties file locations. if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) { // 3. 如果curName 不等于当前的beanName,并且beanFactoryToProcess 等于this.beanFactory的话,获得对应的 // BeanDefinition BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName); try { // 4. visitBeanDefinition visitor.visitBeanDefinition(bd); } catch (Exception ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage(), ex); } } } // New in Spring 2.5: resolve placeholders in alias target names and aliases as well. // 5. 对于别名的处理 beanFactoryToProcess.resolveAliases(valueResolver); // New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes. // 6. 对于嵌套的处理 beanFactoryToProcess.addEmbeddedValueResolver(valueResolver); }
6件事:
- 实例化BeanDefinitionVisitor
- 获得beanFactoryToProcess中的BeanDefinitionNames
- 遍历BeanDefinitionNames,如果curName 不等于当前的beanName,并且beanFactoryToProcess 等于this.beanFactory的话,获得对应的BeanDefinition,然后调用BeanDefinitionVisitor#visitBeanDefinition进行处理.
- 对于别名的处理
- 对于嵌套的处理,向embeddedValueResolvers添加了StringValueResolver.
- 将appliedPropertySources赋值为propertySources.
第5步,实现了Ordered接口的BeanFactoryPostProcessor没有.
第6步,nonOrderedPostProcessors的BeanFactoryPostProcessor有org.springframework.boot.context.properties.ConfigurationBeanFactoryMetaData org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor
其中ConfigurationBeanFactoryMetaData#postProcessBeanFactory实现如下:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; for (String name : beanFactory.getBeanDefinitionNames()) { BeanDefinition definition = beanFactory.getBeanDefinition(name); String method = definition.getFactoryMethodName(); String bean = definition.getFactoryBeanName(); if (method != null && bean != null) { this.beans.put(name, new MetaData(bean, method)); } } }
遍历beanFactory中的BeanDefinitionNames,获得相应的BeanDefinition,如果FactoryMethodName,FactoryBeanName 都有配置的话,就添加到beans 中.
ErrorControllerTargetClassPostProcessor#postProcessBeanFactory,代码如下:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { String[] errorControllerBeans = beanFactory .getBeanNamesForType(ErrorController.class, false, false); for (String errorControllerBean : errorControllerBeans) { try { beanFactory.getBeanDefinition(errorControllerBean).setAttribute( AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); } catch (Throwable ex) { // Ignore } } }
从beanFactory 获得ErrorController的实例,设置preserveTargetClass 为true.这里默认只有一个,为basicErrorController
注册拦截bean创建的bean处理器,这里只是注册,真正的调用是在getBean的时候.代码如下:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
调用
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(priorityOrderedPostProcessors, beanFactory); 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(orderedPostProcessors, beanFactory); 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(internalPostProcessors, beanFactory); 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类型的postProcessorNames.如下:
org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor, embeddedServletContainerCustomizerBeanPostProcessor, errorPageRegistrarBeanPostProcessor, methodValidationPostProcessor
一共7个
- 添加一个BeanPostProcessor–>BeanPostProcessorChecker.BeanPostProcessorChecker是一个普通的信息打印,可能会有些情况,当spring的配置中的后处理器还没有被注册就已经开始了bean的初始化时便会打印出BeanPostProcessorChecker设定的信息.
遍历postProcessorNames,
- 如果该postProcessor实现了PriorityOrdered,则加入priorityOrderedPostProcessors中
- 如果postProcessor实现了PriorityOrdered和MergedBeanDefinitionPostProcessor,则加入到internalPostProcessors
- 如果postProcessor实现了Ordered,则加入到orderedPostProcessorNames中.
- 否则加入到nonOrderedPostProcessorNames.
注册所有实现PriorityOrdered的BeanPostProcessor.如下:
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor, org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor, org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor
注册所有实现Ordered的BeanPostProcessor.如下:
methodValidationPostProcessor
注册所有无序的BeanPostProcessor.如下:
embeddedServletContainerCustomizerBeanPostProcessor, errorPageRegistrarBeanPostProcessor
注册所有MergedBeanDefinitionPostProcessor类型的BeanPostProcessor,并非是重复注册.如下:
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor, org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
- 添加ApplicationListenerDetector–>ApplicationListenerDetector.
为上下文初始化MessageSource,即国际化处理,执行如下代码:
protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } }
如果在配置文件中已经配置了messageSource,那么将messageSource提取并记录在this.messageSource中.
- 如果存在父容器,并且messageSource 是HierarchicalMessageSource 的实例,且hms的ParentMessageSource 为null,则调用getInternalParentMessageSource 进行设置.
如果不存在,则实例化DelegatingMessageSource以便作为getMessage的调用.
- 调用getInternalParentMessageSource 进行设置ParentMessageSource
- 向beanFactory注册messageSource
初始化ApplicationEventMulticaster 代码如下:
protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } }
- 如果用户自定义了事件广播器,那么就使用用户自定义的事件广播器
- 如果没有自定义事件广播器,那么就使用默认的SimpleApplicationEventMulticaster,并向beanFactory 进行注册,id 为applicationEventMulticaster.
扩展点,onRefresh,留个子类来初始化其他的bean.执行EmbeddedWebApplicationContext#onRefresh,代码如下:
protected void onRefresh() { super.onRefresh(); try { createEmbeddedServletContainer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start embedded container", ex); } }
调用父类的onRefresh.代码如下:
public static ThemeSource initThemeSource(ApplicationContext context) { if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) { ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class); // Make ThemeSource aware of parent ThemeSource. if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) { HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource; if (hts.getParentThemeSource() == null) { // Only set parent context as parent ThemeSource if no parent ThemeSource // registered already. hts.setParentThemeSource((ThemeSource) context.getParent()); } } if (logger.isDebugEnabled()) { logger.debug("Using ThemeSource [" + themeSource + "]"); } return themeSource; } else { // Use default ThemeSource to be able to accept getTheme calls, either // delegating to parent context's default or to local ResourceBundleThemeSource. HierarchicalThemeSource themeSource = null; if (context.getParent() instanceof ThemeSource) { themeSource = new DelegatingThemeSource(); themeSource.setParentThemeSource((ThemeSource) context.getParent()); } else { themeSource = new ResourceBundleThemeSource(); } if (logger.isDebugEnabled()) { logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME + "': using default [" + themeSource + "]"); } return themeSource; } }
如果context中有themeSource的定义
- 从context 获取,id 为themeSource type为ThemeSource 的 bean
- 如果父容器实现了ThemeSource,并且ThemeSource 是HierarchicalThemeSource 的子类,并且HierarchicalThemeSource 的ParentThemeSource 没有进行设置.则将父容器赋值给HierarchicalThemeSource的ParentThemeSource
如果context中没有themeSource的定义
- 如果父容器为ThemeSource的子类,则实例化DelegatingThemeSource,并将父容器赋值给DelegatingThemeSource的ParentThemeSource
- 否则实例化为DelegatingThemeSource
创建一个嵌入的Servlet容器.这个我们后续分析.
在所有注册的bean中查找listener beans,注册到消息广播器中.代码如下:
protected void registerListeners() { // Register statically specified listeners first. 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! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
将硬编码方式注册的监听器添加到SimpleApplicationEventMulticaster中的defaultRetriever的applicationListeners.如下:
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer, org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer$AutoConfigurationReportListener, org.springframework.boot.context.config.ConfigFileApplicationListener, org.springframework.boot.context.config.AnsiOutputApplicationListener, org.springframework.boot.logging.LoggingApplicationListener, org.springframework.boot.logging.ClasspathLoggingApplicationListener, org.springframework.boot.autoconfigure.BackgroundPreinitializer, org.springframework.boot.context.config.DelegatingApplicationListener, org.springframework.boot.builder.ParentContextCloserApplicationListener, org.springframework.boot.ClearCachesApplicationListener org.springframework.boot.context.FileEncodingApplicationListener, org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener, org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean, org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor
将配置文件注册的监听器添加到SimpleApplicationEventMulticaster中的defaultRetriever的applicationListenerBeans. 如下:
&org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory, org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor, mvcResourceUrlProvider, springApplicationAdminRegistrar]
- 将之前发生的ApplicationEvent进行发送. 对于当前场景来说,没有
初始化剩下的单例(non-lazy-init).代码如下:
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 bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(new StringValueResolver() { @Override public String resolveStringValue(String strVal) { return 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有id 为 conversionService 并且 type 为 ConversionService 的bean,对beanFactory的ConversionService进行赋值
- 如果beanFactory 没有 EmbeddedValueResolver,则添加一个
- 初始化type 为 LoadTimeWeaverAware 的 bean.对于当前场景是没有的.
- 设置TempClassLoader 为null
- 冻结所有的bean的定义,说明注册的bean定义将不被修改或进一步的处理
- 初始化剩下的单实例. 未进行解析
完成刷新过程,执行的是EmbeddedWebApplicationContext#finishRefresh,代码如下:
protected void finishRefresh() { super.finishRefresh(); EmbeddedServletContainer localContainer = startEmbeddedServletContainer(); if (localContainer != null) { // 发布EmbeddedServletContainerInitializedEvent事件 publishEvent( new EmbeddedServletContainerInitializedEvent(this, localContainer)); } }
调用父类的AbstractApplicationContext#finishRefresh.代码如下:
protected void finishRefresh() { // 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); }
初始化LifecycleProcessor.代码如下:
protected void initLifecycleProcessor() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) { this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class); if (logger.isDebugEnabled()) { logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]"); } } else { DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor(); defaultProcessor.setBeanFactory(beanFactory); this.lifecycleProcessor = defaultProcessor; beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor); if (logger.isDebugEnabled()) { logger.debug("Unable to locate LifecycleProcessor with name '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "': using default [" + this.lifecycleProcessor + "]"); } } }
- 如果beanFactory 有 id 为 lifecycleProcessor 且type 为 LifecycleProcessor bean 的话,就将lifecycleProcessor进行赋值
- 否则 实例化 DefaultLifecycleProcessor,并向beanFactory 进行注册
调用lifecycle processor 的onRefresh方法.代码如下:
public void onRefresh() { startBeans(true); this.running = true; }
- 启动Lifecycle类型的bean. 当前环境下 没有.
- 将running设置为true.
发布ContextRefreshedEvent 事件.代码如下:
protected void publishEvent(Object event, ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } // Decorate event as an ApplicationEvent if necessary ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<Object>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType(); } } // Multicast right now if possible - or lazily once the multicaster is initialized if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // Publish event via parent context as well... if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
- 如果applicationEvent 不是ApplicationEvent 子类的话,就包装为PayloadApplicationEvent. 对于当前的 ContextRefreshedEvent,是ApplicationEvent的子类
如果earlyApplicationEvents 不等于null,就添加到earlyApplicationEvents中,否则直接进行发布.对于当前场景来说,会调用SimpleApplicationEventMulticaster#multicastEvent直接发布.这里我们之前有分析过,对ContextRefreshedEvent类型的事件感兴趣的Listener有:
org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor, org.springframework.boot.context.config.DelegatingApplicationListener, org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer$AutoConfigurationReportListener, org.springframework.boot.ClearCachesApplicationListener, org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean, org.springframework.web.servlet.resource.ResourceUrlProvider
ConfigurationPropertiesBindingPostProcessor最终会调用freeLocalValidator,代码如下:
private void freeLocalValidator() { try { Validator validator = this.localValidator; this.localValidator = null; if (validator != null) { ((DisposableBean) validator).destroy(); } } catch (Exception ex) { throw new IllegalStateException(ex); } }
调用Validator的destroy 进行销毁.
DelegatingApplicationListeners没有做处理.
AutoConfigurationReportListener最终会执行AutoConfigurationReportLoggingInitializer#logAutoConfigurationReport,代码如下:private void logAutoConfigurationReport() { logAutoConfigurationReport(!this.applicationContext.isActive()); }
调用
public void logAutoConfigurationReport(boolean isCrashReport) { if (this.report == null) { if (this.applicationContext == null) { this.logger.info("Unable to provide auto-configuration report " + "due to missing ApplicationContext"); return; } this.report = ConditionEvaluationReport .get(this.applicationContext.getBeanFactory()); } if (!this.report.getConditionAndOutcomesBySource().isEmpty()) { if (isCrashReport && this.logger.isInfoEnabled() && !this.logger.isDebugEnabled()) { this.logger.info(String .format("%n%nError starting ApplicationContext. To display the " + "auto-configuration report re-run your application with " + "'debug' enabled.")); } if (this.logger.isDebugEnabled()) { this.logger.debug(new ConditionEvaluationReportMessage(this.report)); } } }
ClearCachesApplicationListener#onApplicationEvent,代码如下:
public void onApplicationEvent(ContextRefreshedEvent event) { ReflectionUtils.clearCache(); clearClassLoaderCaches(Thread.currentThread().getContextClassLoader()); }
清除ReflectionUtils的缓存.代码如下:
public static void clearCache() { declaredMethodsCache.clear(); declaredFieldsCache.clear(); }
递归清除ClassLoader的缓存.代码如下:
private void clearClassLoaderCaches(ClassLoader classLoader) { if (classLoader == null) { return; } try { Method clearCacheMethod = classLoader.getClass() .getDeclaredMethod("clearCache"); clearCacheMethod.invoke(classLoader); } catch (Exception ex) { // Ignore } clearClassLoaderCaches(classLoader.getParent()); }
SharedMetadataReaderFactoryBean#onApplicationEvent ,清空了metadataReaderFactory的缓存,代码如下:
public void onApplicationEvent(ContextRefreshedEvent event) { this.metadataReaderFactory.clearCache(); }
调用
public void clearCache() { this.cache.clear(); }
ResourceUrlProvider#onApplicationEvent,代码如下:
public void onApplicationEvent(ContextRefreshedEvent event) { if (isAutodetect()) { this.handlerMap.clear(); detectResourceHandlers(event.getApplicationContext()); if (this.handlerMap.isEmpty() && logger.isDebugEnabled()) { logger.debug("No resource handling mappings found"); } if (!this.handlerMap.isEmpty()) { this.autodetect = false; } } }
如果autodetect为true的话.
- 清空handlerMap
调用detectResourceHandlers,将SimpleUrlHandlerMapping中handler为ResourceHttpRequestHandler的添加到handlerMap中.对于当前环境, handlerMap为:
/**/favicon.ico=ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@6bbe50c9]], /webjars/**=ResourceHttpRequestHandler [locations=[class path resource [META-INF/resources/webjars/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@3c46dcbe]], /**=ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@68577ba8]]
- 如果handlerMap 不为空,则将autodetect设为false.
- 直接return
- 如果有父容器的话,
- 如果父容器是AbstractApplicationContext 实例化,向父容器发布事件
- 否则直接进行发布
- 向LiveBeansView进行注册.
- 启动嵌入的ServletContainer , 这里我们后续分析
- 如果启动成功的话,发布EmbeddedServletContainerInitializedEvent事件,这里我们后续分析
清除缓存.代码如下:
protected void resetCommonCaches() { ReflectionUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader()); }
- 清除ReflectionUtils的缓存,这个我们已经分析过了
- 清除ResolvableType的缓存
- 清除CachedIntrospectionResults中的缓存
至此我们就分析完了.