SprintBoot 应用上下文初始化器
本文内容:
- 如何自定义系统初始化器
- 注册自定义系统初始化器的三种方式
自定义系统初始化器与注册
通过实现ApplicationContextInitializer
接口自定义系统初始化器,使用@Order
注解配置加载顺序。
注册自定义系统初始化器有三种方式:
- 在META-INF下的
spring.factories
文件中注册,键值:org.springframework.context.ApplicationContextInitializer - 在启动类中通过SpringApplication实例对象调用addInitializers()方法添加
- 在
application.properties
中配置,键值:context.initialicer.classes,(这种方式配置的加载顺序优先其他)
代码示例
方式一
新建包initailizer
,创建FirstInitializer
类,实现ApplicationContextInitializer
接口。
package net.pjsk.sb.initializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import java.util.HashMap;
import java.util.Map;
/**
* @author liyan
* @date 2021.2.28
*/
@Order(1)
public class FirstInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
// 获取环境
ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment();
// 要初始化的参数
Map<String, Object> map = new HashMap<>();
map.put("key1", "自定义系统初始化器1");
MapPropertySource firstInitializer = new MapPropertySource("firstInitializer", map);
// 将自定义的参数Map加入到环境属性中
environment.getPropertySources().addLast(firstInitializer);
System.out.println("--> 系统初始化器1");
}
}
注册自定义系统初始化器,在resources
目录下新建META-INF
目录,并创建spring.factories
文件。将自定义的系统初始化器配置进来完成注册。
org.springframework.context.ApplicationContextInitializer=net.pjsk.sb.initializer.FirstInitializer
测试
在service
包中创建TestService
类并实现ApplicationContextAware
接口。在这个接口中可以拿到应用上下文对象applicationContext
。
package net.pjsk.sb.service;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
@Service
public class TestService implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public String test() {
// 获取系统初始化器中自定义的属性
return applicationContext.getEnvironment().getProperty("key1");
}
}
在controller中写方法测试。
@GetMapping("/test")
public String test() {
return this.testService.test();
}
浏览器访问接口。
控制台打印。
方式二
package net.pjsk.sb.initializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import java.util.HashMap;
import java.util.Map;
@Order(2)
public class SecondInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment();
Map<String, Object> map = new HashMap<>();
map.put("key2", "自定义系统初始化器2");
MapPropertySource secondInitializer = new MapPropertySource("secondInitializer", map);
environment.getPropertySources().addLast(secondInitializer);
System.out.println("--> 系统初始化器2");
}
}
在启动类的main方法中添加系统初始化器,实例化SpringApplication
对象,通过该对象调用addInitializer()
方法添加自定义的系统初始化器。
package net.pjsk.sb;
import net.pjsk.sb.initializer.SecondInitializer;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
/**
* @author liyan
* @date 2021.2.27
*/
@SpringBootApplication
@MapperScan(value = "net.pjsk.sb.mapper")
public class SbApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SbApplication.class);
// 添加系统初始化器
application.addInitializers(new SecondInitializer());
application.run(args);
}
}
测试
修改TestService中的方法,获取'key2'的值。
浏览器访问。
控制台打印。
方式三
package net.pjsk.sb.initializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import java.util.HashMap;
import java.util.Map;
@Order(3)
public class ThirdInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment();
Map<String, Object> map = new HashMap<>();
map.put("key3", "自定义系统初始化器3");
MapPropertySource thirdInitializer = new MapPropertySource("thirdInitializer", map);
environment.getPropertySources().addLast(thirdInitializer);
System.out.println("--> 系统初始化器3");
}
}
在application.yaml
中配置自定义的系统初始化器。
# 系统初始化器
context:
initializer:
classes: net.pjsk.sb.initializer.ThirdInitializer
测试 浏览器访问。
控制台打印。
总结
- 自定义系统初始化器,需要实现
ApplicationContextInitializer
接口; - 三种注册方式:
- 通过
spring.factories
配置,键值:org.springframework.context.ApplicationContextInitializer
- 通过启动类中的
SpringApplication
对象调用addInitializer()
添加初始化器。 - 在
application.yaml
中配置,键值:context.initializer.classes
- 通过
@Order
的数值越小,优先级越高。application.yaml
中配置的优先级高于其他方式。