【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)是一…...
N_m3u8DL-CLI-SimpleG:解决M3U8流媒体下载难题的开源解决方案
N_m3u8DL-CLI-SimpleG:解决M3U8流媒体下载难题的开源解决方案 【免费下载链接】N_m3u8DL-CLI-SimpleG N_m3u8DL-CLIs simple GUI 项目地址: https://gitcode.com/gh_mirrors/nm3/N_m3u8DL-CLI-SimpleG M3U8流媒体格式已成为在线视频传输的主流标准࿰…...
DataQA数问增长:金融小贷行业的“智能风控大脑“实战揭秘
数问"Web渠道转化率仅0.2,欺诈风险高、客户资质差——你的渠道投放预算,有多少正在打水漂?" 💡 真实场景还原:某头部消费金融公司的渠道危机 时间:2026年3月,周一上午9:00 角色&…...
大多数人手动给Agent加记忆 Meta HyperAgents却让AI自己发明了完整记忆系统
你是不是也这样造Agent:先搭好任务执行模块,再手动塞一个向量数据库或RAG当记忆,最后发现跨轮迭代时效果还是“每次从零开始”?性能没 compounding,跨任务迁移更是一团乱麻。明明AI已经能自我迭代了,为什么…...
Phi-4-mini-reasoning步骤详解:supervisorctl管理服务全命令解析
Phi-4-mini-reasoning步骤详解:supervisorctl管理服务全命令解析 1. 项目介绍 Phi-4-mini-reasoning是一款由微软开发的3.8B参数轻量级开源模型,专为数学推理、逻辑推导和多步解题等强逻辑任务设计。该模型主打"小参数、强推理、长上下文、低延迟…...
当openclaw遇见ai:借助快马平台打造能理解内容的智能抓取命令
最近在开发一个叫openclaw的网页抓取工具时,发现单纯抓取网页内容已经不能满足需求了。很多时候我们需要对抓取的内容进行二次处理,比如自动摘要、分类、去噪等。这时候就想到了借助AI来增强工具的能力,正好发现了InsCode(快马)平台这个好帮手…...
Stable Diffusion 2.0超分实战:4倍放大图片还能保持清晰度的秘密
Stable Diffusion 2.0超分实战:4倍放大图片还能保持清晰度的秘密 在数字图像处理领域,超分辨率技术一直是设计师和开发者关注的焦点。传统放大方法往往导致图像模糊、细节丢失,而基于深度学习的超分方案正在改变这一局面。Stable Diffusion 2…...
SmallThinker-3B-Preview赋能Java后端:智能客服系统数据库设计
SmallThinker-3B-Preview赋能Java后端:智能客服系统数据库设计 最近在做一个Java后端的智能客服项目,核心是要接入一个轻量级的AI模型——SmallThinker-3B-Preview。模型选好了,代码逻辑也搭得差不多了,但一到数据库设计这块&…...
工业以太网双雄:从协议原理到选型落地,EtherCAT与PROFINET实战解析
1. 工业以太网的双雄之争:为什么选型这么难? 第一次接触工业以太网协议选型时,我盯着EtherCAT和PROFINET的参数表发呆了整整一上午。就像面对两个各有所长的武林高手,一个轻功了得,一个内力深厚,实在难以抉…...
Qwen3.5-2B镜像免配置部署:开箱即用WebUI(7860端口)快速上手教程
Qwen3.5-2B镜像免配置部署:开箱即用WebUI(7860端口)快速上手教程 1. 模型简介 Qwen3.5-2B是通义千问系列中的轻量化多模态基础模型,仅有20亿参数规模,专为低功耗、低门槛部署场景设计。这个版本特别适合在端侧设备和…...
Axelspace 太空公司牵头联合体入选日本太空战略基金项目 “提升下一代地球观测卫星能力技术”
—— 通过卫星星座与航空器开展特定排放源二氧化碳排放与吸收监测,打造气候解决方案,开拓全新市场机遇 Axelspace 太空公司、明星电气株式会社、全日空控股株式会社及 JIJ 株式会社联合宣布,各方共同申报的技术研发项目成功入选日本宇宙航空…...
