『SpringBoot 源码分析』run() 方法执行流程:(2)刷新应用上下文-准备阶段
基于 2.2.9.RELEASE 问题:当方法进行了注释标记之后,springboot 又是怎么注入到容器中并创建类呢?
首先创建测试主程序
package com. lagou ; @SpringBootApplication
public class SpringBootMytestApplication { public static void main ( String [ ] args) { SpringApplication . run ( SpringBootMytestApplication . class , args) ; }
}
创建测试 Controller
package com. lagou. controller ; @RestController
public class TestController { @RequestMapping ( "/test" ) public String test ( ) { System . out. println ( "源码环境构建成功..." ) ; return "源码环境构建成功" ; }
}
准备阶段
当准备完成应用上下文环境,以及应用上下文以后,需要为应用上下文做个准备阶段,简单来说其实就是要配置应用上下文,把需要的类装配上
public class SpringApplication { . . . public ConfigurableApplicationContext run ( String . . . args) { . . . try { ApplicationArguments applicationArguments = new DefaultApplicationArguments ( args) ; ConfigurableEnvironment environment = prepareEnvironment ( listeners, applicationArguments) ; configureIgnoreBeanInfo ( environment) ; Banner printedBanner = printBanner ( environment) ; context = createApplicationContext ( ) ; exceptionReporters = getSpringFactoriesInstances ( SpringBootExceptionReporter . class , new Class [ ] { ConfigurableApplicationContext . class } , context) ; prepareContext ( context, environment, listeners, applicationArguments, printedBanner) ; . . . } catch ( Throwable ex) { . . . } . . . }
}
在对应用上下文进行处理时,主要执行了下面几步的装配
把上下文环境设置到应用上下文中 执行容器后置处理 把应用上下文交给 SpringApplication 初始化收集的 org.springframework.context.ApplicationContextInitializer 所有实现类进行初始化工作 利用 org.springframework.boot.context.event.EventPublishingRunListener 向 org.springframework.context.ApplicationListener 发布容器准备好事件
public class SpringApplication { . . . private void prepareContext ( ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context. setEnvironment ( environment) ; postProcessApplicationContext ( context) ; applyInitializers ( context) ; listeners. contextPrepared ( context) ; . . . }
}
执行容器后置处理:其实只是往 BeanFactory 添加了基础的转换器
public class SpringApplication { private BeanNameGenerator beanNameGenerator; private ResourceLoader resourceLoader; private boolean addConversionService = true ; . . . protected void postProcessApplicationContext ( ConfigurableApplicationContext context) { if ( this . beanNameGenerator != null ) { context. getBeanFactory ( ) . registerSingleton ( AnnotationConfigUtils . CONFIGURATION_BEAN_NAME_GENERATOR , this . beanNameGenerator) ; } if ( this . resourceLoader != null ) { if ( context instanceof GenericApplicationContext ) { ( ( GenericApplicationContext ) context) . setResourceLoader ( this . resourceLoader) ; } if ( context instanceof DefaultResourceLoader ) { ( ( DefaultResourceLoader ) context) . setClassLoader ( this . resourceLoader. getClassLoader ( ) ) ; } } if ( this . addConversionService) { context. getBeanFactory ( ) . setConversionService ( ApplicationConversionService . getSharedInstance ( ) ) ; } }
}
执行一些初始化器:就是遍历 org.springframework.context.ApplicationContextInitializer 执行 initialize() 方法
public class SpringApplication { . . . protected void applyInitializers ( ConfigurableApplicationContext context) { for ( ApplicationContextInitializer initializer : getInitializers ( ) ) { Class < ? > requiredType = GenericTypeResolver . resolveTypeArgument ( initializer. getClass ( ) , ApplicationContextInitializer . class ) ; Assert . isInstanceOf ( requiredType, context, "Unable to call initializer." ) ; initializer. initialize ( context) ; } }
}
向各个监听器发送容器已经准备好的事件:就是 org.springframework.boot.context.event.EventPublishingRunListener 向 org.springframework.context.ApplicationListener 发布容器准备好事件
public class SpringApplication { . . . void contextPrepared ( ConfigurableApplicationContext context) { for ( SpringApplicationRunListener listener : this . listeners) { listener. contextPrepared ( context) ; } }
}
发布完监听之后,从上下文中获取 IOC 工厂,并设置允许 bean 定义被覆盖参数
public class SpringApplication { . . . private void prepareContext ( ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context. setEnvironment ( environment) ; postProcessApplicationContext ( context) ; applyInitializers ( context) ; listeners. contextPrepared ( context) ; if ( this . logStartupInfo) { logStartupInfo ( context. getParent ( ) == null ) ; logStartupProfileInfo ( context) ; } ConfigurableListableBeanFactory beanFactory = context. getBeanFactory ( ) ; beanFactory. registerSingleton ( "springApplicationArguments" , applicationArguments) ; if ( printedBanner != null ) { beanFactory. registerSingleton ( "springBootBanner" , printedBanner) ; } if ( beanFactory instanceof DefaultListableBeanFactory ) { ( ( DefaultListableBeanFactory ) beanFactory) . setAllowBeanDefinitionOverriding ( this . allowBeanDefinitionOverriding) ; } . . . }
}
然后加载启动类,并将启动类注入到容器当中,然后发布容器已加载事件
public class SpringApplication { . . . private void prepareContext ( ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context. setEnvironment ( environment) ; postProcessApplicationContext ( context) ; applyInitializers ( context) ; listeners. contextPrepared ( context) ; if ( this . logStartupInfo) { logStartupInfo ( context. getParent ( ) == null ) ; logStartupProfileInfo ( context) ; } ConfigurableListableBeanFactory beanFactory = context. getBeanFactory ( ) ; beanFactory. registerSingleton ( "springApplicationArguments" , applicationArguments) ; if ( printedBanner != null ) { beanFactory. registerSingleton ( "springBootBanner" , printedBanner) ; } if ( beanFactory instanceof DefaultListableBeanFactory ) { ( ( DefaultListableBeanFactory ) beanFactory) . setAllowBeanDefinitionOverriding ( this . allowBeanDefinitionOverriding) ; } if ( this . lazyInitialization) { context. addBeanFactoryPostProcessor ( new LazyInitializationBeanFactoryPostProcessor ( ) ) ; } Set < Object > sources = getAllSources ( ) ; Assert . notEmpty ( sources, "Sources must not be empty" ) ; load ( context, sources. toArray ( new Object [ 0 ] ) ) ; listeners. contextLoaded ( context) ; }
}
其中将启动类注入到容器当中是比较关键的一步,首先先把 ApplicationContext 转换成 BeanDefinitionRegistry ,然后创建 bean 定义加载器
public class SpringApplication { . . . protected void load ( ApplicationContext context, Object [ ] sources) { if ( logger. isDebugEnabled ( ) ) { logger. debug ( "Loading source " + StringUtils . arrayToCommaDelimitedString ( sources) ) ; } BeanDefinitionLoader loader = createBeanDefinitionLoader ( getBeanDefinitionRegistry ( context) , sources) ; . . . } private BeanDefinitionRegistry getBeanDefinitionRegistry ( ApplicationContext context) { if ( context instanceof BeanDefinitionRegistry ) { return ( BeanDefinitionRegistry ) context; } if ( context instanceof AbstractApplicationContext ) { return ( BeanDefinitionRegistry ) ( ( AbstractApplicationContext ) context) . getBeanFactory ( ) ; } throw new IllegalStateException ( "Could not locate BeanDefinitionRegistry" ) ; }
}
创建 BeanDefinitionLoader 主要是把 BeanDefinitionRegistry 以及主类的 sources 进行赋值初始化
public class SpringApplication { private final Object [ ] sources; private final AnnotatedBeanDefinitionReader annotatedReader; private final XmlBeanDefinitionReader xmlReader; private BeanDefinitionReader groovyReader; private final ClassPathBeanDefinitionScanner scanner; private ResourceLoader resourceLoader; . . . protected BeanDefinitionLoader createBeanDefinitionLoader ( BeanDefinitionRegistry registry, Object [ ] sources) { return new BeanDefinitionLoader ( registry, sources) ; } BeanDefinitionLoader ( BeanDefinitionRegistry registry, Object . . . sources) { Assert . notNull ( registry, "Registry must not be null" ) ; Assert . notEmpty ( sources, "Sources must not be empty" ) ; this . sources = sources; this . annotatedReader = new AnnotatedBeanDefinitionReader ( registry) ; this . xmlReader = new XmlBeanDefinitionReader ( registry) ; if ( isGroovyPresent ( ) ) { this . groovyReader = new GroovyBeanDefinitionReader ( registry) ; } this . scanner = new ClassPathBeanDefinitionScanner ( registry) ; this . scanner. addExcludeFilter ( new ClassExcludeFilter ( sources) ) ; }
}
创建 BeanDefinitionLoader 成功后,就可以开始执行 load() ,这里主要是先把主类注册到 IOC 容器中去
public class SpringApplication { private BeanNameGenerator beanNameGenerator; . . . protected void load ( ApplicationContext context, Object [ ] sources) { if ( logger. isDebugEnabled ( ) ) { logger. debug ( "Loading source " + StringUtils . arrayToCommaDelimitedString ( sources) ) ; } BeanDefinitionLoader loader = createBeanDefinitionLoader ( getBeanDefinitionRegistry ( context) , sources) ; if ( this . beanNameGenerator != null ) { loader. setBeanNameGenerator ( this . beanNameGenerator) ; } if ( this . resourceLoader != null ) { loader. setResourceLoader ( this . resourceLoader) ; } if ( this . environment != null ) { loader. setEnvironment ( this . environment) ; } loader. load ( ) ; }
}
其中 load() 通过 AnnotatedBeanDefinitionReader 将主类 source 注册进 beanDefinitionMap 中
class BeanDefinitionLoader { private final AnnotatedBeanDefinitionReader annotatedReader; . . . int load ( ) { int count = 0 ; for ( Object source : this . sources) { count += load ( source) ; } return count; } private int load ( Object source) { Assert . notNull ( source, "Source must not be null" ) ; if ( source instanceof Class < ? > ) { return load ( ( Class < ? > ) source) ; } . . . } private int load ( Class < ? > source) { if ( isGroovyPresent ( ) && GroovyBeanDefinitionSource . class . isAssignableFrom ( source) ) { GroovyBeanDefinitionSource loader = BeanUtils . instantiateClass ( source, GroovyBeanDefinitionSource . class ) ; load ( loader) ; } if ( isComponent ( source) ) { this . annotatedReader. register ( source) ; return 1 ; } return 0 ; }
}
调用 register() 方法时,真正会传到 doRegisterBean() 进行执行。首先会把主类转换成 AnnotatedGenericBeanDefinition ,然后获取主类的名称,把名称和 AnnotatedGenericBeanDefinition 封装成 BeanDefinitionHolder 后,注册到上下文中
public class AnnotatedBeanDefinitionReader { . . . public void register ( Class < ? > . . . componentClasses) { for ( Class < ? > componentClass : componentClasses) { registerBean ( componentClass) ; } } public void registerBean ( Class < ? > beanClass) { doRegisterBean ( beanClass, null , null , null , null ) ; } private < T > void doRegisterBean ( Class < T > beanClass, @Nullable String name, @Nullable Class < ? extends Annotation > [ ] qualifiers, @Nullable Supplier < T > supplier, @Nullable BeanDefinitionCustomizer [ ] customizers) { AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition ( beanClass) ; if ( this . conditionEvaluator. shouldSkip ( abd. getMetadata ( ) ) ) { return ; } abd. setInstanceSupplier ( supplier) ; ScopeMetadata scopeMetadata = this . scopeMetadataResolver. resolveScopeMetadata ( abd) ; abd. setScope ( scopeMetadata. getScopeName ( ) ) ; String beanName = ( name != null ? name : this . beanNameGenerator. generateBeanName ( abd, this . registry) ) ; AnnotationConfigUtils . processCommonDefinitionAnnotations ( abd) ; if ( qualifiers != null ) { for ( Class < ? extends Annotation > qualifier : qualifiers) { if ( Primary . class == qualifier) { abd. setPrimary ( true ) ; } else if ( Lazy . class == qualifier) { abd. setLazyInit ( true ) ; } else { abd. addQualifier ( new AutowireCandidateQualifier ( qualifier) ) ; } } } if ( customizers != null ) { for ( BeanDefinitionCustomizer customizer : customizers) { customizer. customize ( abd) ; } } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder ( abd, beanName) ; definitionHolder = AnnotationConfigUtils . applyScopedProxyMode ( scopeMetadata, definitionHolder, this . registry) ; BeanDefinitionReaderUtils . registerBeanDefinition ( definitionHolder, this . registry) ; }
}
注册到容器中,简单而言就是调用 BeanDefinitionRegistry 把 BeanDefinitionHolder 的 name 和 AnnotatedGenericBeanDefinition 装配进去
public abstract class BeanDefinitionReaderUtils { . . . public static void registerBeanDefinition ( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { String beanName = definitionHolder. getBeanName ( ) ; registry. registerBeanDefinition ( beanName, definitionHolder. getBeanDefinition ( ) ) ; String [ ] aliases = definitionHolder. getAliases ( ) ; if ( aliases != null ) { String [ ] var4 = aliases; int var5 = aliases. length; for ( int var6 = 0 ; var6 < var5; ++ var6) { String alias = var4[ var6] ; registry. registerAlias ( beanName, alias) ; } } }
}
最后会把 name 和 AnnotatedGenericBeanDefinition 存入到 beanDefinitionMap 中
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory , BeanDefinitionRegistry , Serializable { . . . public void registerBeanDefinition ( String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert . hasText ( beanName, "Bean name must not be empty" ) ; Assert . notNull ( beanDefinition, "BeanDefinition must not be null" ) ; if ( beanDefinition instanceof AbstractBeanDefinition ) { try { ( ( AbstractBeanDefinition ) beanDefinition) . validate ( ) ; } catch ( BeanDefinitionValidationException var8) { throw new BeanDefinitionStoreException ( beanDefinition. getResourceDescription ( ) , beanName, "Validation of bean definition failed" , var8) ; } } BeanDefinition existingDefinition = ( BeanDefinition ) this . beanDefinitionMap. get ( beanName) ; if ( existingDefinition != null ) { if ( ! this . isAllowBeanDefinitionOverriding ( ) ) { throw new BeanDefinitionOverrideException ( beanName, beanDefinition, existingDefinition) ; } if ( existingDefinition. getRole ( ) < beanDefinition. getRole ( ) ) { if ( this . logger. isInfoEnabled ( ) ) { this . logger. info ( "Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]" ) ; } } else if ( ! beanDefinition. equals ( existingDefinition) ) { if ( this . logger. isDebugEnabled ( ) ) { this . logger. debug ( "Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]" ) ; } } else if ( this . logger. isTraceEnabled ( ) ) { this . logger. trace ( "Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]" ) ; } this . beanDefinitionMap. put ( beanName, beanDefinition) ; } else { if ( this . hasBeanCreationStarted ( ) ) { synchronized ( this . beanDefinitionMap) { this . beanDefinitionMap. put ( beanName, beanDefinition) ; List < String > updatedDefinitions = new ArrayList ( this . beanDefinitionNames. size ( ) + 1 ) ; updatedDefinitions. addAll ( this . beanDefinitionNames) ; updatedDefinitions. add ( beanName) ; this . beanDefinitionNames = updatedDefinitions; this . removeManualSingletonName ( beanName) ; } } else { this . beanDefinitionMap. put ( beanName, beanDefinition) ; this . beanDefinitionNames. add ( beanName) ; this . removeManualSingletonName ( beanName) ; } this . frozenBeanDefinitionNames = null ; } if ( existingDefinition == null && ! this . containsSingleton ( beanName) ) { if ( this . isConfigurationFrozen ( ) ) { this . clearByTypeCache ( ) ; } } else { this . resetBeanDefinition ( beanName) ; } }
}
总结