回顾
上一节我们看到了最初的使用Springboot和不用的时候有什么区别,怎么开始用,这一节我们看下后续的run中我们可以做什么,我们开发怎么去干扰。也就是怎么在里面合适的为止开始写我们自己的代码片段,这些片段通过Springboot提供的框架连接起来,最后形成一个可运行的完整的功能。
Springboot扩展
我们了解到SpringApplication.run()既开始一个Springboot的运行,开始的时候会检查我们META-INF/spring.factories的文件,如果有这个文件,则加载。这个文件可以配置一系列定制化的内容。比如在Spring运行的时候分好几个阶段,如SpringContext 初始化前,进入到初始化,结束前操作,和结束后的操作等等,由于这些操作都被封装在了Springboot内部,自成一体。但是很多时候用户需要定制在某些特殊的时候做一些操作,需要有用户的自定义代码运行在某一阶段,这个时候这个文件配置的作用就出现了。
java早期有SPI机制,提供给用户定制化的开发。(具体内容见:https://blog.csdn.net/lldouble/article/details/80690446
)
org.springframework.boot.SpringApplicationRunListener=cn.miludeer.init.EnvironmentInitializer
spring.factories的文件内容如上,key=value1,value2 的方式进行配置。启动的时候会取出所有的内容进行初始化处理。
尝试写点代码试试效果
实现cn.miludeer.init.EnvironmentInitializer
public class EnvironmentInitializer implements SpringApplicationRunListener {
public EnvironmentInitializer(SpringApplication application, String[] args) {
}
@Override
public void starting() {
System.out.println("starting...");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
System.out.println("environmentPrepared...");
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("contextPrepared...");
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("contextLoaded...");
}
@Override
public void started(ConfigurableApplicationContext context) {
System.out.println("started...");
}
@Override
public void running(ConfigurableApplicationContext context) {
System.out.println("running...");
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("failed...");
}
运行结果:
main starting...
starting...
environmentPrepared...
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.4.RELEASE)
contextPrepared...
2019-10-30 20:59:11.863 INFO 5487 --- [ main] cn.miludeer.deer.ApplicationMain : Starting ApplicationMain on MacBook-Pro-9.local with PID 5487 (/Users/mac/code/cnmiludeer/target/classes started by mac in /Users/mac/code/cnmiludeer)
2019-10-30 20:59:11.866 INFO 5487 --- [ main] cn.miludeer.deer.ApplicationMain : No active profile set, falling back to default profiles: default
contextLoaded...
2019-10-30 20:59:11.879 INFO 5487 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3d3fcdb0: startup date [Wed Oct 30 20:59:11 CST 2019]; root of context hierarchy
2019-10-30 20:59:12.003 INFO 5487 --- [ main] cn.miludeer.deer.ApplicationMain : Started ApplicationMain in 0.997 seconds (JVM running for 1.562)
started...
running...
main started!!!
2019-10-30 20:59:12.006 INFO 5487 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3d3fcdb0: startup date [Wed Oct 30 20:59:11 CST 2019]; root of context hierarchy
Process finished with exit code 0
可以看到不同的阶段答应出来不同的内容,这就方面了我们在框架的各个部分插入不同的内容实现不同阶段的执行。(主要是在不同阶段的初始化工作等)
其他几个钩子
org.springframework.boot.SpringApplicationRunListener 初始化的各个阶段
org.springframework.boot.env.EnvironmentPostProcessor 获取环境参数(配置)
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter 禁用某些自动化配置
org.springframework.context.ApplicationListener 注册本地事件
总结
Springboot可以将某个模型或某一类的抽象开发逻辑写完(骨架)。用户做开发可以在里面添加自己的逻辑(血肉)。我们要做的就是找对合适的地方,插上我们的代码就可以。
网友评论