n (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
}
方法会先显式的获取应用上下文对象,如果对象为空,再加载默认的环境配置,通过是否是webEnvironment进行判断,默认选择的是AnnotationConfigApplicationContext(注解上下文,通过扫秒注解来加载bean),然后通过BeanUtils来实例化应用上下文对象然后返回,ConfigurableApplicationContext类继承关系如下:
这里推荐一下我的另一篇博客,不太懂ConfigurableApplicationContext的可以去看一下,https://juejin.im/post/5d72055f5188256bab4c0b6d
回到run()方法中,会调用prepareContext()方法将environment, listeners,applicationArguments, printedBanner等组件与上下文对象进行关联
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);
}
// Add boot specific singleton beans
context.getBeanFactory().registerSingleton("springApplicationArguments",
applicationArguments);
if (printedBanner != null) {
context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
}
// Load the sources
Set<Object> sources = getSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[sources.size()]));
listeners.contextLoaded(context);
}
然后会调用refreshContext()方法,实际调用org.springframework.context.support.AbstractApplicationContext.refresh()内的相关方法。这个方法里会进行redis,mybatis等的自动配置,包括spring.factories的加载,bean的实例化,BenFactoryPostProcessor接口的执行,BeanPostProcessor接口的执行,条件注解的解析,国际化功能的初始化等。
refreshContext()方法执行完毕之后会执行afterRefresh方法,当run()方法执行完之后Spring容器也就初始化完毕了
protected void afterRefresh(ConfigurableApplicationContext context,
ApplicationArguments args) {
callRunners(context, args);
}
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<Object>();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<Object>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}
private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
try {
(runner).run(args);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
}
}
private void callRunner(CommandLineRunner runner, ApplicationArguments args) {
try {
(runner).run(args.getSourceArgs());
}
catch (Exception ex) {
throw new IllegalStateException("Failed to execute CommandLineRunner", ex);
}
}