SpringBoot 系统初始化器 - ApplicationContextInitializer 三种实现方式

与世无争的帅哥 提交于 2020-02-24 04:26:56

SpringBoot 系统初始化器 - ApplicationContextInitializer

  • 类名: ApplicationContextInitializer。
  • 介绍: Spring容器刷新(reflash)之前执行的一个回调函数。
  • 作用: 主要是向SpringBoot容器中注册属性。
  • 使用方式: 继承接口自定义实现。
  • 总结:系统初始化器就是SpringBoot预留的一个扩展点,通过这个扩展点我们可以在SpringBoot容器刷新前注册自定义的相关属性。

自定义系统初始化器的实现方式

实现方式01

  • 具体的代码实现如下所示:
  • 步骤01 继承 ApplicationContextInitializer 接口
  • 步骤02 在项目的resources 目录下建立一个目录 META-INF 下再建立一个文件 spring.factories
/**
 * 描述:  第一个初始化器
 * 实现方式1 继承 ApplicationContextInitializer 接口
 *
 * @author mh
 * @create 2020-02-23 12:13
 */
 @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("key01", "value01");
        //打造一个属性
        MapPropertySource mapPropertySource = new MapPropertySource("FirstInitializer", map);
        // 存放到上述的环境中
        MutablePropertySources propertySources = environment.getPropertySources();
        propertySources.addLast(mapPropertySource);
        System.out.println(" ======= run FirstInitializer =============");
    }
}
  • spring.factories 内容如下,主要目的向容器中注册我们自定义的系统初始化器,spring会扫描从META-INF下的spring.factories文件注册系统初始化器
## 注册自定义的系统初始化器
org.springframework.context.ApplicationContextInitializer =com.example.springbootsource.initializer.FirstInitializer
  • 验证核心代码如下所示:
@Service
public class DemoService implements ApplicationContextAware {
    private ApplicationContext applicationContext;


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //获取上下文
        this.applicationContext = applicationContext;
    }

    public String test() {
        return applicationContext.getEnvironment().getProperty("key01");
    }
}

实现方式2

  • 自定义的系统初始化器代码没有不同
  • 在注册阶段,我们可以通过SpringApplication实现进行添加自定义的系统初始化器
  • 系统初始化器初始化器也支持Order注解,值越低优先级越高
  • 具体实现代码如下所示:

/**
 * 描述:  第二个系统初始化器
 *
 * @author mh
 * @create 2020-02-23 12:31
 */
@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("key02", "value02");
        //打造一个属性
        MapPropertySource mapPropertySource = new MapPropertySource("SecondInitializer", map);
        // 存放到上述的环境中
        MutablePropertySources propertySources = environment.getPropertySources();
        propertySources.addLast(mapPropertySource);
        System.out.println(" ======= run SecondInitializer =============");
    }
}
  • 修改启动类
@SpringBootApplication
public class SpringbootSourceApplication {
    public static void main(String[] args) {
//		SpringApplication.run(SpringbootSourceApplication.class, args);
        SpringApplication springApplication = new SpringApplication(SpringbootSourceApplication.class);
        springApplication.addInitializers(new SecondInitializer());
        springApplication.run(args);
    }
}
  • 控制台输出:
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.3.RELEASE)

 ======= run FirstInitializer =============
 ======= run SecondInitializer =============
  • 第一个自定义的系统初始化器 @order(1)
  • 第二个自定义的系统初始化器 @order(2)
  • 验证代码和上述一样

第三种实现方式

  • 自定义的初始化器实现代码一致

  • 注册方式我们选择在application.properties文件中进行注册

  • 代码如下所示:

@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("key03", "value03");
        //打造一个属性
        MapPropertySource mapPropertySource = new MapPropertySource("ThirdInitializer", map);
        // 存放到上述的环境中
        MutablePropertySources propertySources = environment.getPropertySources();
        propertySources.addLast(mapPropertySource);
        System.out.println(" ======= run ThirdInitializer =============");
    }
}
  • application.properties
context.initializer.classes =com.example.springbootsource.initializer.ThirdInitializer
  • 控制台
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.3.RELEASE)

 ======= run ThirdInitializer =============
 ======= run FirstInitializer =============
 ======= run SecondInitializer =============
  • 从控制台可知:第三种注册方式优先于第1 第2 具体原因我们后续在学习。

  • 总结:

    • 自定义的系统初始化器都是通过继承 ApplicationContextInitializer 接口
    • 在注册阶段有三种不同的注册方式。
    • Order的值越小优先级越高
    • application.properties定义的优先于其他方式
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!