墨风如雪博客

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

SpringBoot扩展点之ApplicationContextInitializer

2023年 5月 3日 418点热度 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日

墨风如雪

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

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

文章评论

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

墨风如雪

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

最新 热点 随机
最新 热点 随机
1美元雇佣顶级架构师?MiniMax M2.5要把Agent价格打穿 那个霸榜的Pony Alpha现身了:智谱GLM-5硬刚Claude Opus 纯国产算力硬刚GPT?聊聊刚发布的讯飞星火X2 阿里Qwen-Image-2.0实测:终于有一款能听懂人话、写对汉字的AI了 别再等Sora了,字节Seedance 2.0才是AI视频的“导演时刻” Mistral 掀桌子:40亿参数跑本地,Voxtral 2 把延迟压进了200毫秒
1美元雇佣顶级架构师?MiniMax M2.5要把Agent价格打穿
Docker 常见的命令和常见问题集合(超详细) Grok3暴打GPT-4o!马斯克的"火星AI"竟被小学数学题整破防? 单GPU秒产一分钟!MAI-Voice-1,微软语音AI的“核爆”时刻? MiniMax Speech 2.5:当AI学会了你的口音,世界再无语言障碍 微信抛出亿元算力包,小程序AI变现的最后一块拼图补齐了 打破次元壁垒!阿里Mnn3dAvatar让3D数字人触手可及
标签聚合
算法 设计模式 开源 教程 java 大模型 AI spring

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

Theme Kratos Made By Seaton Jiang