Springboot中的@Profile注解
在项目运行中,包括多种环境,例如线上环境prod(product)、开发环境dev(development)、测试环境test、提测环境qa、单元测试unitest等等。不同的环境需要进行不同的配置,从而在不同的场景中跑我们的程序。例如prod环境和dev环境通常需要连接不同的数据库、需要配置不同的日志输出配置。还有一些类和方法,在不同的环境下有不同的实现方式。
Spring Boot 对此提供了支持,一方面是注解@Profile,另一方面还有多资源配置文件。
一、 @Profile注解使用说明
@profile
注解的作用是指定类或方法在特定的 Profile 环境生效,任何@Component
或@Configuration
注解的类都可以使用@Profile
注解。在使用DI来依赖注入的时候,能够根据@profile
标明的环境,将注入符合当前运行环境的相应的bean。
使用要求:
@Component
或@Configuration
注解的类可以使用@profile
@Profile
中需要指定一个字符串,约定生效的环境
1、@Profile
的使用位置
(1) @Prifile
修饰类
@Configuration
@Profile("prod")
public class JndiDataConfig {
@Bean(destroyMethod="")
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
(2) @Profile
修饰方法
@Configuration
public class AppConfig {
@Bean("dataSource")
@Profile("dev")
public DataSource standaloneDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
@Bean("dataSource")
@Profile("prod")
public DataSource jndiDataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
(3)@Profile
修饰注解
@Profile
注解支持定义在其他注解之上,以创建自定义场景注解。这样就创建了一个@Dev
注解,该注解可以标识bean使用于@Dev
这个场景。后续就不再需要使用@Profile("dev")
的方式,这样即可以简化代码。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Profile("prod")
public @interface Production {
}
2、profile激活
实际使用中,注解中标示了prod、test、qa等多个环境,运行时使用哪个profile由spring.profiles.active控制,以下说明2种方式:配置文件方式、命令行方式。
(1)配置文件方式激活profile
确定当前使用的是哪个环境,这边环境的值与application-prod.properties中-后面的值对应,这是SpringBoot约定好的。
在resources/application.properties中添加下面的配置。需要注意的是,spring.profiles.active的取值应该与@Profile
注解中的标示保持一致。
spring.profiles.active=dev
除此之外,同理还可以在resources/application.yml中配置,效果是一样的:
spring:
profiles:
active: dev
(2)命令行方式激活profile
在打包后运行的时候,添加参数:
java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;
二、多Profile的资源文件
除了@profile注解的可以标明某些方法和类具体在哪个环境下注入。springboot的环境隔离还可以使用多资源文件的方式,进行一些参数的配置。
1、资源配置文件
Springboot的资源配置文件除了application.properties之外,还可以有对应的资源文件application-{profile}.properties。
假设,一个应用的工作环境有:dev、test、prod
那么,我们可以添加 4 个配置文件:
- applcation.properties - 公共配置
- application-dev.properties - 开发环境配置
- application-test.properties - 测试环境配置
- application-prod.properties - 生产环境配置
不同的properties配置文件也可以是在 applcation.properties 文件中来激活 profile:spring.profiles.active = test
2、使用例子
以下是一个多个资源配置文件的例子,主要区分了开发环境dev和线上环境prod。
在controller层中的Sound.java中新建一个接口,返回配置文件中的信息:name和local。
@Controller
@RequestMapping("/sound")
public class Sound {
@Value("${com.name}")
private String name;
@Value("${com.location}")
private String location;
@RequestMapping("hello")
@ResponseBody
public String sound1(){
System.out.println(name + "hello Spring Boot, " +location);
return name + ",hello Spring Boot! " +location;
}
}
application.properties文件内容如下:
## 多环境配置文件激活属性
spring.profiles.active=prod
application-dev.properties文件内容如下:
# 服务端口
server.port=1111
#可以定义一些自己使用的属性,然后通过@Value("${属性名}}")注解来加载对应的配置属性
com.name=DEV
com.location=Beijing
application-prod.properties文件内容如下:
server.port=2222
#可以定义一些自己使用的属性,然后通过@Value("${属性名}}")注解来加载对应的配置属性
com.name=Prod
com.location=Hubei
启动Springboot后,访问http://localhost:2222/sound/hello,则会有如下结果。如果此时访问http://localhost:11111/sound/hello则会无法访问,因为此时spring.profiles.active=prod
激活的是prod环境,使用的是application-prod.properties中的配置。
更改application-dev.properties文件,spring.profiles.active=dev
激活dev环境。重启Springboot则可以访问http://localhost:11111/sound/hello。
参考博客:
[1]: https://blog.csdn.net/xadjccl/article/details/81983768
[2]: https://www.cnblogs.com/jingmoxukong/p/10151785.html#%E7%A4%BA%E4%BE%8B%E6%BA%90%E7%A0%81
[3]: https://blog.csdn.net/he90227/article/details/52981747