目錄
一、@Profile 環境切換
二、例子
2.1 安裝例子所用的依賴
2.2 例1 資料庫配置檔案的讀取
2.2.1 目錄結構
2.2.2 實作代碼
2.3 例2 在例1基礎加添加@Profile 注解
2.3.1 修改配置檔案
2.3.2 使用 @Profile("default")指定預設環境
2.3.3 使用 -Dspring-prfofiles.active 激活指定環境
2.4 使用環境
一般公司開發環境分為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();
}