Spring Boot启动过程
1. 创建SpringApplication实例
构造函数调用initialize
会通过SpringFactoriesLoader.loadFactoryNames(type, classLoader),扫描当前Class所在的工程内所有的 ApplicationContextInitializer和ApplicationListener
加载的ApplicationListener:
org.springframework.boot.ClearCachesApplicationListener@2f4948e4
org.springframework.boot.builder.ParentContextCloserApplicationListener@1f2586d6
org.springframework.boot.context.FileEncodingApplicationListener@10683d9d
org.springframework.boot.context.config.AnsiOutputApplicationListener@3fc2959f
org.springframework.boot.context.config.ConfigFileApplicationListener@5aa9e4eb
org.springframework.boot.context.config.DelegatingApplicationListener@6989da5e
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener@385c9627
org.springframework.boot.logging.ClasspathLoggingApplicationListener@139982de
org.springframework.boot.logging.LoggingApplicationListener@682b2fa
org.springframework.boot.autoconfigure.BackgroundPreinitializer@217ed35e
org.springframework.boot.devtools.restart.RestartApplicationListener@7dcf94f8
同时判断main class和是否是webEnvironment
2.进入SpringApplication.run方法
run方法主要步骤:
1):活动SpringApplicationRunListerns,
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
这里得到一个org.springframework.boot.context.event.EventPublishingRunListener
2)启动listeners
EventPublishingRunListener会广播Application start event, 其中RestartApplicationListener对spring application进行重启
Restarter.instance是一个静态变量,如果已经重启,就不再重启
3)创建并准备ConfigurableEnvironment environment
4)创建ConfigurableApplicationContext context
首先通过Class.forName是否能加载,来检测是否是web环境,根据结果创建不同的conext,如果是web,则创建AnnotationConfigEmbeddedWebApplicationContext
在构建AnnotationConfigEmbeddedWebApplicationContext时,会初始化BeanDefinitionReader和
它会把一些PostProcessor 的beanDefintion注册进context,其中重要的是ConfigurationClassPostProcessor,注册名字为:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
ConfigurationClassPostProcessor implments BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
此post processor会loadBeanDinfinitions 并注册到Context
AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor extends BeanPostProcssor
它是BeanPostProcessor,会把Autowired的自动进行填充。
public AnnotationConfigEmbeddedWebApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
AnnotationConfigUtils::
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
5) 对context进行准备
主要包括:
setEnviroment,
applyInitializers:
1 ConfigurationWarningsApplicationContextInitializer
context.addBeanFactoryPostProcessor(
new ConfigurationWarningsPostProcessor(getChecks()));
2 SharedMetadataReaderFactoryContextInitializer:: addBeanFactoryPostProcessor(CachingMetadataReaderFactoryPostProcessor)
3.AutoConfigurationReportLoggingInitializer
public void initialize(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
applicationContext.addApplicationListener(new AutoConfigurationReportListener());
if (applicationContext instanceof GenericApplicationContext) {
// Get the report early in case the context fails to load
this.report = ConditionEvaluationReport
.get(this.applicationContext.getBeanFactory());
}
}
4.RestartScopeInitializer
applicationContext.getBeanFactory().registerScope("restart", new RestartScope());
loadContext:
6) refreshContext, 调用AbsractApplicationContext的模版方法:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}
这里会进入super.refresh
AbstractApplicationContext.refresh
1. prepareRefresh
2.获得 beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
得到DefaultListableBeanFactory
3.对BeanFactory进行准备
prepareBeanFactory(beanFactory);
主要做以下事情:
注册ApplicationContextAwareProcessor,它主要处理各种Aware接口
注册ApplicationListenerDetector
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());
}
}
4.postProcessBeanFactory,主要给机会在标准初始化之后对beanFactory进行修改
Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
这里主要注册了一个WebApplicationContextServletContextAwareProcessor
如果有basePackages,则进行扫描注册basePackage所包含的bean definition
AnnotationConfigEmbeddedWebApplicationContext::
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);
}
}
super: EmbeddedWebApplicationContext
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(
new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
5. invokeBeanFactoryPostProcessors
调用父类AbstractApplicationContext的方法invokeBeanFactoryPostProcessors. 主要有三个BeanFactoryPostProcssor
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(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 的主要逻辑
1. 处理传进去的 beanFactoryPostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
2. 从已经注册的BeanDefinition中找到所有BeanDefinitionRegistryPostProcessor(它是BeanFactoryPostProcessor的子类),这里会找到ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
之后分三次对这些processor进行处理,先处理PriorityOrdered,之后处理Ordered,最后处理普通的。处理之前会对其processor进行Bean化
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registryPostProcessors.addAll(priorityOrderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
处理ConfigurationClassPostProcessor时,会加载Application类所在的工程的BeanDefinition,会加载工程内jar的bean definition(通过DeferedImportSelector)
(后面详细分析ConfigurationClassPostProcessor处理主要逻辑)
3. 处理BeanFactoryPostProcessor, ConfigurationClassPostProcessor也是BeanFactory postProcessor
这里会对Configuration class进行cglib enhace
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
nvokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
/**
* Prepare the Configuration classes for servicing bean requests at runtime
* by replacing them with CGLIB-enhanced subclasses.
*/
@Override
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);
}
//对configuration class生成cglib 代理,更新 beanDefinitionMap
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
ConfigurationClassPostProcessor的处理流程
1)从注册的bean中得到Configuration class, 这里只有Application这个是Configuration class
创建ConfigurationClassParser
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader,
BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry) {
this.metadataReaderFactory = metadataReaderFactory;
this.problemReporter = problemReporter;
this.environment = environment;
this.resourceLoader = resourceLoader;
this.registry = registry;
this.componentScanParser = new ComponentScanAnnotationParser(
environment, resourceLoader, componentScanBeanNameGenerator, registry);
this.conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);
}
2)ConfigurationClassParser .processConfigurationClass,
SourceClass sourceClass = asSourceClass(configClass);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
doProcessConfigurationClass 主要逻辑:
1 // Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass);
2. // Process any @PropertySource annotations
processPropertySource(propertySource);
3. // Process any @ComponentScan annotations
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
扫描base package获得所有的beanDefinition, 之后检查这些BeanDefinition是否有Configuration class,如果是Configuration class则递归处理,
这里@Component, @CompentScan, @Import被认为是lite Configuration
// The config class is annotated with @ComponentScan -> perform the scan immediately
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
if (ConfigurationClassUtils.checkConfigurationClassCandidate(
holder.getBeanDefinition(), this.metadataReaderFactory)) {
parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
}
}
4. // Process any @Import annotations
5. // Process any @ImportResource annotations
6. // Process individual @Bean methods
7. // Process superclass, if any
8. // No superclass -> processing is complete
其中每个过程都是一个递归调用
3)处理importSelector, 这里的importSelector是EnableAutoConfiuration的Annotation里@Import(EnableAutoConfigurationImportSelector.class)
META-INF/spring-autoconfigure-metadata.properties"
metaData里会定义onCondtionClass等限制
META-INF/spring.factories
扫描工程所在path里这两个pattern的文件,得到
org.springframework.boot.autoconfigure.EnableAutoConfiguration 的类
String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());
processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
configurations = sort(configurations, autoConfigurationMetadata);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
//应用metaData里的OnConditionClass等,filter掉没有符合条件的Configuration 类
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return configurations.toArray(new String[configurations.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
6. registerBeanPostProcessors
如果BeanPostProcessor没有被实例化,则通过getBean进行实例化
7. initMessageSource();, initApplicationEventMulticaster();
8. onRefresh
createEmbeddedServletContainer, 创建出 EmbeddedServletContainerFactory , 如Embeded Tomact
9.registerListeners
10 finishBeanFactoryInitialization(beanFactory);
对bean进行实例化
beanFactory.preInstantiateSingletons();
总结:
对于一个SpringBoot Application应用, 首先会创建SpringApplicaiton这个实例,构造函数会生成一些Initializer和Listener。之后进入run方法。run方法主要会进行Envirmoment创建,准备。 AnnotationConfigEmbeddedWebApplicationContext的创建,初始化。context创建和初始化过程中会注册关键的一些BeanFactoryPostProcessor, BeanPostProcessors.
当环境和context都准备好后,进入refresh方法。refresh方法主要是过程是:准备BeanFactory (注册一下BeanPostProcessor,如ApplicationContextAwareProcessor)。之后调用BeanFactoryPostProcessor,这里一个关键ConfigurationClassPostProcessor会把工程下的Bean, 和工程下的EnableAutoConfiguration的Bean definition进行加载。之后会初始化BeanPostProcessor,最后进行实例化Bean。