一、启动配置原理
几个重要的事件回调机制
配置在META-INF/spring.factories
ApplicationContextInitializer
SpringApplicationRunListener
只需要放在ioc容器中
ApplicationRunner
CommandLineRunner
启动流程:断点启动Spring boot应用
1、下一步进入SpringApplication.run()中,此方法分为2个步骤
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args); //sources为主运行类的信息
}
第一步:创建SpringApplication对象
第二步:运行run();
static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args); //sources为主运行类的信息
}
第一步:创建SpringApplication对象
第二步:运行run();
1.1 第一步SpringApplication创建
初始化参数,执行SpringApplication()方法
public SpringApplication(Object... sources) {
initialize(sources);
}
SpringApplication(Object... sources) {
initialize(sources);
}
1.1.1 执行SpringApplication.initialize()
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));//保存主配置类
}
//判断是否为web应用,通过classLoader判断是否加载的有{ "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" }
this.webEnvironment = deduceWebEnvironment();
//从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();//获取到main方法所在的类
}
void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));//保存主配置类
}
//判断是否为web应用,通过classLoader判断是否加载的有{ "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" }
this.webEnvironment = deduceWebEnvironment();
//从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();//获取到main方法所在的类
}
1.1.1.1 创建ApplicationContextInitializer
getSpringFactoriesInstances()说明: loadFactoryNames()获取需要加载的类
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// 通过classLoader 从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer集合,
Set<String> names = new LinkedHashSet<String>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names); //创建实例
AnnotationAwareOrderComparator.sort(instances); //排序
return instances;
}
<T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// 通过classLoader 从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer集合,
Set<String> names = new LinkedHashSet<String>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names); //创建实例
AnnotationAwareOrderComparator.sort(instances); //排序
return instances;
}
1.1.1.1.1 执行 SpringFactoriesLoader.loadFactoryNames()
说明:主要执行SpringFactoriesLoader.loadFactoryNames(type, classLoader),通过classLoader 从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer
//获取ApplicationContextInitializer 保存起来
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {