墨风如雪博客

  • 源码小店
  • 传家宝VPS
让AI使用变得如此简单
  1. 首页
  2. java
  3. spring
  4. 正文

SpringBoot扩展点之ApplicationContextInitializer

2023年 5月 3日 342点热度 1人点赞 0条评论

前言

提到Spring、Springoboot,很多人马上就会想到依赖注入、控制反转、自动装配、约定大于配置、使开发变得简单等等。但是如果仅仅会使用Springboot、SpringMVC完成一些增删改查,解决一些bug,那么实际上你并没有真的懂Spring、Springboot。Spring的核心是容器,Springboot更是封装了Spring,把复杂隐藏在内部,让其在使用上更简单,同时又预留了很多的扩展。所以我认为学会Springboot的简单使用只是一个开始,对业务开发更有参考和学习意义的是Springboot如何把复杂变得简单、预留的扩展接口又是如何使用的。

在 Spring Boot 中,我们可以通过实现 ApplicationContextInitializer 接口来扩展 Spring Boot 应用程序的上下文初始化过程。该接口提供了初始化 Spring 应用程序上下文之前的回调方法,可以在应用程序上下文的构建过程中对其进行某些自定义行为。

下面是 ApplicationContextInitializer 接口的定义:

public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {

    void initialize(C applicationContext);

}
  • 当 Spring Boot 应用程序的 ApplicationContext 被创建之后,将会通知所有实现了 ApplicationContextInitializer 接口的启动类都会执行其 initialize() 方法;
  • 接口有一个泛型形参 C 限制应用内容器类型,通常是 ConfigurableApplicationContext 的子类,如 GenericApplicationContext、AnnotationConfigApplicationContext 等;
  • 在 initialize() 方法中,我们可以自定义初始化过程,例如:添加自定义的 bean、配置属性、注册监听器、配置 profile 等。

下面介绍一下 ApplicationContextInitializer 接口常见的扩展点和其使用场景:

自定义配置文件路径

Spring Boot 默认的配置文件是 application.properties 或 application.yml。如果我们希望使用自定义的配置文件,可以通过 ApplicationContextInitializer 扩展点实现。

下面是一个示例,其自定义配置文件位置为 /opt/config/application.properties:

public class CustomInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        applicationContext.getEnvironment().getPropertySources()
                .addLast(new ResourcePropertySource("file:/opt/config/application.properties"));
    }
}

通过 applicationContext.getEnvironment().getPropertySources() 获取应用的环境变量,然后通过 addLast() 方法将自定义的配置文件注入到环境变量中。

要生效,我们需要在 SpringApplication 中将其注册:

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringBootApplication.class);
    app.addInitializers(new CustomInitializer());
    app.run(args);
}

激活 Profile

可以通过 initialize() 方法中加载自定义配置文件的方式,动态激活使用不同的 Profile。例如,在一台机器的不同环境下,使用不同的 Profile:

public class ProfileInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        Environment environment = applicationContext.getEnvironment();
        String activeProfiles = environment.getProperty("spring.profiles.active");
        if (StringUtils.isEmpty(activeProfiles)) {
            // 默认使用 test 环境配置
            environment.setActiveProfiles("test");
        }
    }
}

添加额外的 Bean

在 initialize() 方法中也可以注册额外的 Bean。例如,向应用程序上下文中添加自定义的 HelloService Bean。

public class BeanInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        BeanDefinitionRegistry beanDefinitionRegistry =
                (BeanDefinitionRegistry) applicationContext.getBeanFactory();
        RootBeanDefinition beanDefinition = new RootBeanDefinition(HelloService.class);
        beanDefinitionRegistry.registerBeanDefinition("helloService", beanDefinition);
    }
}

首先,获取应用程序上下文中的 BeanDefinitionRegistry。然后创建一个 RootBeanDefinition 实例化 HelloService 并将其注册到应用程序上下文。

最后,我们需要将它们注册到主应用程序中:

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringBootApplication.class);
    app.addInitializers(new BeanInitializer());
    app.run(args);
}

综上所述,通过 ApplicationContextInitializer 接口,我们可以轻松地扩展 Spring Boot 应用程序的上下文初始化过程。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: ApplicationContextInitializer springboot 扩展
最后更新:2023年 5月 3日

墨风如雪

一个热爱生活,热爱分享的程序员

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

墨风如雪

一个热爱生活,热爱分享的程序员

最新 热点 随机
最新 热点 随机
Kimi K2.5开源:自带百人众包团队,月之暗面重新定义生产力 告别修图软件的图层噩梦,腾讯混元3.0让AI学会了“思考” 参数仅100亿却硬刚千亿巨头:阶跃星辰Step3-VL-10B凭什么封神? 腾讯CodeBuddy 2.0:从“副驾驶”到“全栈合伙人”的进化 97毫秒极致响应!Qwen3-TTS开源,重新定义语音生成的“速度与激情” 2026开年王炸:文心5.0带着2.4万亿参数和原生全模态来了
仅需1GB内存!腾讯混元MT1.5开源,让手机翻译彻底告别云端依赖十天谈下二十亿美金:Meta豪掷千金买下的中国AI天才,到底凭什么?智谱ZCode上手:把Claude和Gemini装进桌面,编程还能这么玩?告别延迟!通义开源Fun-Audio-Chat,这才是我们要的语音AI这可能是最懂人话的AI:阿里MAI-UI让手机自动驾驶成真DeepSeek新年炸场:给失控的AI模型装上数学红绿灯
2026开年王炸:文心5.0带着2.4万亿参数和原生全模态来了 Docker 常见的命令和常见问题集合(超详细) JAVA基础 IO流详解 claude 3.7 sonnet 原型图平替,DeepSeek原型图开发指南 如何使用Java原子类实现自旋锁和读写锁? 每日一道算法题:插入排序算法
标签聚合
大模型 deepseek java 教程 算法 设计模式 AI spring

COPYRIGHT © 2023 墨风如雪博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang