前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot 的启动扩展点 ApplicationContextInitializer

SpringBoot 的启动扩展点 ApplicationContextInitializer

作者头像
用户3147702
发布2022-09-23 08:32:01
5600
发布2022-09-23 08:32:01
举报

1. 引言

此前的文章中,我们详细介绍了 Spring 预留的六个可以用来扩展代码的扩展点,从而让我们能够在 Spring 的启动阶段添加我们需要的业务启动代码:

添加 SpringBoot 自定义启动代码的六种方式(上)

添加 SpringBoot 自定义启动代码的六种方式(下)

事实上,Spring 的扩展点还有很多,只是通常如果我们仅仅是添加业务启动代码,或是对运行参数进行初始化解析,使用上述六个扩展点就已经可以满足需求。

但是,如果我们想要从根本上改变一些 Spring 的默认行为,例如修改 Context 中的属性,或者要改变 bean 的创建加载行为,这时,我们就必须在 SpringBoot 生命周期的最早期进行扩展。

SpringBoot 为我们预留了这样的扩展点,它就是本文将要介绍的 ApplicationContextInitializer。

2. ApplicationContextInitializer

SpringBoot 在 Spring 的基础上,遵循约定大于配置原则,加入了许许多多自动装配的机制。让我们在给别人提供组件时,只需要按照 SpringBoot 的规范实现我们自己的扩展,别人无需任何配置就可以自动装配我们的组件。ApplicationContextInitializer 就是可以被这样自动装配的扩展点。

SpringBoot 会在完成 ConfigurableApplicationContext 的构建后,在容器刷新之前,自动调用已经被装配进 SpringBoot 容器的 ApplicationContextInitializer 接口实现类,执行它的 initialize 方法。

ApplicationContextInitializer 接口的定义如下:

如果这个接口有多个实现类,SpringBoot 支持通过 @Order 注解或实现 Ordered 接口指定每个实现类的执行优先级。

3. 添加启动的三种方式

如果我们实现了上述 ApplicationContextInitializer 接口,如何将我们的实现类添加到 SpringBoot 的启动中呢?有三种方法。

3.1 在 main 方法中调用

通过 SpringApplication 对象的 addInitializers 方法,可以添加多个 ApplicationContextInitializer 实现类:

3.2 在 classpath 下的配置文件中配置

SpringBoot 启动时,会扫描 classpath,寻找 application.properties 配置,来找到启动过程中需要调用的相关组件。

在这个配置文件中,加入 ApplicationContextInitializer 实现类的配置,就可以实现让 SpringBoot 自动加载该实现类。

3.3 SpringBoot 的 SPI 扩展 -- META-INF/spring.factories 中配置

在 classpath 下的 META-INF/spring.factories 中配置相应的实现类也同样可以配置 ApplicationContextInitializer 实现类的自动加载和启动:

4. 实例:利用 ApplicationContextInitializer 实现 bean 的手动加载

在 SpringBoot 中,创建 bean 有多种方法:

  1. 通过 xml bean 标签描述的方法;
  2. @Bean 注解的方法;
  3. 通过 @Component、@Service、@Controler、@Repository 注解的类;
  4. 通过 @Import 注解;
  5. 实现 ImportSelector、ImportBeanDefinitionRegistrar、EnableImportSelector 接口;
  6. 通过 beanFactory 手动注入。

这些方式我们已经很熟悉了,但有时,我们希望完全自己构造出一个 bean 对象,并且由于它受到其它 bean 的依赖,需要在启动最初的阶段被加载到 SpringBoot 的上下文环境中,这时,通过 ApplicationContextInitializer 来实现就是一个很好的选择。

下面的例子展示了通过 ApplicationContextInitializer 的实现类创建 bean:

在这个例子中,调用了回调参数 GenericApplicationContext 对象的 registerBean 方法,指定了 bean 的 name、类型、对象以及 bean 属性。

值得提的是第四个参数,该参数是可选的,它是用来指定 bean 属性的 BeanDefinitionCustomizer 接口实现。

当然了,这只是一个例子,除此以外,ApplicationContextInitializer 还有多种用途,例如将 beanFactory 替换成你自己实现的对象,来实现你想要的独特的 bean 加载方式等等。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 引言
  • 2. ApplicationContextInitializer
  • 3. 添加启动的三种方式
    • 3.1 在 main 方法中调用
      • 3.2 在 classpath 下的配置文件中配置
        • 3.3 SpringBoot 的 SPI 扩展 -- META-INF/spring.factories 中配置
        • 4. 实例:利用 ApplicationContextInitializer 实现 bean 的手动加载
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档