文章目錄
- 目錄
- 一、ApplicationContextInitializer
- ①使用步驟:
- ②注冊方法3種:
- 示範 1.app.addInitializers方式
- 示範 2:通過配置項context.initializer.classes指定
- 3.spring.factories機制(注冊listener監聽器也可以使用這種方式)
- 二、CommandLineRunner
- ①使用步驟:
- 三、ApplicationRunner
目錄
本文章主要了解在spring容器執行refreshed之前的一個回調接口:ApplicationContextInitializer,
在容器啟動成功後的最後一步回調(類似開機自啟動)的接口:CommandLineRunner和ApplicationRunner。
腦圖如下:
一、ApplicationContextInitializer
該接口是接口是在spring容器執行refreshed之前的一個回調。
①使用步驟:
- 1: 寫一個類: 實作AApplicationContextInitializer接口
- 2: 注冊ApplicationContextInitializer
②注冊方法3種:
- 1.app.addInitializers
- 2:通過配置項context.initializer.classes指定
- 3.可以通過spring.factories機制(注冊listener監聽器也可以使用這種方式)
示範 1.app.addInitializers方式
寫個實作類
public class MyAppliationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("bean count: " + applicationContext.getBeanDefinitionCount());
}
}
在入口中注冊和調用:
@SpringBootApplication
public class Demo8Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Demo8Application.class);
app.addInitializers(new MyAppliationContextInitializer());
ConfigurableApplicationContext context = app.run(args);
context.close();
}
}
測試
:
測試已經注入!
示範 2:通過配置項context.initializer.classes指定
public class MyAppliationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("bean count: " + applicationContext.getBeanDefinitionCount());
}
}
public class MyAppliationContextInitializer2 implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println(applicationContext.getDisplayName());
}
}
application.properties,寫了2個實作類:
context.initializer.classes=com.springboot.demo8.MyAppliationContextInitializer,com.springboot.demo8.MyAppliationContextInitializer2
@SpringBootApplication
public class Demo8Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Demo8Application.class);
ConfigurableApplicationContext context = app.run(args);
context.close();
}
運作結果ok:
3.spring.factories機制(注冊listener監聽器也可以使用這種方式)
建立一個項目intializer:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springboot</groupId>
<artifactId>intializer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>intializer</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
public class EchoAppliationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("=========EchoAppliationContextInitializer==========");
}
}
intializer\src\main\resources\META-INF\spring.factories:
org.springframework.context.ApplicationContextInitializer=com.springboot.intializer.EchoAppliationContextInitializer
将該項目引入原來的項目:
<dependency>
<groupId>com.springboot</groupId>
<artifactId>intializer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
測試:
@SpringBootApplication
public class Demo8Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Demo8Application.class);
ConfigurableApplicationContext context = app.run(args);
context.close();
}
}
運作結果:
結果顯示已經注入!!
二、CommandLineRunner
該接口是在容器啟動成功後的最後一步回調(類似開機自啟動),可以在應用啟動時列印一些東西之類的。
①使用步驟:
- 1.寫一個類,實作CommandLineRunner 接口
-
2 把該類納入到spring的容器管理中
示範一下 注意:可以通過@Order注解或者Ordered接口來控制執行順序。order值小的優先
@Order(1)
@Component
public class ServerSuccessReport implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("=====應用已經成功的啟動============" + Arrays.asList(args));
}
}
@Order(2)
@Component
public class ServerStartedReport implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("=====應用啟動後的時間是:============"+ LocalDateTime.now().toString());
}
}
以上2個類都實作了CommandLineRunner 接口,并用@Compoent,并通過order控制優先級,值小的優先執行,注入spring:
測試下:
@SpringBootApplication
public class Demo8Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Demo8Application.class);
ConfigurableApplicationContext context = app.run(args);
context.close();
}
}
運作結果:
三、ApplicationRunner
CommandLineRunner,ApplicationRunner 差別
差別在于方法的參數不一樣
CommandLineRunner的參數是最原始的參數,沒有做任務處理
ApplicationRunner的參數是ApplicationArguments,是對原始參數做了進一步的封裝
舉例說明:
看下CommandLineRunner的擷取參數代碼:
@Component
public class ServerSuccessReport implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("=====應用已經成功的啟動============" + Arrays.asList(args));
}
}
看戲ApplicationRunner的擷取參數代碼:
import java.util.Arrays;
@Component
public class StartedApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("應用已經啟動,參數為:" + Arrays.asList(args.getSourceArgs()));
}
}
運作結果:
都擷取了程式的參數,這裡我們看不出來差別,繼續改造:
- 先設定啟動參數:
- ApplicationRunner 擷取的是一個ApplicationArguments對象,我們來通過參數對象列印看下:
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Demo8Application.class);
ConfigurableApplicationContext context = app.run(args);
ApplicationArguments arg = context.getBean(ApplicationArguments.class);
System.out.println(arg.getSourceArgs().length);
System.out.println(arg.getOptionNames());
System.out.println(arg.getOptionValues("myname"));
context.close();
}
運作結果:
可以看到通過ApplicationArguments可以使用其提供的getOptionNames,getOptionValues方法很友善的擷取參數值,而CommandLineRunner 隻能擷取到
--myname=admin
這樣的字元串,我們擷取key或者value需要使用split切割很麻煩,而且ApplicationArguments還有好多實用的方法:
這就是CommandLineRunner,ApplicationRunner 差別 : 方法的參數類型不一樣.
本文講了主要是springboot容器2個常用接口:在spring容器執行refreshed之前的一個回調接口:ApplicationContextInitializer,
在容器啟動成功後的最後一步回調(類似開機自啟動)的接口:CommandLineRunner和ApplicationRunner,和這2個接口的差別.
個人微信公号:
搜尋: 怒放de每一天
不定時推送相關文章,期待和大家一起成長!!