【Spring】多环境切换
🎈博客主页:🌈我的主页🌈
🎈欢迎点赞 👍 收藏 🌟留言 📝 欢迎讨论!👏
🎈本文由 【泠青沼~】 原创,首发于 CSDN🚩🚩🚩
🎈由于博主是在学小白一枚,难免会有错误,有任何问题欢迎评论区留言指出,感激不尽!🌠个人主页
目录
- 🌟 一、Java配置
- 🌟 二、XML配置
- 🌟 三、原理分析
- 🌟 三、自定义Profile
🌟 一、Java配置
首先创建一个 DataSource 类:
public class DataSource {private String username;private String password;private String url;@Overridepublic String toString() {return "DataSource{" +"username='" + username + '\'' +", password='" + password + '\'' +", url='" + url + '\'' +'}';}
}
向 Spring 容器中注册多个 DataSource,并且在注册的时候设置 Profile,只有当条件满足的时候,才向 Spring 容器中注册相应的 Bean,否则不注册
public class JavaConfig {@Bean@Profile("dev")DataSource devDataSource(){DataSource dev = new DataSource();dev.setUsername("dev");dev.setPassword("dev");dev.setUrl("jdbc:mysql:3306/dev");return dev;}@Bean@Profile("prod")DataSource prodDataSource(){DataSource prod = new DataSource();prod.setUsername("prod");prod.setPassword("prod");prod.setUrl("jdbc:mysql:3306/prod");return prod;}}
这里到底向 Spring 容器中注册多少个 DataSource,主要还是看条件是否满足,如果有多个条件满足,那么就注册多个 DataSource 实例到 Spring 容器中,否则就不注册。
最后,启动容器:
public static void main(String[] args) {//这里注意,不能添加配置类,如果添加了配置类,则 refresh 方法会被调用,而 Spring 容器的初始化则正是从这里开始的//此时,我们还没设置当前系统环境AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();//这里注意,不能添加配置类,如果添加了配置类,则 refresh 方法会被调用,而 Spring 容器的初始化则正是从这里开始的//此时,我们还没设置当前系统环境ConfigurableEnvironment evn = ctx.getEnvironment();evn.setActiveProfiles("prod");//此时再去设置配置类ctx.register(JavaConfig.class);//开始初始化容器ctx.refresh();DataSource dataSource = ctx.getBean(DataSource.class);System.out.println(dataSource);}
启动容器的时候,一开始不要传配置类进去,如果传了,则 refresh 方法会被自动调用,而此时我们还没设置容器的环境!所以,使用无参构造方法创建 AnnotationConfigApplicationContext 对象,然后设置系统环境,再去设置配置类,最后再去初始化容器
🌟 二、XML配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><beans profile="dev"><bean class="com.dong.demo3.DataSource" ><property name="username" value="dev"/><property name="password" value="dev"/><property name="url" value="jdbc:mysql:3306/dev"/></bean></beans><beans profile="prod"><bean class="com.dong.demo3.DataSource" ><property name="username" value="prod"/><property name="password" value="prod"/><property name="url" value="jdbc:mysql:3306/prod"/></bean></beans>
</beans>
这个是在 父标签 beans 中设置条件,满足对应的条件,父标签中的所有 Bean 才会被初始化
public class XMLDemo1 {public static void main(String[] args) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext();ctx.getEnvironment().addActiveProfile("prod");ctx.setConfigLocation("beans1.xml");ctx.refresh();DataSource bean = ctx.getBean(DataSource.class);System.out.println(bean);}
}
🌟 三、原理分析
@Profile
注解的定义就是一个组合注解:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 从这里可以看到,本质上就是一个条件注解,条件则是 ProfileCondition
@Conditional(ProfileCondition.class)
public @interface Profile {/*** The set of profiles for which the annotated component should be registered.*/String[] value();}
那我们来看下 ProfileCondition:
class ProfileCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// 这句话实际上就是查询到 Profile 注解的所有属性// 对于 Profile 注解来说,实际上就只有 value 属性// value->dev value->prodMultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());if (attrs != null) {// attrs.get("value") 表示读取属性中的 value 属性,value 属性的值是一个数组,所以这里需要遍历for (Object value : attrs.get("value")) {//判断当前系统环境中是否包含这个 valueif (context.getEnvironment().matchesProfiles((String[]) value)) {return true;}}return false;}return true;}}
🌟 三、自定义Profile
首先,先自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Conditional(MyCondition.class)
public @interface MyProfile {String[] value();
}
然后自定义条件,在自定义条件中解析注解:
public class MyCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(MyProfile.class.getName());if(attrs != null){List<Object> list = attrs.get("value");for (Object value : list) {boolean b = context.getEnvironment().acceptsProfiles(Profiles.of((String[]) value));if(b){return true;}}}return false;}
}
最后使用自定义注解:
public class JavaConfig {@Bean@MyProfile("dev")DataSource devDataSource(){DataSource dev = new DataSource();dev.setUsername("dev");dev.setPassword("dev");dev.setUrl("jdbc:mysql:3306/dev");return dev;}@Bean@MyProfile("prod")DataSource prodDataSource(){DataSource prod = new DataSource();prod.setUsername("prod");prod.setPassword("prod");prod.setUrl("jdbc:mysql:3306/prod");return prod;}}
启动容器:
public static void main(String[] args) {//这里注意,不能添加配置类,如果添加了配置类,则 refresh 方法会被调用,而 Spring 容器的初始化则正是从这里开始的//此时,我们还没设置当前系统环境AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();//这里注意,不能添加配置类,如果添加了配置类,则 refresh 方法会被调用,而 Spring 容器的初始化则正是从这里开始的//此时,我们还没设置当前系统环境ConfigurableEnvironment evn = ctx.getEnvironment();evn.setActiveProfiles("prod");//此时再去设置配置类ctx.register(JavaConfig.class);//开始初始化容器ctx.refresh();DataSource dataSource = ctx.getBean(DataSource.class);System.out.println(dataSource);}
相关文章:
【Spring】多环境切换
🎈博客主页:🌈我的主页🌈 🎈欢迎点赞 👍 收藏 🌟留言 📝 欢迎讨论!👏 🎈本文由 【泠青沼~】 原创,首发于 CSDN🚩…...
python经典百题之求10000之内的素数
题目:求10000之内的素数 程序分析 求10000之内的素数是一个常见的问题。素数是大于1且只能被1和自身整除的整数。我们可以使用循环遍历10000以内的每个数,判断其是否是素数。 方法1: 简单遍历法 遍历2到10000之间的每个数,判断其是否为素…...

ROS2 从头开始:第 5 部分 - 并发、执行器和回调组
一、说明 让我们回到基础。并发意味着系统或软件可以同时运行许多任务。例如,在单核 CPU 机器上,可以通过使用线程来实现并发。本文探讨了...

笔试强训Day3
学了一坤时Linux,赶紧来俩道题目放松放松。 T1:在字符串中找出连续最长的数字串 链接:在字符串中找出连续最长的数字串__牛客网 输入一个字符串,返回其最长的数字子串,以及其长度。若有多个最长的数字子串,…...

软考软件设计师-存储管理-文件管理-计算机网络(中
文章目录 一、存储管理页面置换算法 (最佳OPT)存储页面-先进先出置换算法(FIFO)最久未使用算法(最近最久未使用LRU) 二、文件管理初识文件管理文件目录-绝对路径文件管理-文件的结构文件管理-索引的分配 空闲存储空间的管理(位示图法)三、计算…...

Vue3的学习
create-vue创建vue3项目 create-vue是官方新的脚手架工具,底层切换到了vite(下一代构建工具),为开发提供急速响应 前提环境条件:控制面板输入node -v,显示的是安装了16.0或更高版本的Node.js创建一个Vue应…...

什么是Peppol ID?如何创建?
Peppol 网络的两大优势是安全和高效,由于Peppol 最常用于电子发票,因此这些优势在电子发票上展露无遗。相比之下,通过电子邮件发送 PDF 格式的发票和其他文件不仅处理成本较高,而且容易出现发票欺诈。 如果您所在的公共部门组织或…...
Spring注解大揭秘:@Component、@Service、@Repository详解
Spring注解大揭秘:Component、Service、Repository详解 前言比较 前言 想象一下,你正在构建一个复杂的Spring应用程序。你需要管理各种不同类型的组件,包括服务层、数据访问层和通用组件。Spring的Component、Service和Repository注解就像是你…...

Innodb底层原理与Mysql日志机制
MySQL内部组件结构 Server层 主要包括连接器、词法分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,…...
浅谈大数据背景下用户侧用电数据在电力系统的应用与发展分析
安科瑞 华楠 摘要:随着能源互联网、互联网、新型传感技术的持续推进,电力用户侧用电数据呈现指数级剧增、异构性增强的情况,逐渐构成了用户侧用电行为大数据。然而目前对电力领域的数据价值挖掘于电网内部和电源端,用户侧庞大且蕴…...

20230919在WIN10下使用python3将PDF文档转为DOCX格式的WORD文档
20230919在WIN10下使用python3将PDF文档转为DOCX格式的WORD文档 2023/9/19 11:20 python pdf word https://blog.csdn.net/u013185349/article/details/130059657 Python实现PDF转Word文档 AcceptedLin 已于 2023-04-10 14:45:17 修改 1243 收藏 1 文章标签: pd…...
PCR检测试剂——博迈伦
PCR(聚合酶链式反应)是一种常用的分子生物学技术,被广泛应用于基因分型、基因表达分析、病原体检测等领域。在PCR实验中,PCR检测试剂是必不可少的重要组成部分,它们包括引物、酶、缓冲液和核苷酸。 1. 引物(…...

spring一个项目多个模块聚合打包问题解决方案
文章目录 1.问题描述:2.解决方案一、创建聚合父工程二、创建子模块(module)三、编写子模块代码1.模块1(demo-one)2.模块2(demo-tow) 四、创建聚合模块 (demo-starter)1. …...
Linux设备树(Device Tree)何时被解析
Linux设备树(Device Tree)是在内核启动阶段就会被解析。当 Linux 内核启动的时候,它会读取设备树文件(dtb文件)并根据里面的信息来组织设备、加载驱动等。在驱动代码里,通常我们是在驱动初始化(…...
【Elasticsearch】数据简单操作(二)
简介:Elasticsearch(ES)是一个开源的分布式搜索和分析引擎,用于快速存储、搜索和分析大量数据。它具有高性能、可扩展性和灵活性的特点,被广泛用于构建实时搜索、日志分析、数据可视化等应用。 本文主要介绍ES索引的操…...

4 vCPU 实例达成 100 万 JSON API 请求/秒的优化实践
“性能工程” (Performance engineering)是个日渐流行的概念。顾名思义“性能工程”是包含在系统开发生命周期中所应用的一个技术分支,其目的就是确保满足非功能性的性能需求,例如:性能、可靠性等。由于现代软件系统变…...
呼叫中心系统有什么优势
在随着企业的管理水平也在不断提高。企业经营管理中所涉及到的各种复杂问题都有逐渐凸显出来。传统的呼叫中心已无法满足企业服务需求和客户满意度变化的要求。因此通过呼叫中心系统将企业业务流程和数据整合起来进行管理和运营已经成为目前企业管理领域中较为流行和成熟之选。…...

如何在linux操作系统下安装nvm
本文主要介绍如何在linux操作系统下安装nvm,如果想知道nvm如何在windows操作系统下使用,请参考文章如何通过nvm管理多个nodejs版本_nvm 查看所有node版本-CSDN博客。 1、nvm下载 nvm全称Node Version Manager,即Node版本管理器。访问官网地址…...

Linux 入门:基本指令
本篇文章来介绍我们在初学Linux时可以会碰倒的一些基本指令,让我们对这些指令有一个基本的了解。 目录 01. ls 指令 02. pwd 命令 03. cd 指令 04. touch 指令 05. mkdir 指令(重要) 06. rmdir指令 && rm 指令(重…...

IP转地理位置:探讨技术与应用
IP地址是互联网上设备的唯一标识符,而将IP地址转换为地理位置信息是网络管理、安全监控和市场定位等领域中的一项重要任务。本文将深入探讨IP转地理位置的技术原理和各种应用场景。 IP地址与地理位置 IP地址(Internet Protocol Address)是一…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...