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
相关文章
|
25天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
167 73
|
20天前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
49 21
|
25天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
25天前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
2月前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
185 2
|
2月前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
70 2
|
2月前
|
前端开发 Java 开发者
Spring MVC中的控制器:@Controller注解全解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序控制层的核心。它不仅简化了控制器的定义,还提供了灵活的请求映射和处理机制。本文将深入探讨`@Controller`注解的用法、特点以及在实际开发中的应用。
141 0
|
8月前
|
Java API Spring
Spring容器如何使用一个注解来指定一个类型为配置类型
Spring容器如何使用一个注解来指定一个类型为配置类型
67 0
|
3月前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
59 0
|
7月前
|
XML Java 数据格式
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
71 0