1.SpringBoot项目启动方式:
- 在IDE中启动SpringBoot主类(XXXApplication)中的main方法
- 使用mvn spring-boot:run命令启动
- 打成jar包之后使用java -jar xxx.jar运行
- 打成war包之后放在web容器中运行
这是一篇一年多前写的博客,使用的源码版本是1.5.x。当时发布在CSDN,现在同步到其他平台,虽然SpringBoot这个版本帝刷的很快,但是2.x版本的启动流程并没有怎么变化,一样可供参考。
2.SpringBoot启动流程主要分为三步:
第一部分:SpringApplication初始化模块,配置一些基本的环境变量,资源,监听器,构造器;
第二部分:实现了应用具体的启动方案,包括流程的监听模块,加载配置环境模块以及创建上下文环境模块
第三部分:自动化配置模块,这个模块是实现SpringBoot的自动配置
SpringBoot程序的主入口就是标注了@SpringBootApplication注解的类,该类中有一个main方法,在main方法中调用SpringApplication的run()方法,这个run()方法来启动整个程序
@SpringBootApplication
public class CrmWebApiApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(CrmWebApiApplication.class, args);
}
}
下面是@SpringBootApplication注解的头部源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
这是一个组合注解,其中标注的注解主要有以下作用
@EnableAutoConfiguration: 开启SpringBoot自动配置,在程序启动时会自动加载SpringBoot的默认配置,如果有对一些参数进行配置,则会在程序启动时或调用时进行追加或者覆盖
@SpringBootConfiguration: 这个注解和@Configuration注解的作用一样,用来表示被标注的类是一个配置类,会将被标注的类中一个或多个被@Bean注解修饰的方法添加到Spring容器中,实例的名字默认是方法名
@ComponentScan: 包扫描注解,默认扫描主类包路径下的类
进入run()方法后的代码如下:
/**
* Static helper that can be used to run a {@link SpringApplication} from the
* specified sources using default settings and user supplied arguments.
* @param sources the sources to load
* @param args the application arguments (usually passed from a Java main method)
* @return the running {@link ApplicationContext}
*/
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}
这里会创建一个SpringApplication类的实例,进入SpringApplication类中可以看到构造方法里调用了一个initialize(sources)方法
/**
* Create a new {@link SpringApplication} instance. The application context will load
* beans from the specified sources (see {@link SpringApplication class-level}
* documentation for details. The instance can be customized before calling
* {@link #run(String...)}.
* @param sources the bean sources
* @see #run(Object, String[])
* @see #SpringApplication(ResourceLoader, Object...)
*/
public SpringApplication(Object... sources) {
initialize(sources);
}
Initialize(sources)方法源码如下:
@SuppressWarnings({ "unchecked", "rawtypes" })
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
//将sources设置到SpringApplication类的source属性中,这时的source值只有主类
this.sources.addAll(Arrays.asList(sources));
}
//判断是不是web程序,
this.webEnvironment = deduceWebEnvironment();
//从spring.factories文件中找出key为ApplicationContextInitializer的类进行实例化,然后设置到SpringApplciation类的initializers属性中,这个过程也是找出所有的应用程序初始化器
setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class));
//从spring.factories文件中找出key为ApplicationListener的类并实例化后设置到SpringApplication的listeners属性中。这个过程就是找出所有的应用程序事件监听器
setListeners((Collection) getSpringFactoriesI