前面说完了context = this.createApplicationContext()过程,接下来我们说下this.prepareContext,但其实在这一步之前,还有一步spring boot的异常上报处理,还是先给个总源码,要讲的俩步标号5,6:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
5、 exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{
ConfigurableApplicationContext.class}, context);
6、this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
先说异常处理,在spring .factoreis查看该定义如下
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);进入方法查看:
//这里从META-INF/spring.factories中获取并初始化SpringBootExceptionReporter子类列表
//获取到一个FailureAnalyzers实例
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = this.getClassLoader();
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
FailureAnalyzers类源码
//异常失败原因分析器
final class FailureAnalyzers implements SpringBootExceptionReporter {
//失败分析器
private final List<FailureAnalyzer> analyzers;
//构造函数
FailureAnalyzers(ConfigurableApplicationContext context, ClassLoader classLoader) {
Assert.notNull(context, "Context must not be null");
this.classLoader = (classLoader != null) ? classLoader : context.getClassLoader();
//加载失败分析器列表
this.analyzers = loadFailureAnalyzers(this.classLoader);
//准备分析异常原因
prepareFailureAnalyzers(this.analyzers, context);
}
//加载异常分析器
private List<FailureAnalyzer> loadFailureAnalyzers(ClassLoader classLoader) {
//通过META-INF/spring.factories中,获取到FailureAnalyzer的子类列表如下
//BeanCurrentlyInCreationFailureAnalyzer,
//BeanDefinitionOverrideFailureAnalyzer,
//BeanNotOfRequiredTypeFailureAnalyzer,
//BindFailureAnalyzer,
//BindValidationFailureAnalyzer,
//UnboundConfigurationPropertyFailureAnalyzer,
//ConnectorStartFailureAnalyzer,
//NoSuchMethodFailureAnalyzer,
//NoUniqueBeanDefinitionFailureAnalyzer,
//PortInUseFailureAnalyzer,
//ValidationExceptionFailureAnalyzer,
//InvalidConfigurationPropertyNameFailureAnalyzer,
//InvalidConfigurationPropertyValueFailureAnalyzer,
//NoSuchBeanDefinitionFailureAnalyzer,
//DataSourceBeanCreationFailureAnalyzer,
//ikariDriverConfigurationFailureAnalyzer,
//NonUniqueSessionRepositoryFailureAnalyzer
List<String> analyzerNames = SpringFactoriesLoader
.loadFactoryNames(FailureAnalyzer.class, classLoader);
List<FailureAnalyzer> analyzers = new ArrayList<>();
for (String analyzerName : analyzerNames) {
try {
Constructor<?> constructor = ClassUtils.forName(analyzerName, classLoader)
.getDeclaredConstructor();
ReflectionUtils.makeAccessible(constructor);
analyzers.add((FailureAnalyzer) constructor.newInstance());
}
catch (Throwable ex) {
logger.trace("Failed to load " + analyzerName, ex);
}
}
AnnotationAwareOrderComparator.sort(analyzers);
return analyzers;
}
}
说完异常分析,进入主题:
6、this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
直接进入方法:
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
//设置context(上下文)环境
//统一ApplicationContext和Application,使用Application的environment
context.setEnvironment(environment);
//ApplicationContext的后置处理
postProcessApplicationContext(context);
//执行Initializers
applyInitializers(context);
//发布contextPrepared事件
listeners.contextPrepared(context);
if (this.logStartupInfo) {
//配置了info日志
//打印启动和profile日志
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
//获取到DefaultListableBeanFactory实例
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//注册名为springApplicationArguments,值为applicationArguments的单例bean
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
//banner不为空,那么注册名为springBootBanner,值为printedBanner的单例bean
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
//allowBeanDefinitionOverriding默认为false
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 获取sources列表,获取到我们的YanggxApplication.class
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
//初始化bean加载器,并加载bean到应用上下文
load(context, sources.toArray(new Object[0]));
//发布contextLoaded事件
listeners.contextLoaded(context);
}
}
1、context.setEnvironment(environment);,统一ApplicationContext和Application使用的environment
配置ApplicationContext和Application的environment成员变量, 使用Application的environment, AnnotationConfigServletWebServerApplicationContext的bean定读取器reader和bean扫描器scanner都使用Application的environment
点击实现类,其所有实现该方法的context父类都将设置environment
以最终AnnotationConfigServletWebServerApplicationContext为例:
public class AnnotationConfigServletWebServerApplicationContext
extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
//显式调用父类AbstractApplicationContext的setEnvironment方法
super.setEnvironment(environment);
//调用AnnotatedBeanDefinitionReader#setEnvironment()方法
this.reader.setEnvironment(environment);
//ClassPathBeanDefinitionScanner继承了ClassPathScanningCandidateComponentProvider,所以调用了父类setEnvironment方法
this.scanner.setEnvironment(environment);
}
}
super.setEnvironment(environment)显式调用父类AbstractApplicationContext的setEnvironment方法,多个父类依次调用。
2、postProcessApplicationContext
ApplicationContext的后置处理
执行了以下三步
1、设置ApplicationContext的beanNameGenerator
2、设置ApplicationContext的resourceLoader和classLoader
3、设置ApplicationContext的类型转换Service
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
//没有设置beanNameGenerator,默认为null
if (this.beanNameGenerator != null) {
//如果beanNameGenerator不为空
//那么注册一个名为internalConfigurationBeanNameGenerator
//值为beanNameGenerator的单例bean
context.getBeanFactory().registerSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
this.beanNameGenerator);
}
//没有设置resourceLoader,默认为null
if (this.resourceLoader != null) {
//如果resourceLoader不为空
if (context instanceof GenericApplicationContext) {
//context是GenericApplicationContext子类
//那么设置上下文context的resourceLoader
((GenericApplicationContext) context)
.setResourceLoader(this.resourceLoader);
}
if (context instanceof DefaultResourceLoader) {
//如果当前上下文是DefaultResourceLoader的子类
//那么设置上下文context的classLoader
((DefaultResourceLoader) context