您现在的位置是:首页 >技术杂谈 >SpringBoot 通过@Profile注解配置多环境网站首页技术杂谈
SpringBoot 通过@Profile注解配置多环境
                简介SpringBoot 通过@Profile注解配置多环境            
            参考资料
一. 使用场景
在Spring中,可以使用配置文件的方式来指定不同环境下所需要的配置信息
⏹application.yml
spring:
  profiles:
  	# 通过active来指定当前所处的开发环境
    active: dev
 
⏹application-dev.yml
spring:
  datasource:
    url: jdbc:mysql://localhost/myblog-dev
    username: dev
    password: mysql
    driver-class-name: com.mysql.cj.jdbc.Driver
 
⏹application-product.yml
spring:
  datasource:
    url: jdbc:mysql://localhost/myblog-product
    username: product
    password: mysql
    driver-class-name: com.mysql.cj.jdbc.Driver
 
但有时候,我们不通过配置文件,而是通过配置类的方式来指定不同环境下的配置信息,
 此时就需要用到@Profile注解。
二. 前期准备
⏹用来封装数据库信息的Entity
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class DBInfoEntity {
    private String url;
    private String port;
    private String userName;
    private String password;
}
 
⏹配置接口
public interface Config {
	
	// 获取数据库信息
    DBInfoEntity getDBInfo();
	
	// 获取系统URL
    String getSystemUrl();
}
 
三. @Profile注解作用于类上
- 我们使用
@Profile注解分别作用于如下所示的两个配置类上,分别指定dev和product环境下才能起作用。 - 我们通过
@Configuration注解指定两个配置类的Bean名称都是MyConfig,一般情况下会报错,因为Spring的IOC容器中,Bean的名称是唯一的,但是我们使用了@Profile注解指定了开发环境,不满足指定开发环境的配置类不会被添加到Bean中,所以不会报错。 
3.1 配置类
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration("MyConfig")
// 指定开发环境为dev
@Profile("dev")
public class MyConfig1 implements Config {
    @Override
    public DBInfoEntity getDBInfo() {
        return DBInfoEntity.builder()
                .url("https://127.0.0.1")
                .port("8080")
                .userName("devUser")
                .password("110120")
                .build();
    }
    @Override
    public String getSystemUrl() {
        return "https://www.dev.com";
    }
}
 
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration("MyConfig")
// 指定开发环境为product
@Profile("product")
public class MyConfig2 implements Config {
    @Override
    public DBInfoEntity getDBInfo() {
        return DBInfoEntity.builder()
                .url("https://127.0.0.2")
                .port("8089")
                .userName("prodUser")
                .password("999000")
                .build();
    }
    @Override
    public String getSystemUrl() {
        return "https://www.prod.com";
    }
}
 
3.2 效果
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class Test32Controller implements CommandLineRunner {
	
	// 注入接口,会自动从IOC容器中获取该接口的实现类
    @Autowired
    private Config config;
    
    @Override
    public void run(String... args) throws Exception {
        
        DBInfoEntity dbInfo = config.getDBInfo();
        System.out.println(dbInfo);
        String systemUrl = config.getSystemUrl();
        System.out.println(systemUrl);
    }
}
 
???dev环境

???product环境

四. @Profile注解作用于方法上
4.1 定义一个生产环境的注解
- 当
@Profile注解作用于自定义注解上时,自定义注解便可标识开发环境,相当于是@Profile(“开发环境名称”)的简写方式。 
import org.springframework.context.annotation.Profile;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Profile("product")
public @interface ProductionAnnotation {
}
 
4.2 配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class MyConfig3 {
	
	// 开发环境时,才会注入IOC容器
    @Bean
    @Profile("dev")
    public String getNameDev() {
        return "devName";
    }
	
	// 生产环境时,才会注入IOC容器
    @Bean
    @ProductionAnnotation  // 相当于 @Profile("product")
    public String getNameProduct() {
        return "productName";
    }
}
 
4.3 效果
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class Test32Controller implements CommandLineRunner {
    @Autowired
    private ApplicationContext applicationContext;
    @Override
    public void run(String... args) throws Exception {
        // 判断当前IOC容器中是否存在名称为 getNameDev 的Bean
        boolean getNameDevExist = applicationContext.containsBean("getNameDev");
        if (getNameDevExist) {
            // 从IOC容器中获取出名称为 getNameDev 的Bean
            Object bean1 = applicationContext.getBean("getNameDev");
            System.out.println("目前所在的是开发环境!");
            System.out.println(bean1);
        }
        boolean getNameProductExist = applicationContext.containsBean("getNameProduct");
        if (getNameProductExist) {
            Object bean2 = applicationContext.getBean("getNameProduct");
            System.out.println("目前所在的是生产环境!");
            System.out.println(bean2);
        }
    }
}
 
???dev环境

???product环境

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。
        
    
        
    
            




U8W/U8W-Mini使用与常见问题解决
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结