分解一下步骤:先构造方法, 然后run方法
构造方法解析
- 获取BeanDefinition 主源
- 推断应用类型
- ApplicationContext初始化器
- 监听器和事件
- 主类推断
文章目录
1.1 获取BeanDefinition 主源
这里可以理解为获取一个ResourceLoader 用于获取BeanDefinition
然后断言主源是否存在
然后将主源添加到集合中, 这个集合为primarySources
集合用于后续解析获取到BeanDefinition
1.2 推断应用类型
用于判断是SERVLET 还是 REACTIVE 还是 NONE
static WebApplicationType deduceFromClasspath() {
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
1.3 ApplicationContext初始化器
初始化进行增强
private List<BootstrapRegistryInitializer> getBootstrapRegistryInitializersFromSpringFactories() {
ArrayList<BootstrapRegistryInitializer> initializers = new ArrayList<>();
getSpringFactoriesInstances(Bootstrapper.class).stream()
.map((bootstrapper) -> ((BootstrapRegistryInitializer) bootstrapper::initialize))
.forEach(initializers::add);
initializers.addAll(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
return initializers;
}
springApplication.addInitializers(new ApplicationContextInitializer<ConfigurableApplicationContext>() {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
// context
GenericApplicationContext context = (GenericApplicationContext) applicationContext;
context.registerBean("bean1", Bean1.class);
}
});
1.4 监听器和事件
注册监听器, 用于后面使用
1.5 主类推断
判断main方法是哪个类
这里我利用反射调用这个方法
@SpringBootApplication
public class Main {
public static void main(String[] args)throws Exception{
SpringApplication app = new SpringApplication(Main.class);
app.run(args);
Method method = SpringApplication.class.getDeclaredMethod("deduceMainApplicationClass");
method.setAccessible(true);
System.out.println(method.invoke(app));
}
}
获取类名