回顧
上一節(jié)我們看到了最初的使用Springboot和不用的時(shí)候有什么區(qū)別,怎么開始用,這一節(jié)我們看下后續(xù)的run中我們可以做什么,我們開發(fā)怎么去干擾。也就是怎么在里面合適的為止開始寫我們自己的代碼片段,這些片段通過(guò)Springboot提供的框架連接起來(lái),最后形成一個(gè)可運(yùn)行的完整的功能。
Springboot擴(kuò)展
我們了解到SpringApplication.run()既開始一個(gè)Springboot的運(yùn)行,開始的時(shí)候會(huì)檢查我們META-INF/spring.factories的文件,如果有這個(gè)文件,則加載。這個(gè)文件可以配置一系列定制化的內(nèi)容。比如在Spring運(yùn)行的時(shí)候分好幾個(gè)階段,如SpringContext 初始化前,進(jìn)入到初始化,結(jié)束前操作,和結(jié)束后的操作等等,由于這些操作都被封裝在了Springboot內(nèi)部,自成一體。但是很多時(shí)候用戶需要定制在某些特殊的時(shí)候做一些操作,需要有用戶的自定義代碼運(yùn)行在某一階段,這個(gè)時(shí)候這個(gè)文件配置的作用就出現(xiàn)了。
java早期有SPI機(jī)制,提供給用戶定制化的開發(fā)。(具體內(nèi)容見(jiàn):https://blog.csdn.net/lldouble/article/details/80690446
)
org.springframework.boot.SpringApplicationRunListener=cn.miludeer.init.EnvironmentInitializer
spring.factories的文件內(nèi)容如上,key=value1,value2 的方式進(jìn)行配置。啟動(dòng)的時(shí)候會(huì)取出所有的內(nèi)容進(jìn)行初始化處理。
嘗試寫點(diǎn)代碼試試效果
實(shí)現(xiàn)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...");
}
運(yùn)行結(jié)果:
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
可以看到不同的階段答應(yīng)出來(lái)不同的內(nèi)容,這就方面了我們?cè)诳蚣艿母鱾€(gè)部分插入不同的內(nèi)容實(shí)現(xiàn)不同階段的執(zhí)行。(主要是在不同階段的初始化工作等)
其他幾個(gè)鉤子
org.springframework.boot.SpringApplicationRunListener 初始化的各個(gè)階段
org.springframework.boot.env.EnvironmentPostProcessor 獲取環(huán)境參數(shù)(配置)
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter 禁用某些自動(dòng)化配置
org.springframework.context.ApplicationListener 注冊(cè)本地事件
總結(jié)
Springboot可以將某個(gè)模型或某一類的抽象開發(fā)邏輯寫完(骨架)。用戶做開發(fā)可以在里面添加自己的邏輯(血肉)。我們要做的就是找對(duì)合適的地方,插上我們的代碼就可以。