详解Spring Framework提供的扩展点:ApplicationContextInitializer应用上下文初始化器,以及它在SpringBoot中的应用【享学Spring】(下)

简介: 详解Spring Framework提供的扩展点:ApplicationContextInitializer应用上下文初始化器,以及它在SpringBoot中的应用【享学Spring】(下)

SpringBoot中ApplicationContextInitializer的使用


思考良久,最终还是决定把该初始化器在SpringBoot中的应用也在此处一并说明了(毕竟这块的使用还是比较简单的,所以放一起吧)


熟悉SpringBoot的小伙伴应该知道:它里面大量的使用到了Spring容器上下文启动的相关回调机制:比如SPI、事件/监听、启动器等等。


ApplicationContextInitializer是在springboot启动过程(refresh方法前)调用。提取部分源码参考如下:

public class SpringApplication {
  // 对象初始化的时候 会从spring.factories里拿出来
  private void initialize(Object[] sources) {
    ...
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    ...
  }
  public ConfigurableApplicationContext run(String... args) {
    ...
      prepareContext(context, environment, listeners, applicationArguments, printedBanner);
    ...
  }
  private void prepareContext(ConfigurableApplicationContext context,
      ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
      ApplicationArguments applicationArguments, Banner printedBanner) {
    ...
    applyInitializers(context);
    ...
  }
  // 执行处  把所有的遍历执行(已经排序)getInitializers里会根据order进行排序
  protected void applyInitializers(ConfigurableApplicationContext context) {
    for (ApplicationContextInitializer initializer : getInitializers()) {
      Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(
          initializer.getClass(), ApplicationContextInitializer.class);
      Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
      initializer.initialize(context);
    }
  }
}


了解了SpringBoot加载、执行ApplicationContextInitializer的过程,就可以很容易总结出在SpringBoot中自定义使用ApplicationContextInitializer的三种方式:


请注意在SpringBoot中自定义和在Spring Framework中自定义的步骤区别~


SpringBoot中自定义ApplicationContextInitializer的三种方式

spring.factories方式(官方就是这么用的,推荐)


不解释


application.properties添加配置方式

对于这种方式是通过DelegatingApplicationContextInitializer这个初始化类中的initialize方法获取到application.properties中的context.initializer.classes实现类的


所以只需要将实现了ApplicationContextInitializer的类添加到application.properties即可。示例如下:

context.initializer.classes=你的实现类全类名


API方式addInitializers()方法添加


形如:

  public static void main(String[] args) {
    //type01
    SpringApplication springApplication = new SpringApplication(Application.class);
    // 添加进去
    springApplication.addInitializers(new Demo01ApplicationContextInitializer());
    springApplication.run(args);
    //SpringApplication.run(InitializerDemoApplication.class,args);
  }


虽然三种方式都可以,但个人比较推荐的方式为通过spring.factories方式配置


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写入日志。


以上都是SpringBoot内置的上文启动器,可见Spring留出的这个钩子,被SpringBoot发扬光大了。

实际上不仅于此,SpringBoot对Spring Framework的事件监听机制也都有大量的应用~


总结


ApplicationContextInitializer是Spring留出来允许我们在上下文刷新之前做自定义操作的钩子,若我们有需求想要深度整合Spring上下文,借助它不乏是一个非常好的实现。


随便浏览一下SpringBoot的源码可知,它对Spring特征特性的使用,均是非常的流畅且深度整合的。所以说SpringBoot易学难精的最大拦路虎:其实是对Spring Framework系统性的把握~


Tips:spring-test包里有个注解org.springframework.test.context.ContextConfiguration它有个属性可以指定ApplicationContextInitializer辅助集成测试时候的自定义对上下文进行预处理~

相关文章
|
7天前
|
人工智能 Java API
Spring AI与DeepSeek实战一:快速打造智能对话应用
在 AI 技术蓬勃发展的今天,国产大模型DeepSeek凭借其低成本高性能的特点,成为企业智能化转型的热门选择。而Spring AI作为 Java 生态的 AI 集成框架,通过统一API、简化配置等特性,让开发者无需深入底层即可快速调用各类 AI 服务。本文将手把手教你通过spring-ai集成DeepSeek接口实现普通对话与流式对话功能,助力你的Java应用轻松接入 AI 能力!虽然通过Spring AI能够快速完成DeepSeek大模型与。
203 11
|
8天前
|
人工智能 Java API
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
|
10天前
|
人工智能 Java API
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
|
10天前
|
存储 人工智能 开发框架
Spring AI Alibaba 应用框架挑战赛圆满落幕,恭喜获奖选手
Spring AI Alibaba 应用框架挑战赛圆满落幕,恭喜获奖选手
|
12天前
|
存储 人工智能 开发框架
Spring AI Alibaba 应用框架挑战赛圆满落幕,恭喜获奖选手
第二届开放原子大赛 Spring AI Alibaba 应用框架挑战赛决赛于 2 月 23 日在北京圆满落幕。
|
13天前
|
人工智能 Java API
Java也能快速搭建AI应用?一文带你玩转Spring AI可落地性
Java语言凭借其成熟的生态与解决方案,特别是通过 Spring AI 框架,正迅速成为 AI 应用开发的新选择。本文将探讨如何利用 Spring AI Alibaba 构建在线聊天 AI 应用,并实现对其性能的全面可观测性。
|
3月前
|
人工智能 前端开发 Java
Spring AI Alibaba + 通义千问,开发AI应用如此简单!!!
本文介绍了如何使用Spring AI Alibaba开发一个简单的AI对话应用。通过引入`spring-ai-alibaba-starter`依赖和配置API密钥,结合Spring Boot项目,只需几行代码即可实现与AI模型的交互。具体步骤包括创建Spring Boot项目、编写Controller处理对话请求以及前端页面展示对话内容。此外,文章还介绍了如何通过添加对话记忆功能,使AI能够理解上下文并进行连贯对话。最后,总结了Spring AI为Java开发者带来的便利,简化了AI应用的开发流程。
2022 0
|
3月前
|
XML 前端开发 安全
Spring MVC:深入理解与应用实践
Spring MVC是Spring框架提供的一个用于构建Web应用程序的Model-View-Controller(MVC)实现。它通过分离业务逻辑、数据、显示来组织代码,使得Web应用程序的开发变得更加简洁和高效。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring MVC,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
158 2
|
3月前
|
XML Java 数据格式
Spring Core核心类库的功能与应用实践分析
【12月更文挑战第1天】大家好,今天我们来聊聊Spring Core这个强大的核心类库。Spring Core作为Spring框架的基础,提供了控制反转(IOC)和依赖注入(DI)等核心功能,以及企业级功能,如JNDI和定时任务等。通过本文,我们将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring Core,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
80 14
|
4月前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
101 1

热门文章

最新文章