hualinux spring 4.16:@Profile 切换环境

目录

一、@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();
    }

运行一下test02方法,结果如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值