Spring系列(十一):@Profile 注解用法介绍

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 在Spring容器中如果存在同一类型的多个组件,可以使用@Profile注解标识实际要获取的是哪一个bean,这在不同的环境使用不同的变量的场景下非常有用。最典型的例子:开发环境、测试环境、生产环境会配置不同的数据源,在尽量不修改代码的情况下,可以使用这个注解来动态指定要连接的数据源。

今天给大家分享Spring属性注入的注解@Profile 介绍,希望对大家能有所帮助!

image_d504a09f.png

一、@Profile 注解的作用

在Spring容器中如果存在同一类型的多个组件,可以使用@Profile注解标识实际要获取的是哪一个bean,这在不同的环境使用不同的变量的场景下非常有用。

最典型的例子:开发环境、测试环境、生产环境会配置不同的数据源,在尽量不修改代码的情况下,可以使用这个注解来动态指定要连接的数据源。

二、@Profile 指定环境的方式

2.1 JVM启动参数

运行的时候给虚拟机参数位置增加 -Dspring.profiles.active=dev

2.2 通过代码方式控制:

  • 首先创建一个AnnotationConfigApplicationContext
  • 设置环境变量,指定要激活的环境
  • 注册配置类
  • 启动的时候刷新容器

三、@Profile 实现切换数据源示例

3.1 导入依赖

<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.44</version>
</dependency>

3.2 新建数据源配置文件dataSource.properties

dataSource.user=root
dataSource.password=123
dataDriveClassName=com.mysql.jdbc.Drive

3.3 新建TestProfileConfig.java 配置类

package com.spring.config;


import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.StringValueResolver;


import javax.sql.DataSource;
import java.beans.PropertyVetoException;


// 加载配置文件
@PropertySource("classpath:/dataSource.properties")
@Configuration
public class TestProfileConfig implements EmbeddedValueResolverAware {


    // 通过@Value注解获取配置文件dataSource.user的值
    @Value("${dataSource.user}")
    private String user;
    private StringValueResolver resolver;
    private String  dirveClassName;
    /**
     * 开发环境
     **/
    @Profile("dev")
    @Bean
    public DataSource dataSourceDev(@Value("${dataSource.password}") String pwd) throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(pwd);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev_db");
        dataSource.setDriverClass(dirveClassName);
        return dataSource;
    }
    /**
     * 测试环境
     **/
    @Profile("test")
    @Bean
    public DataSource dataSourceTest(@Value("${dataSource.password}") String pwd) throws PropertyVetoException{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(pwd);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test_db");
        dataSource.setDriverClass(dirveClassName);
        return dataSource;
    }
    /**
     * 生产环境
     **/
    @Profile("onLine")
    @Bean
    public DataSource dataSourceOnLine(@Value("${dataSource.password}") String pwd) throws PropertyVetoException{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(pwd);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/online_db");
        dataSource.setDriverClass(dirveClassName);
        return dataSource;
    }


    /**
     * 通过StringValueResolver解析dataDriveClassName的值
     **/
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        dirveClassName=resolver.resolveStringValue("${dataSource.dataDriveClassName}");
    }
}

3.4 新建测试类TestProfile.java

package com.spring.test;


import com.spring.config.TestProfileConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


import javax.sql.DataSource;


public class TestProfile {
    public static void main(String[] args) {


       /* 命令行动态参数:运行的时候给虚拟机参数位置增加 -Dspring.profiles.active=dev
        通过代码方式控制:
            1首先创建一个AnnotationConfigApplicationContext
            2 设置环境变量,指定要激活的环境
            3 注册配置类
            4启动的时候刷新容器
        */
        // 01  首先创建一个AnnotationConfigApplicationContext
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        //02  设置环境变量,指定要激活的环境 可以指定一个或者多个
        context.getEnvironment().setActiveProfiles("dev","onLine");
        //03  注册配置类
        context.register(TestProfileConfig.class);
        //04  启动刷新容器
        context.refresh();
        String[] names = context.getBeanNamesForType(DataSource.class);
        for (String name : names) {
            System.out.println(name);
        }
    }
}

输出结果:

dataSourceDev

dataSourceOnLine

四、使用总结

1、针对标注了环境标识的bean,只有在这个环境被激活的时候,才会注入到容器当中。默认是default环境。

2、如果@Profile 注解的位置在类上,相当于只有在指定该环境的情况下,整个配置类里面的配置才有机会生效。

3、针对没有标注环境表示的bean,在任何环境下都可以被正常加载。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
14天前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
97 26
|
17天前
|
缓存 Java 数据库
SpringBoot缓存注解使用
Spring Boot 提供了一套方便的缓存注解,用于简化缓存管理。通过 `@Cacheable`、`@CachePut`、`@CacheEvict` 和 `@Caching` 等注解,开发者可以轻松地实现方法级别的缓存操作,从而提升应用的性能和响应速度。合理使用这些注解可以大大减少数据库的访问频率,优化系统性能。
163 89
|
2月前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
181 73
|
4天前
|
监控 Java Spring
SpringBoot:SpringBoot通过注解监测Controller接口
本文详细介绍了如何通过Spring Boot注解监测Controller接口,包括自定义注解、AOP切面的创建和使用以及具体的示例代码。通过这种方式,可以方便地在Controller方法执行前后添加日志记录、性能监控和异常处理逻辑,而无需修改方法本身的代码。这种方法不仅提高了代码的可维护性,还增强了系统的监控能力。希望本文能帮助您更好地理解和应用Spring Boot中的注解监测技术。
33 16
|
2月前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
60 21
|
2月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
2月前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
9月前
|
Java API Spring
Spring容器如何使用一个注解来指定一个类型为配置类型
Spring容器如何使用一个注解来指定一个类型为配置类型
78 0
|
4月前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
68 0
|
8月前
|
XML Java 数据格式
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
78 0