spring-boot源码解析之应用启动
spring boot 项目使用默认配置的思想,极大的简化了 spring 项目的开发。下面的代码就是一个最简单的 spring 项目:
1 |
|
代码很简洁,只调用了SpringApplication的 run 方法。接下来,我们就要深入源码,分析下,spring boot的启动过程。
1 | public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { |
在 SpringApplication的静态方法 run里,其实上是构造了SpringApplication的实例,并调用了实例的 run(类方法)。
先看看 SpringApplication 的构造方法干了什么?
1 | public SpringApplication(Class<?>... primarySources) { |
使用deduceFromClasspath 判断当前程序类型
1 | private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet", |
设置初始化器(Initializer) 和监听器(listener)
可以看到初始化器和监听器的获取方法都是getSpringFactoriesInstances。
1 | private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) { |
当入参是”ApplicationContextInitializer.class”时,factoryClassName为”org.springframework.context.ApplicationContextInitializer”。
1 | public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) { |
文件中的一段内容:
1 | # Application Context Initializers |
上述配置文件中的实现类会通过createSpringFactoriesInstances方法获取对应的实例。
1 | private <T> List<T> createSpringFactoriesInstances(Class<T> type, |
推断应用入口类
1 | // 通过构造一个运行时异常,通过异常栈中方法名为main的栈帧来得到入口类的名字。 |
至此,对于SpringApplication实例的初始化过程就结束了。
SpringApplication.run方法
1 | public ConfigurableApplicationContext run(String... args) { |
获取 run listeners
1 | private SpringApplicationRunListeners getRunListeners(String[] args) { |
这里仍然利用了getSpringFactoriesInstances方法来获取实例.
1 | # Run Listeners |
准备环境 prepareEnvironment
1 | private ConfigurableEnvironment prepareEnvironment( |
创建Spring上下文
1 | public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context." |
Spring上下文前置处理
1 | private void prepareContext(ConfigurableApplicationContext context, |
Spring上下文刷新
1 | private void refreshContext(ConfigurableApplicationContext context) { |
Spring上下文后置处理
1 | protected void afterRefresh(ConfigurableApplicationContext context, |
callRunners
1 | private void callRunners(ApplicationContext context, ApplicationArguments args) { |
调用注册的runner,下面的接口的实现类,区别是参数不同:
- org.springframework.boot.ApplicationRunner
- org.springframework.boot.CommandLineRunner
1 | public interface ApplicationRunner { |