一羞延、SpringApplication的幾種常用方式
二、定制啟動Banner
三脾还、SpringBoot事件和監(jiān)聽器
四伴箩、SpringBoot的Web環(huán)境信息
五、SpringBoot的ApplicationRunner接口 和 CommandLineRunner接口
SpringBoot版本:1.5.13.RELEASE
對應(yīng)官方文檔鏈接:https://docs.spring.io/spring-boot/docs/1.5.13.RELEASE/reference/htmlsingle/
上一篇:SpringBoot 入門篇(二) SpringBoot常用注解以及自動配置
一鄙漏、SpringApplication的幾種常用方式
??在之前的兩篇SpringBoot 入門介紹中嗤谚,都使用了在main方法中執(zhí)行SpringApplication.run()這種方式來啟動我們的工程
// 方式一
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
??如果我們需要在SpringBoot啟動過程中添加一些定制代碼(如定制啟動Banner,設(shè)置自定義監(jiān)聽器等)怔蚌,這種方式就無法滿足我們的要求了巩步,因此,官方文檔提供了其他的啟動方式來滿足我們定制需求桦踊。在給出官方文檔提供的啟動方式之前椅野,我們進(jìn)入SpringApplication.run()方法簡單看下底層做了些什么動作。
??可以看到籍胯,SpringApplication.run()的底層其實就是new了一個SpringApplication的對象鳄橘,并執(zhí)行run()方法,run()方法里面執(zhí)行了哪些動作在之后的文章中詳細(xì)說明芒炼。接著我們來看官方文檔提供的啟動方式
// 方式二
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.run(args);
}
到了這里瘫怜,就不在多說什么了。
??有時我們需要創(chuàng)建多層次的ApplicationContext (例如本刽,父子關(guān)系的Spring的ApplicationContext 和SpringMVC)鲸湃,這時我們可以使用官方提供的另外一種“平滑”的API調(diào)用方式來啟動工程赠涮,即使用SpringApplicationBuilder講多個方法調(diào)用串起來,通過parent() 和 child()來創(chuàng)建多層次的ApplicationContext暗挑。如果查看底層代碼笋除,可以看到除了調(diào)用child()方法略有不同,其他的和前兩種方法幾乎一樣炸裆。
// 方式三
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.run(args);
}
以上三方式是SpringBoot最常用的啟動方式垃它,當(dāng)然,官方還提供了通過配置application.properties文件在SpringBoot啟動過程中添加一些定制邏輯的方案烹看。
二国拇、定制啟動Banner
??如果在啟動時,打印的如下這個圖案(Banner)不符合我們的審美咋辦惯殊?如果我們要在圖案中加入公司標(biāo)志或者版權(quán)聲明咋辦酱吝?如果我們不想打印Banner咋辦?
??SpringBoot為我們提供了修改Banner的方法土思。我們可以在類路徑下banner.txt务热、banner.gif、banner.jpg或者banner.png來定制Banner(banner.gif己儒、banner.jpg或者banner.png會“翻譯”成對應(yīng)的ASCII藝術(shù)圖案)崎岂,當(dāng)然,我們也可以在SpringBoot配置文件中指定banner.location或者banner.image.location對應(yīng)的Banner路徑來定制Banner闪湾。
??需要注意的是冲甘,當(dāng)文本文件(banner.txt)和圖像文件(banner.gif/jpg/png)是可以同時在控制臺顯示,但如果有多個圖像文件响谓,只會顯示其中排序靠后的一個(即優(yōu)先級png>jpg>gif)。
在banner.txt中還支持使用一些變量:
${spring-boot.version}:SpringBoot的版本
${spring-boot.formatted-version}:格式化后的SpringBoot的版本
${application.version}:應(yīng)用版本(在MANIFEST.MF文件中定義)
${application.formatted-version}:格式化后的應(yīng)用版本(在MANIFEST.MF文件中定義)
${application.title}:應(yīng)用名稱(在MANIFEST.MF文件中定義)
${Ansi.NAME} (${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME}): ANSI控制碼
??如果我們通過代碼生成定制的Banner省艳,那么可以自己實現(xiàn)Banner接口娘纷,通過實現(xiàn)printBanner()方法,并結(jié)合使用SpringApplication.setBanner(?)或者SpringApplicationBuilder.banner()的方式來打印定制的Banner跋炕。
??如果我們不想打印Banner赖晶,可以使用通過在代碼中設(shè)置Banner.Mode.OFF的方式關(guān)閉Banner打印。當(dāng)然辐烂,也可以通過在配置文件中設(shè)置 spring.main.banner-mode=off 的方式進(jìn)行關(guān)閉遏插。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
// 方式一
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
// 方式二
/*new SpringApplicationBuilder()
.sources(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);*/
}
}
三、SpringBoot事件和監(jiān)聽器
??事件是用來通知監(jiān)聽事件的監(jiān)聽器某件事情的處理狀態(tài)纠修,在SpringBoot啟動過程中胳嘲,除了Spring框架的事件外,SpringBoot還會觸發(fā)其他的一些事件扣草,這些事件按下列順序觸發(fā):
(1)ApplicationStartingEvent:項目剛啟動時觸發(fā)了牛,此時除了注冊監(jiān)聽器和初始器之外颜屠,其他所有處理都沒有開始;
(2)ApplicationEnvironmentPreparedEvent:上下文得到環(huán)境信息之后觸發(fā)鹰祸,此時上下文創(chuàng)建還沒有創(chuàng)建甫窟;
(3)ApplicationPreparedEvent:bean的定義信息加載完成之后觸發(fā),此時bean還沒有初始化蛙婴;
(4)ApplicationReadyEvent:在所有bean初始化完畢粗井,所有回調(diào)處理完成,系統(tǒng)準(zhǔn)備處理服務(wù)請求時觸發(fā)街图;
(5)ApplicationFailedEvent:啟動過程出現(xiàn)異常時候觸發(fā)浇衬。
??知道SpringBoot啟動時發(fā)送的時間后,我們就能自定義監(jiān)聽器對這些事件進(jìn)行監(jiān)聽台夺,從而達(dá)到擴展啟動流程的目的径玖。我們的自定義監(jiān)聽器需要實現(xiàn)ApplicationListener接口,同時指定需要監(jiān)聽哪個事件颤介。
??然后在main方法中梳星,將自定義監(jiān)聽器加入到SpringApplication中。
??除了上述代碼的方式添加監(jiān)聽器外滚朵,還可以通過在classpath下創(chuàng)建META-INF/spring.factories文件冤灾,并將自定義監(jiān)聽器通過鍵值對的形式(org.springframework.context.ApplicationListener = com.qzc.demo4.MyListener)加入到SpringApplication中。
??執(zhí)行main方法啟動工程
四辕近、SpringBoot的Web環(huán)境信息
??ApplicationContext是Spring框架中一個很重要的接口韵吨,它擴展了BeanFactory,增加了很多常用的功能移宅。SpringBoot啟動過程中归粉,SpringApplication通常會選擇合適的ApplicationContext實現(xiàn)類,在默認(rèn)情況下漏峰,如果是Web應(yīng)用糠悼,則會創(chuàng)建AnnotationConfigEmbeddedWebApplicationContext類的對象;否則會創(chuàng)建AnnotationConfigApplicationContext類的對象浅乔。
??通過查看SpringApplication,run()的底層代碼倔喂,可以看到,創(chuàng)建什么類型的ApplicationContext是由 webEnvironment 這個布爾變量來決定的靖苇,而 webEnvironment 這個變量是由項目的classpath下是否存在javax.servlet.Servlet或者org.springframework.web.context.ConfigurableWebApplicationContext席噩,如果存在其中的一個,則為true贤壁;否則為false悼枢。
??我們可以通過SpringApplication.setWebEnvironment()方法來改變webEnvironment 變量從而改變ApplicationContext的具體類型。當(dāng)然脾拆,我們還可以通過setApplicationContextClass()方法來完全定制ApplicationContext萧芙。
SpringApplication application = new SpringApplication(Application.class);
application.setWebEnvironment(false);
// application.setApplicationContextClass(...);
application.run(args);
五给梅、SpringBoot的ApplicationRunner接口 和 CommandLineRunner接口
??如果我們想在SpringBoot啟動時傳入一些參數(shù)進(jìn)行一些特殊的業(yè)務(wù)邏輯處理,此時我們可以去實現(xiàn)ApplicationRunner 或者 CommandLineRunner 接口双揪,這兩個接口都只有一個run()方法动羽,該run()方法會在SpringApplication.run(?) 完成之前被調(diào)用。另外渔期,如果我們有多個類實現(xiàn)了ApplicationRunner 或者 CommandLineRunner 接口运吓,我們可以在該類上標(biāo)注@Order注解或者讓該類再實現(xiàn)org.springframework.core.Ordered接口來保證執(zhí)行的順序。
??ApplicationRunner 和 CommandLineRunner 的區(qū)別就是封裝參數(shù)的形式不一樣疯趟,ApplicationRunner將參數(shù)封裝到ApplicationArguments類中拘哨,而CommandLineRunner 將參數(shù)傳到String可變數(shù)組中。
@Component
@Order(1) // 數(shù)值越小信峻,優(yōu)先級越高
public class MyCommandLineRunner implements CommandLineRunner {
//public class MyCommandLineRunner implements CommandLineRunner, Order {
@Override
public void run(String... args) {
if (args != null) {
for (String s : args) {
System.out.println("MyCommandLineRunner:" + s);
}
}
}
}
@Component
@Order(2) // 數(shù)值越小倦青,優(yōu)先級越高
public class MyApplicationRunner implements ApplicationRunner {
// public class MyApplicationRunner implements ApplicationRunner, Order {
@Override
public void run(ApplicationArguments args) {
if (args != null) {
String[] argArr = args.getSourceArgs();
for (String s : argArr) {
System.out.println("MyApplicationRunner:" + s);
}
}
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.run(args);
}
}
??在IDEA中進(jìn)行如下配置
啟動執(zhí)行main方法啟動工程可以看到
上一篇:SpringBoot 入門篇(二) SpringBoot常用注解以及自動配置
下一篇:SpringBoot 入門篇(四) SpringBoot外部配置以及優(yōu)先級