【四】Spring源码分析之启动主流程---AbstractApplicationContext的refresh方法
入口:
在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会调用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 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()));}}
委托给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>();将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分类中所有后置处理器(ConfigurationBeanFactoryMetaData、ErrorMvcAutoConfiguration.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:AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、ConfigurationPropertiesBindingPostProcessor
ordered:MethodValidationPostProcessor、AnnotationAwareAspectJAutoProxyCreator(这个跟AOP有关)
nonOrdered:EmbeddedServletContainerCustomizerBeanPostProcessor、ErrorPageRegistrarBeanPostProcessor
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.调用父类AbstractApplicationContext的finishRefresh 方法
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方法相关推荐
- Spring源码分析之getBean主流程分析
当我们通过向Spring容器获取某个bean的时候,总是调用Spring中重载的各种getBean方法.那么,getBean中的流程是什么样的? 通过本文,你将对getBean方法的主流程有一个详细的 ...
- Spring源码分析之BeanPostProcessor接口和BeanFactoryPostProcessor接口方法不执行原因分析
首先下面是我的Bean /** Copyright 2002-2017 the original author or authors.** Licensed under the Apache Lice ...
- Spring源码分析(三)
Spring源码分析 第三章 手写Ioc和Aop 文章目录 Spring源码分析 前言 一.模拟业务场景 (一) 功能介绍 (二) 关键功能代码 (三) 问题分析 二.使用ioc和aop重构 (一) ...
- spring源码分析第四天------springmvc核心原理及源码分析
spring源码分析第四天------springmvc核心原理及源码分析 1.基础知识普及 2. SpringMVC请求流程 3.SpringMVC代码流程 4.springMVC源码分析 4.1 ...
- Spring 源码分析(四) ——MVC(二)概述
随时随地技术实战干货,获取项目源码.学习资料,请关注源代码社区公众号(ydmsq666) from:Spring 源码分析(四) --MVC(二)概述 - 水门-kay的个人页面 - OSCHINA ...
- Spring源码分析之Bean的创建过程详解
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...
- Spring 源码分析衍生篇十三 :事务扩展机制 TransactionSynchronization
文章目录 一.前言 二.TransactionSynchronization 1. TransactionSynchronization 1.1 TransactionSynchronization ...
- spring源码分析之spring-core总结篇
1.spring-core概览 spring-core是spring框架的基石,它为spring框架提供了基础的支持. spring-core从源码上看,分为6个package,分别是asm,cgli ...
- spring源码分析之BeanDefinition相关
目录 前言: BeanDefinition的家族系列 1.BeanDefintion的UML类图 2.BeanDefintion家族类详解 2.1.通用接口 2.2.BeanDefintion接口 2 ...
最新文章
- 技术图文:02 创建型设计模式(下)
- 三天打工生活终于结束了
- Sharepoin学习笔记—架构系列--05 Sharepoint的四种执行模型 2
- HTML CSS JS(一)
- matlab进行sg滤波,Matlab,SG滤波器
- python使用python-docx导出word
- 《An Introduction to Ray Tracing》—— 3.3 Ray-Surface Intersections
- python教学笔记_python学习笔记(一)
- 恭祝大家2019新年吉祥顺利!
- 请教大家, 关于 $0118 号消息
- VC6.0+XT库+OPENCV1.0调试笔记
- C语言练习题(递归)
- BitComet种子torrent内容解析
- 移动固态硬盘没有连接到计算机,移动固态硬盘装个Win to go,这才是移动固态硬盘正确的打开方式...
- OC, OD门和线与逻辑
- 【设计】电压电流偏置
- 在Chrome浏览器中点击链接,打开IE浏览器,跳转到指定页面并传递参数
- a轮b轮c轮天使轮区别是什么?
- 单片机编程系列之分层设计2(怎样合理拆分子系统)
- 想用 AI 在《MineCraft》挖矿躺赢?660 支队伍全部失败