入口:

在SpringBoot启动的时候,SpringApplication的run方法中

refreshContext(context);

里面最终调用的是AbstractApplicationContext类的refresh方法来刷新容器

源码:

@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 设置Spring容器的启动时间,撤销关闭状态,开启活跃状态prepareRefresh();// 得到BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 给BeanFactory设置一些属性prepareBeanFactory(beanFactory);try {// 后置处理BeanFactorypostProcessBeanFactory(beanFactory);// 注册并调用BeanFactoryPostProcessor后置处理器// 其中ConfigurationClassPostProcessor这个后置处理器会扫描Bean并且注册到容器中
//这个方法做了很多事,Spring IOC容器初始化中的资源定位、BeanDefinition载入和解析、BeanDefinition注册都是这个方法完成的invokeBeanFactoryPostProcessors(beanFactory);// 注册BeanPostProcessor后置处理器,这里的后置处理器在下方实例化Bean方法中会用到registerBeanPostProcessors(beanFactory);initMessageSource();// 初始化ApplicationEventMulticasterinitApplicationEventMulticaster();//创建tomcat启动了Tomcat的Server、Service、Container、Engine、Realm、Pipeline、Value、MapperListerneronRefresh();// 注册监听器registerListeners();// 实例化非懒加载的BeanfinishBeanFactoryInitialization(beanFactory);// 启动tomcat的ConnectorfinishRefresh();}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();}}}

方法详解

1.prepareRefresh方法

源码

调用AnnotationConfigEmbeddedWebApplicationContext类的prepareRefresh

   @Overrideprotected void prepareRefresh() {this.scanner.clearCache();super.prepareRefresh();}

这里super会调用AbstractApplicationContextPrepareRefresh方法

   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 environmentinitPropertySources();// Validate that all properties marked as required are resolvable// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();}

控制台打印的这句话就在这里

2019-02-22 15:50:01.994  INFO 1560 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6c7a164b: startup date [Fri Feb 22 15:49:59 CST 2019]; root of context hierarchy

做了4件事

1.清除源数据缓存

2.设置Spring容器的启动时间,撤销关闭状态,开启活跃状态。

3.初始化属性源信息,调用的是WebApplicationContextUtils类的initServletPropertySources方法。这里因为servletContext和servletConfig为空,所以什么都没做。

4.验证环境信息里一些必须存在的属性。调用的AbstractPropertyResolver类的validateRequiredProperties方法。这里因为this.requiredProperties里面没有元素,所以什么都没做。

2.obtainFreshBeanFactory方法

源码

   protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}

调用子类refreshBeanFactory方法

   @Overrideprotected 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件事

1.调用子类的refeshBeanFactory(),设置BeanFactory的SerializationId,把SerializationId和弱引用的DefaultListableBeanFacotry注册到beanFactory的serializableFactories属性(一个Map)中,设置refreshed标志为true。

2.获取BeanFactory,这里是org.springframework.beans.factory.support.DefaultListableBeanFactory类,在创建applicationContext的时候就创建了它。

3.如果XmlWebApplicationContext ,AnnotationConfigApplicationContext类容器, 会在这一步加载BeanFactory。

而我们这里debug的是AnnotationConfigEmbeddedWebApplicationContext容器,在容器创建的时候就创建好了BeanFactory。

3.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());}}

做了5件事

1.给BeanFactory设置BeanClassLoader类加载器,设置BeanExpressionResolver表达式解析器,设置PropertyEditorRegistrar资源编辑注册器。

2.给BeanFactory添加BeanPostProcessor。这里是加的ApplicationContextAwareProcessor

在ignoredDependencyInterfaces集合中加入EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、

3.给BeanFactory注册解析依赖。往resolvableDependencies(是Map)注册BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext

4.给BeanFactory添加BeanPostProcessor。这里是加的ApplicationListenerDetector

5.给BeanFactory注册一些单例Bean,如:environment、systemProperties、systemEnvironment

4.postProcessBeanFactory方法

源码

AnnotationConfigEmbeddedWebApplicationContext类

   @Overrideprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 调用父类EmbeddedWebApplicationContext的实现super.postProcessBeanFactory(beanFactory);// 查看basePackages属性,如果设置了会使用ClassPathBeanDefinitionScanner去扫描basePackages包下的bean并注册if (this.basePackages != null && this.basePackages.length > 0) {this.scanner.scan(this.basePackages);}// 查看annotatedClasses属性,如果设置了会使用AnnotatedBeanDefinitionReader去注册这些beanif (this.annotatedClasses != null && this.annotatedClasses.length > 0) {this.reader.register(this.annotatedClasses);}}

父类EmbeddedWebApplicationContext

   @Overrideprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(ServletContextAware.class);}

做了2件事

1.给beanFactory添加BeanPostProcessor后置处理器WebApplicationContextServletContextAwareProcessor

2.给beanFactory添加ignoredDependencyInterfaces忽略依赖接口ServletContextAware

5. invokeBeanFactoryPostProcessors方法

这个方法做了很多事,Spring IOC容器初始化中的资源定位、BeanDefinition载入和解析、BeanDefinition注册都是这个方法完成的

源码

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

委托给PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors方法执行。这个方法写得很恶心,真的,一点都不优雅!

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>();将ApplicationContext中的后置处理器BeanFactoryPostProcessors分类为常规的后置处理器(PropertySourceOrderingPostProcessor)和注册BeanDefinition的后置处理器(ConfigurationWarningsPostProcessor、CachingMetadataReaderFactoryPostProcessor)for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;执行ApplicationContext中注册BeanDefinition的后置处理器(ConfigurationWarningsPostProcessor、CachingMetadataReaderFactoryPostProcessor)的postProcessBeanDefinitionRegistry方法。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)) {把BeanFactory中已经进注册表了的BeanDefinition信息的注册BeanDefinition的后置处理器BeanFactoryPostProcessors实例化。这里即是ConfigurationClassPostProcessor类currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);调用了ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry方法,把扫描到的所有BeanDefinition都注册到容器的注册表(一个Map)中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.调用所有注册BeanDefinition的后置处理器的postProcessBeanFactoryinvokeBeanFactoryPostProcessors(registryProcessors, beanFactory);调用所有常规后置处理器的postProcessBeanFactory方法。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.把BeanFactory中已经进注册表了的BeanDefinition信息的所有BeanFactoryPostProcessors后置处理器实例化,按照priorityOrdered、Ordered、nonOrdered分类。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.调用priorityOrdered分类中所有后置处理器(PropertySourcesPlaceholderConfigurer)的postProcessBeanFactory方法。sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.调用Ordered分类中所有后置处理器的postProcessBeanFactory方法。其实这里,这个分类是空的。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.调用nonOrdered分类中所有后置处理器(ConfigurationBeanFactoryMetaData、ErrorMvcAutoConfiguration.PreserveErrorControllerTargetClassPostProcessor)的postProcessBeanFactory方法。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();}

该方法分为两大部分:

第一部分做了5件事

1.将ApplicationContext中的后置处理器BeanFactoryPostProcessors分类为常规的后置处理器(PropertySourceOrderingPostProcessor)和注册BeanDefinition的后置处理器(ConfigurationWarningsPostProcessor、CachingMetadataReaderFactoryPostProcessor)

2.执行ApplicationContext中注册BeanDefinition的后置处理器(ConfigurationWarningsPostProcessor、CachingMetadataReaderFactoryPostProcessor)的postProcessBeanDefinitionRegistry方法。

3.把BeanFactory中已经进注册表了的BeanDefinition信息的注册BeanDefinition的后置处理器BeanFactoryPostProcessors实例化。这里即是ConfigurationClassPostProcessor类调用了ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry方法把BeanDefinition都注册到容器的注册表(一个Map)中,先注册PriorityOrdered,再注册Ordered,再注册nonOrdered

4.调用所有注册BeanDefinition的后置处理器的postProcessBeanFactory

其中调用了ConfigurationClassPostProcessor的postProcessBeanFactory方法。其他两个注册BeanDefinition后置处理器的该方法是空的。

该方法中调用enhanceConfigurationClasses用来将标记@Configuration的配置类的BeanDefinition的beanClass替换为经过cglib加强过的,这样在实例化此bean的时候,就可以使用替换的代理类来创建对象了。此处跟AOP有关

该在BeanFactory中添加一个后置处理器ImportAwareBeanPostProcessor

5.调用所有常规后置处理器postProcessBeanFactory方法。

即是PropertySourceOrderingPostProcessor的postProcessBeanFactory方法。

这里专门另外写一篇来介绍 ConfigurationClassPostProcessor类postProcessBeanDefinitionRegistry方法是怎么把所有的bean扫到注册到IOC的注册表总的:

【八】Spring Boot 源码分析之启动主流程----ConfigurationClassPostProcessor的processConfigBeanDefinitionRegistry方法

第二部分做了5件事

1.把BeanFactory中已经进注册表了的BeanDefinition信息的所有BeanFactoryPostProcessors后置处理器实例化,按照priorityOrdered、Ordered、nonOrdered分类。

2.调用priorityOrdered分类中所有后置处理器(PropertySourcesPlaceholderConfigurer)的postProcessBeanFactory方法。

3.调用Ordered分类中所有后置处理器的postProcessBeanFactory方法。其实这里,这个分类是空的。

4.调用nonOrdered分类中所有后置处理器(ConfigurationBeanFactoryMetaDataErrorMvcAutoConfiguration.PreserveErrorControllerTargetClassPostProcessor)的postProcessBeanFactory方法。

5.清空beanFactory源数据缓存

6.registerBeanPostProcessors方法

源码

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

委托给PostProcessorRegistrationDelegate的静态方法registerBeanPostProcessors执行。这个方法写得很恶心,真的,一点都不优雅!

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// Register BeanPostProcessorChecker that logs an info message when// a bean is created during BeanPostProcessor instantiation, i.e. when// a bean is not eligible for getting processed by all BeanPostProcessors.int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();List<String> orderedPostProcessorNames = new ArrayList<String>();List<String> nonOrderedPostProcessorNames = new ArrayList<String>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, register the BeanPostProcessors that implement PriorityOrdered.sortPostProcessors(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,跟上一个方法中的BeanFactoryPostProcessor不一样!

做了3件事:

1.把BeanFactory中已经进注册表了的BeanDefinition信息的BeanPostProcessor后置处理器实例化。

2.把BeanPostProcessor按照priorityOrdered、ordered、nonOrdered、internalPostProcessors分类。

priorityOrdered:AutowiredAnnotationBeanPostProcessorRequiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorConfigurationPropertiesBindingPostProcessor

ordered:MethodValidationPostProcessorAnnotationAwareAspectJAutoProxyCreator(这个跟AOP有关)

nonOrdered:EmbeddedServletContainerCustomizerBeanPostProcessorErrorPageRegistrarBeanPostProcessor

internalPostProcessors:AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor

3.把各个分类的BeanFactoryPostProcessor后置处理器注册到BeanFactory

7.initMessageSource方法

初始化上下文中的资源文件,如国际化文件的处理等。这里走的是else。

源码:

protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// Make MessageSource aware of parent MessageSource.if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {// Only set parent context as parent MessageSource if no parent MessageSource// registered already.hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isDebugEnabled()) {logger.debug("Using MessageSource [" + this.messageSource + "]");}}else {// Use empty MessageSource to be able to accept getMessage calls.DelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);if (logger.isDebugEnabled()) {logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +"': using default [" + this.messageSource + "]");}}}

8.initApplicationEventMulticaster方法

初始化ApplicationEventMulticaster。如果ApplicationContext容器中没有定义ApplicationEventMulticaster,则new一个SimpleApplicationEventMulticaster。这里走的是else。

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 + "]");}}}

9.onRefresh方法

源码:调用的EmbeddedWebApplicationContext类的onRefresh方法。

   protected void onRefresh() {super.onRefresh();try {createEmbeddedServletContainer();}catch (Throwable ex) {throw new ApplicationContextException("Unable to start embedded container",ex);}}

重点在createEmbeddedServletContainer方法

private void createEmbeddedServletContainer() {EmbeddedServletContainer localContainer = this.embeddedServletContainer;ServletContext localServletContext = getServletContext();if (localContainer == null && localServletContext == null) {EmbeddedServletContainerFactory containerFactory = getEmbeddedServletContainerFactory();this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(getSelfInitializer());}else if (localServletContext != null) {try {getSelfInitializer().onStartup(localServletContext);}catch (ServletException ex) {throw new ApplicationContextException("Cannot initialize servlet context",ex);}}initPropertySources();}

该方法中会去创建内嵌的Servlet容器,这里既是Tomcat。

跟到里面会发现启动了Tomcat的Server、Service、Container、Engine、Realm、Pipeline、Value、MapperListerner

这里单独写一篇介绍Spring Boot启动的时候走到这个方法后,是怎么去启动内置的Tomcat的

【六】Spring Boot 源码分析之启动内置Tomcat(Tomcat组件、生命周期简介、一次请求)

10.registerListeners方法

源码:

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

做了3件事:

1.把Spring容器内的事件监听器(applicationContext.applicationListener中)注册到事件广播器SimpleApplicationEventMulticaster

2.把BeanFactory中BeanDefition注册表中有的事件监听器(CachingMetadataReaderFactory、ConfigurationPropertiesBindingPostProcessor、mvcResourceUrlProvider、springApplicationAdminRegistrar、这些是bean的名字,并没有实例化)注册到事件广播器SimpleApplicationEventMulticaster

3.广播较早的事件,这里是空的,所以并没有广播什么。

11.finishBeanFactoryInitialization方法

源码:

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() {@Overridepublic 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.// 重点在这句话!这句话做bean的初始化工作beanFactory.preInstantiateSingletons();}

实例化BeanFactory中已经被注册但是未实例化的所有Bean(懒加载的不需要实例化)。即生成环境所需要的Bean

前面几个if在debug的时候没进去,for循环weaverAwareNames为空也没进去,重点介绍beanFactory.preInstantiateSingletions方法

【五】Spring Boot 源码分析之启动主流程----DefaultListableBeanFactory的preInstantiateSingletons方法

12.finishRefresh方法

源码:

调用子类EmbeddedWebApplicationContext类的finishRefresh方法

protected void finishRefresh() {// 调用父类AbstractApplicationContext的finishRefresh 方法super.finishRefresh();// 启动tomcat的ConnectorEmbeddedServletContainer localContainer = startEmbeddedServletContainer();if (localContainer != null) {// 用SimpleApplicationEventMulticaster发布EmbeddedServletContainerInitializedEvent事件publishEvent(new EmbeddedServletContainerInitializedEvent(this, localContainer));}}

做了3件事:

12.1.调用父类AbstractApplicationContextfinishRefresh 方法

   protected void finishRefresh() {// Initialize lifecycle processor for this context.initLifecycleProcessor();// 初始化生命周期处理器DefaultLifecycleProcessor,调用DefaultLifecycleProcessor含有startBeans方法getLifecycleProcessor().onRefresh();// 用SimpleApplicationEventMulticaster发布ContextRefreshedEvent事件publishEvent(new ContextRefreshedEvent(this));LiveBeansView.registerApplicationContext(this);}

做了3件事:

12.1.1.初始化生命周期处理器DefaultLifecycleProcessor,调用DefaultLifecycleProcessor含有startBeans方法

12.1.2.用SimpleApplicationEventMulticaster发布ContextRefreshedEvent事件。

12.1.3.给LiveBeansView注册ApplicationContext

12.1.2 广播出 ContextRefreshedEvent事件后各个监听器执行的逻辑:

12.1.2.1 ConfigurationPropertiesBindingPostProcessor

源码:

public void onApplicationEvent(ContextRefreshedEvent event) {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);}}

12.1.2.2 DelegatingApplicationListener

源码:并没有监听这个事件

public void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationEnvironmentPreparedEvent) {List<ApplicationListener<ApplicationEvent>> delegates = getListeners(((ApplicationEnvironmentPreparedEvent) event).getEnvironment());if (delegates.isEmpty()) {return;}this.multicaster = new SimpleApplicationEventMulticaster();for (ApplicationListener<ApplicationEvent> listener : delegates) {this.multicaster.addApplicationListener(listener);}}if (this.multicaster != null) {this.multicaster.multicastEvent(event);}}

 12.1.2.3 AutoConfigurationReportLoggingInitializer

源码:

   protected void onApplicationEvent(ApplicationEvent event) {ConfigurableApplicationContext initializerApplicationContext = AutoConfigurationReportLoggingInitializer.this.applicationContext;if (event instanceof ContextRefreshedEvent) {if (((ApplicationContextEvent) event).getApplicationContext() == initializerApplicationContext) {logAutoConfigurationReport();}}else if (event instanceof ApplicationFailedEvent) {if (((ApplicationFailedEvent) event).getApplicationContext() == initializerApplicationContext) {logAutoConfigurationReport(true);}}}

调用了logAutoConfigurationReport方法

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

12.1.2.4 ClearCachesApplicationListener

源码:主要是清除缓存。

   public void onApplicationEvent(ContextRefreshedEvent event) {ReflectionUtils.clearCache();clearClassLoaderCaches(Thread.currentThread().getContextClassLoader());}

12.1.2.5 SharedMetadataReaderFactoryContextInitializer

源码:清除缓存

       public void onApplicationEvent(ContextRefreshedEvent event) {this.metadataReaderFactory.clearCache();}

12.1.2.6 ResourceUrlProvider

源码:

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

12.2. 启动tomcat的Connector

【六】Spring Boot 源码分析之启动内置Tomcat(Tomcat组件、生命周期简介、一次请求)

12.3.用SimpleApplicationEventMulticaster发布EmbeddedServletContainerInitializedEvent事件

广播出 EmbeddedServletContainerInitializedEvent事件后各个监听器执行的逻辑:

12.3.1 DelegatingApplicationListener

源码:并没有监听EmbeddedServletContainerInitializedEvent事件

public void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationEnvironmentPreparedEvent) {List<ApplicationListener<ApplicationEvent>> delegates = getListeners(((ApplicationEnvironmentPreparedEvent) event).getEnvironment());if (delegates.isEmpty()) {return;}this.multicaster = new SimpleApplicationEventMulticaster();for (ApplicationListener<ApplicationEvent> listener : delegates) {this.multicaster.addApplicationListener(listener);}}if (this.multicaster != null) {this.multicaster.multicastEvent(event);}}

12.4 ServerPortInfoApplicationContextInitializer

源码:

   protected void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {String propertyName = getPropertyName(event.getApplicationContext());setPortProperty(event.getApplicationContext(), propertyName,event.getEmbeddedServletContainer().getPort());}

【四】Spring源码分析之启动主流程---AbstractApplicationContext的refresh方法相关推荐

  1. Spring源码分析之getBean主流程分析

    当我们通过向Spring容器获取某个bean的时候,总是调用Spring中重载的各种getBean方法.那么,getBean中的流程是什么样的? 通过本文,你将对getBean方法的主流程有一个详细的 ...

  2. Spring源码分析之BeanPostProcessor接口和BeanFactoryPostProcessor接口方法不执行原因分析

    首先下面是我的Bean /** Copyright 2002-2017 the original author or authors.** Licensed under the Apache Lice ...

  3. Spring源码分析(三)

    Spring源码分析 第三章 手写Ioc和Aop 文章目录 Spring源码分析 前言 一.模拟业务场景 (一) 功能介绍 (二) 关键功能代码 (三) 问题分析 二.使用ioc和aop重构 (一) ...

  4. spring源码分析第四天------springmvc核心原理及源码分析

    spring源码分析第四天------springmvc核心原理及源码分析 1.基础知识普及 2. SpringMVC请求流程 3.SpringMVC代码流程 4.springMVC源码分析 4.1 ...

  5. Spring 源码分析(四) ——MVC(二)概述

    随时随地技术实战干货,获取项目源码.学习资料,请关注源代码社区公众号(ydmsq666) from:Spring 源码分析(四) --MVC(二)概述 - 水门-kay的个人页面 - OSCHINA ...

  6. Spring源码分析之Bean的创建过程详解

    前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...

  7. Spring 源码分析衍生篇十三 :事务扩展机制 TransactionSynchronization

    文章目录 一.前言 二.TransactionSynchronization 1. TransactionSynchronization 1.1 TransactionSynchronization ...

  8. spring源码分析之spring-core总结篇

    1.spring-core概览 spring-core是spring框架的基石,它为spring框架提供了基础的支持. spring-core从源码上看,分为6个package,分别是asm,cgli ...

  9. spring源码分析之BeanDefinition相关

    目录 前言: BeanDefinition的家族系列 1.BeanDefintion的UML类图 2.BeanDefintion家族类详解 2.1.通用接口 2.2.BeanDefintion接口 2 ...

最新文章

  1. 技术图文:02 创建型设计模式(下)
  2. 三天打工生活终于结束了
  3. Sharepoin学习笔记—架构系列--05 Sharepoint的四种执行模型 2
  4. HTML CSS JS(一)
  5. matlab进行sg滤波,Matlab,SG滤波器
  6. python使用python-docx导出word
  7. 《An Introduction to Ray Tracing》—— 3.3 Ray-Surface Intersections
  8. python教学笔记_python学习笔记(一)
  9. 恭祝大家2019新年吉祥顺利!
  10. 请教大家, 关于 $0118 号消息
  11. VC6.0+XT库+OPENCV1.0调试笔记
  12. C语言练习题(递归)
  13. BitComet种子torrent内容解析
  14. 移动固态硬盘没有连接到计算机,移动固态硬盘装个Win to go,这才是移动固态硬盘正确的打开方式...
  15. OC, OD门和线与逻辑
  16. 【设计】电压电流偏置
  17. 在Chrome浏览器中点击链接,打开IE浏览器,跳转到指定页面并传递参数
  18. a轮b轮c轮天使轮区别是什么?
  19. 单片机编程系列之分层设计2(怎样合理拆分子系统)
  20. 想用 AI 在《MineCraft》挖矿躺赢?660 支队伍全部失败

热门文章

  1. 谷歌获批GAN专利,一整套对抗训练网络被收入囊中
  2. 教你怎样任意转换视频格式
  3. 2020 蓝桥杯大学 B 组省赛模拟赛 七巧板
  4. 加勒比海盗船——最优装载问题-贪心算法
  5. 基于HTML+CSS+JavaScript仿淘宝购物商城设计毕业论文源码
  6. 你知道什么是 a站、b站、c站、d站、e站、f站、g站、h站、i站、j站、k站、l站、m站、n站…z 站吗 ?...
  7. Conti勒索软件源代码分析
  8. 最好的天线基础知识!超实用 随时查询
  9. 用计算机画画教学设计,电脑版你画画教学设计
  10. 颠覆性AI程序:人工智能如何推动天文学创新?