玩转SpringBoot:动态排除Starter配置,轻松部署

引言

在软件开发中,进行本地单元测试是一项常规且必要的任务。然而,在进行单元测试时,有时需要启动一些中间件服务,如Kafka、Elasticjob等。举例来说,我曾经遇到过一个问题:项目中使用了Redisson锁,但由于Redisson版本较低,在Mac环境下偶尔会报错# RedisConnectionException: Unable to init enough connections amount。鉴于升级版本带来的风险,以及问题仅在本地启动时出现,我决定在本地环境中排除Redisson的Starter,从而避免影响其他环境的配置。那么,我们应该如何做呢?

我们以上篇介绍如何自定义Starter中的文章中示例CoderAcademyStarter为例。我们引入了这个starter。

Starter自动配置类的排除

在《SpringBoot如何自定义Starter》中,我们介绍了如何在META-INF/spring.factories文件中使用org.springframework.boot.autoconfigure.EnableAutoConfiguration来指定Starter的自动配置类。Spring Boot启动时会扫描所有已引入jar包中的spring.factories文件,并根据EnableAutoConfiguration键下的类来加载和执行相应的自动配置逻辑。当我们不希望应用启动时使用该Starter的功能时,就需要排除自动配置类。

我们可以通过spring.autoconfigure.exclude属性排除CoderAcademyStarter的自动配置类:

spring.autoconfigure.exclude=com.springboot.starter.coderacademy.config.CoderAcademyAutoConfig

spring.autoconfigure.exclude是Spring Boot中的一个属性,用于指定在自动配置过程中要排除的自动配置类。通过设置该属性,我们可以明确告知Spring Boot不要自动配置指定的类,即使它们满足自动配置的条件。当需要禁用特定的自动配置类时,可以在application.propertiesapplication.yml中设置spring.autoconfigure.exclude属性,并提供要排除的自动配置类的完全限定类名。这样,Spring Boot在自动配置过程中将不会考虑这些类。

此时,如果我们在使用CoderAcademyService时会出现错误:

image.png

根据不同环境排除Starter自动配置类

在日常开发中,我们通常需要针对不同的环境指定不同的配置。我们可以通过spring.actice.profiles属性来指定不同环境的配置文件的加载。例如,我们可以在本地指定spring.actice.profiles=local,然后创建一个application-local.properties的配置文件,在其中指定spring.autoconfigure.exclude

另外,我们还可以实现ApplicationListener<ApplicationContextInitializedEvent>接口,通过监听上下文初始化事件来根据环境变量的标识排除Starter的自动配置类。当Spring应用程序的ApplicationContext被初始化时,将触发ApplicationContextInitializedEvent事件。通常,在应用程序的上下文初始化过程中会先加载bean定义、执行后处理器等操作。因此,通过监听ApplicationContextInitializedEvent事件,我们可以在Spring容器初始化的早期阶段执行一些定制化的逻辑。

我们可以通过实现ApplicationListener<ApplicationContextInitializedEvent>接口,根据一些环境变量的标识排除Starter的自动配置类。例如,我们可以定义一个coderacademy.enable的标识来决定是否扫描Starter。以下是一个示例:

import org.springframework.boot.context.event.ApplicationContextInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;

@Configuration
public class EnvironmentHandler implements ApplicationListener<ApplicationContextInitializedEvent> {

    @Override
    public void onApplicationEvent(ApplicationContextInitializedEvent event) {
        ConfigurableEnvironment environment = event.getApplicationContext().getEnvironment();
        if (environment.getProperty("coderacademy.enable") != null && "false".equals(environment.getProperty("coderacademy.enable"))) {
            System.setProperty("spring.autoconfigure.exclude", "com.springboot.starter.coderacademy.config.CoderAcademyAutoConfig");
        }
    }
}

然后,在启动应用时,通过-Dcoderacademy.enable=false指定排除Starter的自动配置类。这种方式特别适用于本地启动应用时排除Starter或其他Bean的初始化。

当然本地启动也可以直接通过-Dspring.autoconfigure.exclude=com.springboot.starter.coderacademy.config.CoderAcademyAutoConfig也可以满足排除Starter的配置。

自定义Starter Bean排除

在《SpringBoot如何自定义Starter》文中,我们还提到了一种调用方使用Starter的方式,我们可以不是用自动配置类的Starter,可以自定义配置的信息,在手动创建Starter对应的服务的Bean。例如:

@Data
@Configuration
public class StarterConfig {

    @Value("${springboot.coderacademy.name}")
    private String staterMsg;

    @Bean
    public CoderAcademyService coderAcademyService(){
        CoderAcademyConfig coderAcademyConfig = new CoderAcademyConfig();
        coderAcademyConfig.setUrl(staterMsg);
        return new CoderAcademyService(coderAcademyConfig);
    }
}

对于这种情况,我们可以使用Spring Boot的注解@ConditionalOnProperty来控制是否创建Bean。@ConditionalOnProperty是一个条件注解,根据配置属性的值来决定是否应该创建一个Bean或应用某个配置。具体来说,@ConditionalOnPropertyname属性表示配置属性的名称,havingValue属性表示配置属性的期望值,默认为truematchIfMissing属性表示当配置属性不存在时是否匹配条件,默认为false

因此,我们可以给CoderAcademyService的Bean添加@ConditionalOnProperty注解:

@Data
@Configuration
public class StarterConfig {

    @Value("${springboot.coderacademy.name}")
    private String staterMsg;

    @ConditionalOnProperty(name = "coderacademy.enable", havingValue = "true", matchIfMissing = true)
    @Bean
    public CoderAcademyService coderAcademyService(){
        CoderAcademyConfig coderAcademyConfig = new CoderAcademyConfig();
        coderAcademyConfig.setUrl(staterMsg);
        return new CoderAcademyService(coderAcademyConfig);
    }
}

这样,我们在启动应用时可以通过-Dcoderacademy.enable=false变量来控制是否创建CoderAcademyService,而设置了matchIfMissing=true,即使其他环境没有该环境变量也不受影响。

除了@ConditionalOnProperty之外,Spring Boot还提供了其他一些条件注解,用于根据不同的条件来决定是否应该创建Bean或者是否应该应用某个配置。一些常见的条件注解包括:

  1. @ConditionalOnClass:当类路径中存在指定的类时,才会创建Bean或应用配置。
  2. @ConditionalOnMissingClass:当类路径中不存在指定的类时,才会创建Bean或应用配置。
  3. @ConditionalOnBean:当容器中存在指定的Bean时,才会创建Bean或应用配置。
  4. @ConditionalOnMissingBean:当容器中不存在指定的Bean时,才会创建Bean或应用配置。
  5. @ConditionalOnExpression:当满足SpEL表达式定义的条件时,才会创建Bean或应用配置。
  6. @ConditionalOnJava:当JVM运行的Java版本符合指定条件时,才会创建Bean或应用配置。
  7. @ConditionalOnWebApplication:当运行的环境是Web应用程序时,才会创建Bean或应用配置。
  8. @ConditionalOnNotWebApplication:当运行的环境不是Web应用程序时,才会创建Bean或应用配置。

总结

本文介绍了在Spring Boot项目中如何排除Starter自动配置类,以及根据不同环境动态排除配置的方法。通过spring.autoconfigure.exclude属性和条件注解如@ConditionalOnProperty,我们可以灵活控制Bean的创建和配置的应用,从而更好地适应不同的部署环境和需求。

本文已收录于我的个人博客:码农Academy的博客,专注分享Java技术干货,包括Java基础、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中间件、架构设计、面试题、程序员攻略等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/426989.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

试手一下CameraX(APP)

书接上回。 首先还是看谷歌的官方文档&#xff1a; https://developer.android.com/media/camera/camerax?hlzh-cn https://developer.android.com/codelabs/camerax-getting-started?hlzh-cn#1 注&#xff1a;这里大部分内容也来自谷歌文档。 官方文档用的是Kotlin&…

JavaWeb之 创建 Web项目,使用Tomcat 部署项目,使用 Maven 构建Web项目(一万八千字详解)

目录 前言3.1 Tomcat 简介3.1.1 什么是 Web服务器3.1.2 Tomcat 是什么3.1.3 小结 3.2 Tomcat 的基本使用3.2.1 下载 Tomcat3.2.2 安装 Tomcat3.2.3 卸载 Tomcat3.2.4 启动 Tomcat3.2.5 关闭 Tomcat3.2.6 配置 Tomcat3.2.7 在 Tomcat 中部署 Web项目 3.3 在 IDEA 中创建 Web 项目…

探索前景:机器学习中常见优化算法的比较分析

目录 一、介绍 二、技术背景 三、相关代码 四、结论 一、介绍 优化算法在机器学习和深度学习中至关重要&#xff0c;可以最小化损失函数&#xff0c;从而改善模型的预测。每个优化器都有其独特的方法来导航损失函数的复杂环境以找到最小值。本文探讨了一些最常见的优化算法&…

Python爬虫——解析常用三大方式之JsonPath

目录 JsonPath 安装 使用 我们的json数据 基本使用 案例 总结 JsonPath 主要适用于解析一些json的数据 安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ jsonpath 使用 obj json.load(open( json文件 , r , encoding utf-8 ) )ret jsonpath.…

一些C语言知识

C语言的内置类型&#xff1a; char short int long float double C99中引入了bool类型&#xff0c;用来表示真假的变量类型&#xff0c;包含true&#xff0c;false。 这个代码的执行结果是什么&#xff1f;好好想想哦&#xff0c;坑挺多的。 #include <stdio.h>int mai…

EdgeX Foundry 安全模式安装部署

文章目录 一、安装准备1.官方文档2. 克隆服务器3.安装 Docker4.安装 docker-compose 二、安装部署1.docker-comepse2.启动 EdgeX Foundry3.访问 UI3.1. consul3.2. EdgeX Console EdgeX Foundry # EdgeX Foundryhttps://iothub.org.cn/docs/edgex/ https://iothub.org.cn/docs…

机器学习|KNN和Kmeans

KNN和Kmeans KNN KNN-K个最近的邻居&#xff0c;而K是可人先预设出来的。 所谓近朱者赤&#xff0c;近墨者黑。 可以选取离当前最近的K个样本来作为辅助判断&#xff0c;因为本样本和最近的K个样本应该是处于一种相似的状态。 以下是一个苹果和梨的识别任务。 图上会出现一个未…

立式学习灯值得买吗?五款立式学习灯真实测评

现在人们注重健康生活&#xff0c;特别是在面对目前青少年严峻的近视情况&#xff0c;大路灯作为补充光线的照明电器&#xff0c;在市场热度持续高涨&#xff0c;但其负面评价也屡见不鲜。有人反映使用后眼睛更容易疲劳、酸疼等不适症状。作为一名专业测评师&#xff0c;我提醒…

pdf编辑软件哪个好用?5款PDF编辑器分享

pdf编辑软件哪个好用&#xff1f;PDF编辑软件在现代办公和学术研究中发挥着举足轻重的作用&#xff0c;它们不仅具备基础的编辑和修改功能&#xff0c;还能够支持多种注释工具&#xff0c;帮助我们高效地管理和整理PDF文件。无论是需要调整文档布局、添加文本或图像&#xff0c…

Linux系统——LNMP架构

目录 一、LNMP架构定义 1.LNMP定义 1.1LNMP工作原理 2.FASTCGI 2.1CGI的由来 2.2为什么会有FastCGI 3.PHP 3.1什么是PHP-FPM 3.2PHP配置 3.1.1对配置文件的修改生效方法 3.1.2/etc/php.ini配置文件格式 3.1.3注释符&#xff1a; 3.1.4php.ini配置参考文档 3.1.5…

【Linux取经路】文件系统——inode与软硬链接

文章目录 一、前言二、认识硬件——磁盘2.1 磁盘的存储构成2.2 磁盘的逻辑抽象 三、操作系统对磁盘的使用3.1 再来理解创建文件3.2 再来理解删除文件3.3 再来理解目录 四、硬链接五、软链接六、结语 一、前言 在之前的【Linux取经路】文件系统之被打开的文件——文件描述符的引…

自动驾驶加速落地,激光雷达放量可期(上)

1 激光雷达应用广泛&#xff0c;汽车有望成最大催化 激光雷达&#xff08;LiDAR&#xff09;是一种主动遥感技术&#xff0c;通过测定传感器发出的激光在传感器与目标物体之间的传播距离&#xff0c;来分析目标地物表面的反射能量大小、反射波谱的幅度、频率和相位等信息&#…

python基础使用之记录日志模块

我们在编写Python 程序时&#xff0c;记录日志信息是一种非常重要的需求&#xff0c;日志可以帮助调试和跟踪程序的执行过程。那么Python中提供了内置的logging模块&#xff0c;用于记录各种级别的日志信息。本文主要介绍Python日志信息输出的实现过程。 1. 导入 logging 模块…

C++入门全集(4):类与对象【下】

一、再谈构造函数 1.1 构造函数体内赋值 我们知道&#xff0c;在创建对象时&#xff0c;编译器会自动调用构造函数给对象中的各个成员变量一个合适的初始值 class Date { public:Date(int year, int month, int day){_year year;_month month;_day day;}private:int _yea…

开源项目:智能化图像分类技术在新能源发电监控中的应用与实践

一、引言 在当今世界&#xff0c;能源的转型和升级是推动社会可持续发展的关键因素。随着技术的进步&#xff0c;新能源发电逐渐成为能源结构调整的重要力量。在众多发电方式中&#xff0c;新能源发电技术如风力、太阳能等因其清洁、可再生的特性而备受青睐。然而&#xff0c;…

百度文库旋转验证码识别

最近研究了一下图像识别&#xff0c;一直找到很好的应用场景&#xff0c;今天我就发现可以用百度的旋转验证码来做一个实验。没想到效果还挺好&#xff0c;下面就是实际的识别效果。 1、效果演示 2、如何识别 2.1准备数据集 首先需要使用爬虫&#xff0c;对验证码图片进行采…

MATLAB中sigmoid函数用法

目录 语法 说明 示例 应用 sigmoid 激活 sigmoid函数的功能是应用sigmoid激活 语法 Y sigmoid(X) 说明 sigmoid 激活运算将 sigmoid 函数应用于输入数据。此运算等效于&#xff1a; 注意 此函数将 sigmoid 运算应用于 dlarray 数据。如果要在 layerGraph 对象或 Layer …

Git 版本控制

Git 版本控制 1. About Version Control (关于版本控制)1.1. Local Version Control Systems (本地版本控制系统)1.2. Centralized Version Control Systems (集中化的版本控制系统)1.3. Distributed Version Control Systems (分布式版本控制系统) 2. 换行符的处理3. keyboard…

深入理解Docker自定义网络:构建高效的容器网络环境

目录 博客前言: 一.docker自定义网络介绍 1.docker自定义网络介绍 2.使用技术的优势 3.基本使用流程 二.实战操作 1.模式理论介绍 bridge模式(默认模式) host模式 2.模式特点 查看桥接模式的特点 查看仅主机模式的特点 3.实战操作 bridge模式 host模式 自定义网络…

Android Compose - PlainTooltipBox(已废弃)的替代方案

Android Compose - PlainTooltipBox 的替代方案 TooltipBox(positionProvider TooltipDefaults.rememberPlainTooltipPositionProvider(),tooltip {PlainTooltip {Text(/* tooltip content */)}},state rememberTooltipState(), ) {// tooltip anchorIconButton(onClick {…