Spring扩展接口-ApplicationContextInitializer

简介

上下文(ConfigurableApplicationContext)刷新(当spring框架内部执行 ConfigurableApplicationContext#refresh() 方法的时候或者在SpringBoot的run()执行时)之前,Spring提供了扩展接口ApplicationContextInitializer,允许对ConfigurableApplicationContext做进一步的处理和设置。

  • 通常用于需要对应用程序上下文进行编程初始化的web应用程序中。例如,根据上下文环境注册属性源或激活配置文件。参考ContextLoader和FrameworkServlet中支持定义contextInitializerClasses作为context-param或定义init-param。
  • ApplicationContextInitializer支持Order注解,表示执行顺序,越小越早执行;
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {

    /**
     * Initialize the given application context.
     * @param applicationContext the application to configure
     */
    void initialize(C applicationContext);

}

用途示例

SpringBoot内置的一些ApplicationContextInitializer

下面列出了一个使用缺省配置的Springboot web应用默认所使用到的ApplicationContextInitializer实现们: DelegatingApplicationContextInitializer 使用环境属性context.initializer.classes指定的初始化器(initializers)进行初始化工作,如果没有指定则什么都不做。通过它使得我们可以把自定义实现类配置在application.properties里成为了可能。 ContextIdApplicationContextInitializer 设置Spring应用上下文的ID,会参照环境属性。至于Id设置为啥值会参考环境属性: spring.application.name vcap.application.name spring.config.name spring.application.index vcap.application.instance_index 如果这些属性都没有,ID使用application。 ConfigurationWarningsApplicationContextInitializer 对于一般配置错误在日志中作出警告 ServerPortInfoApplicationContextInitializer 将内置servlet容器实际使用的监听端口写入到Environment环境属性中。这样属性local.server.port就可以直接通过@Value注入到测试中,或者通过环境属性Environment获取。 SharedMetadataReaderFactoryContextInitializer 创建一个SpringBoot和ConfigurationClassPostProcessor共用的CachingMetadataReaderFactory对象。实现类为:ConcurrentReferenceCachingMetadataReaderFactory ConditionEvaluationReportLoggingListener 将ConditionEvaluationReport写入日志。

自定义实现示例

public class FirstInitializer implements ApplicationContextInitializer {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();

        Map<String, Object> map = new HashMap<>();
        map.put("key1", "First");

        MapPropertySource mapPropertySource = new MapPropertySource("firstInitializer", map);
        environment.getPropertySources().addLast(mapPropertySource);

        System.out.println("run firstInitializer");
    }

}

三种添加方式: 1.在 main函数中编程方式添加

@SpringBootApplication
public class SpringbootApplication {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(SpringbootApplication.class);
        springApplication.addInitializers(new FirstInitializer());
        springApplication.run();
    }

}

2.在application.properties配置

context.initializer.classes=com.learn.springboot.initializer.FirstInitializer

3.SPI扩展方式,在resources/META-INF/spring.factories 中配置

org.springframework.context.ApplicationContextInitializer=com.learn.springboot.initializer.FirstInitializer

更多信息请移步Spring专栏:www.yuque.com/mrhuang-ire…

参考: [1].www.cnblogs.com/duanxz/p/11… [2].zhuanlan.zhihu.com/p/650183190

posted @ 2023-10-12 10:07  扎Zn了老Fe  阅读(25)  评论(0编辑  收藏  举报  来源