ApplicationContextInitializer接口在spring容器执行refreshed之前回调,实现方式有3种
方式一:调用SpringApplication的addInitializers方法注册
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.edu.spring</groupId> <artifactId>springboot</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>springboot</name> <!-- FIXME change it to the project‘s website --> <url>http://www.example.com</url> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.6.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <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>
MyApplicationContextInitializer.java,实现ApplicationContextInitializer接口
package com.edu.spring.springboot; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { // TODO Auto-generated method stub System.out.println("当前容器bean数量:"+applicationContext.getBeanDefinitionCount()); } }
App.java,调用SpringApplication的addInitializers方法(可以有多个)
package com.edu.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication app=new SpringApplication(App.class); app.addInitializers(new MyApplicationContextInitializer()); ConfigurableApplicationContext context= app.run(args); context.close(); } }
运行结果如下:
方式二:application.properties中配置context.initializer.classes属性(可以配置多个)
application.properties
context.initializer.classes=com.edu.spring.springboot.MyApplicationContextInitializer,com.edu.spring.springboot.MyApplicationContextInitializer2
MyApplicationContextInitializer2.java
package com.edu.spring.springboot; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; public class MyApplicationContextInitializer2 implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext applicationContext) { // TODO Auto-generated method stub System.out.println("app name:"+applicationContext.getApplicationName()); } }
App.java,去掉addInitializers方法
package com.edu.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication app=new SpringApplication(App.class); ConfigurableApplicationContext context= app.run(args); context.close(); } }
运行结果如下:
方式三:使用spring.factories机制
resources/META-INF/spring.factories
org.springframework.context.ApplicationContextInitializer=com.edu.spring.springboot.EchoApplicationContextInitializer
EchoApplicationContextInitializer.java
package com.edu.spring.springboot; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; public class EchoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { public void initialize(ConfigurableApplicationContext applicationContext) { System.out.println("=============EchoApplicationContextInitializer================="); } }
App.java
package com.edu.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication app=new SpringApplication(App.class); ConfigurableApplicationContext context= app.run(args); context.close(); } }
运行结果如下:
由于spring.factories机制会扫描所有工程里面的/META-INF/spring.factories文件,所以另建一个工程也可以运行,如下:
新建core-bean
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.edu.core</groupId> <artifactId>core-bean</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>springboot</name> <!-- FIXME change it to the project‘s website --> <url>http://www.example.com</url> <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</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> </dependencies> </project>
EchoApplicationContextInitializer.java
package com.edu.initializer; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; public class EchoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { public void initialize(ConfigurableApplicationContext applicationContext) { System.out.println("=============core-bean:EchoApplicationContextInitializer================="); } }
resources/META-INF/spring.factories
org.springframework.context.ApplicationContextInitializer=com.edu.initializer.EchoApplicationContextInitializer
原工程的pom.xml文件引入core-bean坐标
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.edu.spring</groupId> <artifactId>springboot</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>springboot</name> <!-- FIXME change it to the project‘s website --> <url>http://www.example.com</url> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.6.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <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> <dependency> <groupId>com.edu.core</groupId> <artifactId>core-bean</artifactId> <version>1.0.0</version> </dependency> </dependencies> </project>
运行原工程App.java
package com.edu.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication app=new SpringApplication(App.class); ConfigurableApplicationContext context= app.run(args); context.close(); } }
运行结果如下:
CommandLineRunner、ApplicationRunner是spring容器启动成功后最后的回调,@Order控制顺序,数字越小越先执行,请看示例:
ServerSuccessReport.java
package com.edu.spring.springboot; import java.util.Arrays; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Order(1) @Component public class ServerSuccessReport implements CommandLineRunner { @Override public void run(String... args) throws Exception { // TODO Auto-generated method stub System.out.println("==========ServerSuccessReport1============"+Arrays.asList(args)); } }
ServerSuccessReport2.java
package com.edu.spring.springboot; import java.util.Arrays; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Order(3) @Component public class ServerSuccessReport2 implements CommandLineRunner { @Override public void run(String... args) throws Exception { // TODO Auto-generated method stub System.out.println("==========ServerSuccessReport2============"+Arrays.asList(args)); } }
StartedApplicationRunner.java
package com.edu.spring.springboot; import java.util.Arrays; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Order(2) @Component public class StartedApplicationRunner implements ApplicationRunner { public void run(ApplicationArguments args) throws Exception { System.out.println("应用已经启动,参数为:"+Arrays.asList(args.getSourceArgs())); } }
App.java
package com.edu.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication app=new SpringApplication(App.class); ConfigurableApplicationContext context= app.run("aa","bb "); context.close(); } }
运行结果如下:
CommandLineRunner与ApplicationRunner的区别是CommandLineRunner参数是原始的,ApplicationRunner参数是对原始参数的封装。
(011)Spring Boot之回调接口ApplicationContextInitializer、CommandLineRunner、ApplicationRunner