目录
一、@Profile 注解的作用
二、@Profile 指定环境的方式
2.1 JVM启动参数
2.2 通过代码方式控制:
三、@Profile 实现切换数据源示例
3.1 导入依赖
3.2 新建数据源配置文件dataSource.properties
3.3 新建TestProfileConfig.java 配置类
3.4 新建测试类TestProfile.java
四、使用总结
今天给大家分享Spring属性注入的注解@Profile 介绍,希望对大家能有所帮助!
一、@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")@Beanpublic 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")@Beanpublic 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")@Beanpublic 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首先创建一个AnnotationConfigApplicationContext2 设置环境变量,指定要激活的环境3 注册配置类4启动的时候刷新容器*/// 01 首先创建一个AnnotationConfigApplicationContextAnnotationConfigApplicationContext 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,在任何环境下都可以被正常加载。