目录
2.3.2 使用 @Profile("default")指定默认环境
2.3.3 使用 -Dspring-prfofiles.active 激活指定环境
一般公司开发环境分为3种:开发环境dev、测试环境test、生产环境prod
开发环境dev:一般是开发本地进行开发
测试环境test:一般是在公司测试服务器进行测试
生产环境prod:直接在线上跑,产生收入的,即给客户使用的在开发的时候代码往往根据根据不同的环境进行数据库切换,这样我可以配置3套环境的数据库配置,在不同环境上跑我就指定不同的配置即可,那怎么做到呢?这就用到了今天的主角@Profile
一、@Profile 环境切换
/**
* Profile:
* Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
*
* 开发环境、测试环境、生产环境;
* 数据源:(/A)(/B)(/C)
*
* @Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
* 1)加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
* 2)写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
* 3)没有标注环境标识的bean,在任何环境下都是加载的。
* */
二、例子
2.1 安装例子所用的依赖
本章所有的例子都在使用上一章《hualinux spring 4.15:spring添加maven支持 10分钟学会mavne》所建立的项目基础上安装的
安装软件都用maven安装了,不用直接下载jar包放在项目的lib目录中,让maven代为管理。
这个例子中需要用到3个jar包
c3p0:主要是读取外部配置文件,一般数据库配置文件放在外部,我这里使用yml方式
mchange-commons-java:c3p0数据库连接池的辅助包
mysql-connector-java:jdbc驱动包,是java连接mysql数据库使用的,我这里只是配置文件,并没用到mysql数据库
使用maven之后,我直接用单元测试进行测试了,不使用传统的Main入口函数运行了,所以还需要安装一个junit单元测试包,idea支持junit5
上面4种包的可以去maven官网 搜索得到相关的版本和maven安装的配置文件,我使用目前它们的最新版本,分别复制,粘贴进idea的pom.xml的<dependencies></dependencies>标签中,即可,复制完后的pom.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hualinux</groupId>
<artifactId>spring-annotation2</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/mchange-commons-java -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>mchange-commons-java</artifactId>
<version>0.2.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<!-- JUnit5:单元测试需要用到-->
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>14.0.1</source>
<target>14.0.1</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
然后点pom.xml右边的更新即会自动下载安装
安装后之后,不会出现红色字体,表示全部正常
ps:本章所有例子的pom.xml 配置都不会变
2.2 例1 数据库配置文件的读取
2.2.1 目录结构
db.yml:mysql数据库配置文件,maven规定要放夺resources目录中,不能放其它地方
com.hualinux.conf.MainConfProfile.java:这个为数据库配置文件
IOCTest_Profile.java:这个java文件我放在test目录下,表示这个是一个测试文件,我使用的是junit5单元测试,这个也很简单的,讲一下就懂了
2.2.2 实现代码
db.yml内容如下:
user: root
pwd: root
driverClass: com.mysql.cj.jdbc.Driver
jdbcUrlTest: jdbc:mysql://127.0.0.1:3306/hua_test?serverTimezone=GMT%2B8
jdbcUrlDev: jdbc:mysql://127.0.0.1:3306/hua_dev?serverTimezone=GMT%2B8
jdbcUrlProd: jdbc:mysql://127.0.0.1:3306/hua?serverTimezone=GMT%2B8
注意:
1.那个冒号后面有一个空格的!而且这个空格是不能省的,省会出读不到数据。
2.值不能用双引号或单引号,引起来,否则连接数据库会有问题,下面是错误的写法
#值不能用单引号或双引号,否则会出问题,下面写法是错误的 driverClass: "com.mysql.cj.jdbc.Driver" jdbcUrlTest: "jdbc:mysql://127.0.0.1:3306/hua_test?serverTimezone=GMT%2B8" jdbcUrlDev: "jdbc:mysql://127.0.0.1:3306/hua_dev?serverTimezone=GMT%2B8" jdbcUrlProd: "jdbc:mysql://127.0.0.1:3306/hua?serverTimezone=GMT%2B8"
com.hualinux.conf.MainConfProfile.java代码如下:
package com.hualinux.conf;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
@PropertySource(value={"classpath:/db.yml"})
@Configuration
public class MainConfProfile {
@Value("${user}")
private String user;
@Value("${pwd}")
private String pwd;
@Value("${driverClass}")
private String driverClass;
@Value("${jdbcUrlTest}")
private String jdbcUrlTest;
@Value("${jdbcUrlDev}")
private String jdbcUrlDev;
@Value("${jdbcUrlProd}")
private String jdbcUrlProd;
@Bean("testDataSource")
public DataSource dataSourceTest() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setDriverClass(driverClass);
//测试环境使用的数据库
dataSource.setJdbcUrl(jdbcUrlTest);
return dataSource;
}
@Bean("devDataSource")
public DataSource dataSourceDev() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setDriverClass(driverClass);
//开发环境使用的数据库
dataSource.setJdbcUrl(jdbcUrlDev);
return dataSource;
}
@Bean("prodDataSource")
public DataSource dataSourceProd() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setDriverClass(driverClass);
//生产环境使用的数据库
dataSource.setJdbcUrl(jdbcUrlProd);
return dataSource;
}
}
test-->java-->IOCTest_Profile.java
import com.hualinux.conf.MainConfProfile;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import javax.sql.DataSource;
public class IOCTest_Profile {
AnnotationConfigApplicationContext ctx;
@Test
//注意test不能有返回值只能是void
public void test01(){
ctx=new AnnotationConfigApplicationContext(MainConfProfile.class);
String[] namesForType = ctx.getBeanNamesForType(DataSource.class);
for (String name: namesForType){
System.out.println(name);
ComboPooledDataSource dataSource= (ComboPooledDataSource) ctx.getBean(name);
System.out.println(dataSource.getJdbcUrl());
}
ctx.close();
}
}
ps:测试文件是没有main主入口函数的,当测试一个方法的时候不能有返回值,只能是void
@Test注解是测试方法的意思,junit5常用注解的意思可以看它的官网说明
写完了,然后运行一个test01即可,点一下test01左边的绿色圆即可,如下图所示:
测试的结果如下:
testDataSource
jdbc:mysql://127.0.0.1:3306/hua_test?serverTimezone=GMT%2B8
devDataSource
jdbc:mysql://127.0.0.1:3306/hua_dev?serverTimezone=GMT%2B8
prodDataSource
jdbc:mysql://127.0.0.1:3306/hua?serverTimezone=GMT%2B8
2.3 例2 在例1基础加添加@Profile 注解
2.3.1 修改配置文件
上面例1只是测试是否读到了配置,现在在配置文件的各个bean中添加@Profile 注解指定一下配置名字名
com.hualinux.conf.MainConfProfile.java,修改部分代码如下:
@Profile("test")
@Bean("testDataSource")
public DataSource dataSourceTest() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setDriverClass(driverClass);
//测试环境使用的数据库
dataSource.setJdbcUrl(jdbcUrlTest);
return dataSource;
}
@Profile("dev")
@Bean("devDataSource")
public DataSource dataSourceDev() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setDriverClass(driverClass);
//开发环境使用的数据库
dataSource.setJdbcUrl(jdbcUrlDev);
return dataSource;
}
@Profile("prod")
@Bean("prodDataSource")
public DataSource dataSourceProd() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setDriverClass(driverClass);
//生产环境使用的数据库
dataSource.setJdbcUrl(jdbcUrlProd);
return dataSource;
}
PS:上面3个@Profile注解中都没有@Profile("default"),表示3个都不会激活,如果你运行test01结果为空的,什么都没有
2.3.2 使用 @Profile("default")指定默认环境
如果我们要指定一个默认,比如本机开发,去这里选择dev环境,改成:
@Profile("default")
@Bean("devDataSource")
运行一下test01方法效果如下图所示:只能读到一个默认的
2.3.3 使用 -Dspring-prfofiles.active 激活指定环境
如果我有这么下个需求,我不用默认配置,到使用的时候我再指定激活那个bean配置行不行,行!
那就得用到 -Dspring.profiles.active 参数激活指定环境,你把 2.3.2 的 @Profile("default")改回 @Profile("dev")
再按如下操作:
的VM options:添加多一个 -Dspring.profiles.active=test
注:这个配置一个要写正确! -Dspring.profiles.active=test 前面的小横杠不能少,大小写要一样
再运行一个test01,看一下效果:
测试完之后再配置删除,恢复原来的
2.4 使用环境
我在上面的基础上再添加多一个测试方法,看一下怎么使用这个bean
test-->java-->IOCTest_Profile.java 添加多一个测试方法,如下:
@Test
//注意test不能有返回值只能是void
public void test02(){
ctx=new AnnotationConfigApplicationContext();
// 1. 创建一个 ApplicationContext,这里没有一开始就指定配置类
ctx = new AnnotationConfigApplicationContext();
//2. 设置需要激活的环境,在没有指定默认的情况下
ctx.getEnvironment().setActiveProfiles("dev");
// 3. 注册主配置类
ctx.register(MainConfProfile.class);
//4. 启动刷新容器
ctx.refresh();
String[] namesForType = ctx.getBeanNamesForType(DataSource.class);
for (String name: namesForType){
System.out.println(name);
ComboPooledDataSource dataSource= (ComboPooledDataSource) ctx.getBean(name);
System.out.println(dataSource.getJdbcUrl());
}
ctx.close();
}
运行一下test02方法,结果如下: