我们这里大概梳理一下启动过程的步骤:
1. 初始化监听器,以及添加到SpringApplication的自定义监听器 。2. 发布ApplicationStartedEvent事件,如果想监听ApplicationStartedEvent事件,你可以这样定义:public class ApplicationStartedListener implements ApplicationListener,然后通过SpringApplication.addListener(..)添加进去即可 。3. 装配参数和环境,确定是web环境还是非web环境 。4. 装配完环境后,就触发ApplicationEnvironmentPreparedEvent事件 。5. 如果SpringApplication的showBanner属性被设置为true,则打印启动的Banner 。6. 创建ApplicationContext,会根据是否是web环境,来决定创建什么类型的ApplicationContext 。7. 装配Context的环境变量,注册Initializers、beanNameGenerator等 。8. 发布ApplicationPreparedEvent事件 。9. 注册springApplicationArguments、springBootBanner,加载资源等10. 遍历调用所有SpringApplicationRunListener的contextLoaded()方法 。11. 调用ApplicationContext的refresh()方法,装配context beanfactory等非常重要的核心组件 。12. 查找当前ApplicationContext中是否注册有CommandLineRunner,如果有,则遍历执行它们 。13. 发布ApplicationReadyEvent事件,启动完毕,表示服务已经可以开始正常提供服务了 。通常我们这里会监听这个事件来打印一些监控性质的日志,表示应用正常启动了 。
文章插图
启动流程
@SpringBootApplication 注解看完了静态方法,我们来看一下另一个注解 @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 { // 省略方法}
我们省略掉对应的方法属性,发现实际上这个注解是由 3 个注解组合而成:@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan
其中 @SpringbootConfiguration 是完全等价于 @Configuration 的,此处应该是为了和 spring 的注解做区分 。所以一开始的实现,等价于:
@Configuration@EnableAutoConfiguration@ComponentScanpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
当然了,springboot 的理念就是极简配置,能少写一行代码,就少写一行代码!@Configuration 注解这里的 @Configuration 大家应该并不陌生,spring 中可以使用下面的写法,替代 spring xml 的配置写法:
@Configurationpublic class MockConfiguration{ @Bean public MockService mockService(){ return new MockServiceImpl(dependencyService()); } @Bean public DependencyService dependencyService(){ return new DependencyServiceImpl(); }}
@ComponentScan 注解@ComponentScan 的功能其实就是自动扫描并加载符合条件的组件(比如 @Component 和 @Service等)或者bean定义,最终将这些bean定义加载到IoC容器中 。我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明 @ComponentScan 所在类的package进行扫描 。
ps: 所以我们的 Application 启动类一般是放在根目录,这样连扫描的包也省略掉了 。
@EnableAutoConfiguration 注解这个注解我们放在最后讲解,因为它为 springboot 带来了更多的便利性 。
注解定义
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {}
这个注解实际上是一个组合注解 @AutoConfigurationPackage + @Import@AutoConfigurationPackage:自动配置包
@Import: 导入自动配置的组件
我们来看一下这 2 个注解:
推荐阅读
- Python线程的生命周期你知道多少,一文帮你全部搞清楚
- C#语音对话控制PLC太香
- 如何挑选牛腱子肉
- 去饭店必点菜 去饭店不知道点什么菜
- 面试不懂 Linux 内存管理?我用 20 张图给你讲明白
- 荣耀magic3官方消息 荣耀magic3上市
- Docker 命令自动补全?要的
- .NET已经步入5.0时代,这些代码保护软件需要知道
- 小麦粉怎么做馒头
- 诈骗|反诈警官老陈称辞职是错误决定:感到委屈不服气 生活似乎难回到以前