Spring注解驱动开发三切换环境Profile

本文介绍了Spring框架中如何通过@Profile注解实现不同环境下的Bean动态激活与配置。包括@Profile注解的基本使用方法、如何指定Bean生效的环境及激活环境的多种方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@Profile注解

Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能。指定组件在哪个环境的情况下才能被注册到容器中,不指定则任何环境下都能注册这个组件。

可以通过如下四种方式指定Bean生效的环境。

ConfigurableEnvironment.setActiveProfiles
AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME =spring.profiles.active
web.xml配置
@ActiveProfiles注解

接口类如下:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {

	/**
	 * The set of profiles for which the annotated component should be registered.
	 */
	String[] value();

}

① 如果不加@Profile注解,则该bean在任何环境下都被注入

@Bean
public Yellow yellow(){
	return new Yellow();
}

② 如果指定了@Profile,则只有该环境被激活的时候bean才会被注入

@Profile("dev")
@Bean("devDataSource")
public DataSource dataSourceDev(@Value("${db.password}")String pwd) throws Exception{
	ComboPooledDataSource dataSource = new ComboPooledDataSource();
	dataSource.setUser(user);
	dataSource.setPassword(pwd);
	dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/xian");
	dataSource.setDriverClass(driverClass);
	return dataSource;
}

③ 如果指定了@Profile(“default”),那么默认环境下bean会被注入

@Profile("default")
@Bean("testDataSource")
public DataSource dataSourceTest(@Value("${db.password}")String pwd) throws Exception{
	ComboPooledDataSource dataSource = new ComboPooledDataSource();
	dataSource.setUser(user);
	dataSource.setPassword(pwd);
	dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
	dataSource.setDriverClass(driverClass);
	return dataSource;
}

④ 如果@Profile配置于类上,则该类下的bean想起作用,Spring激活的环境首先要与类配置@Profile指定的环境一致,其次再看类中方法上的@Profile注解配置。

@PropertySource("classpath:/dbconfig.properties")
@Profile("dev")
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware{
	
	@Value("${db.user}")
	private String user;
	
	private StringValueResolver valueResolver;
	
	private String  driverClass;
	
	@Bean
	public Yellow yellow(){
		return new Yellow();
	}
	
	@Profile("default")
//	@Profile("test")
	@Bean("testDataSource")
	public DataSource dataSourceTest(@Value("${db.password}")String pwd) throws Exception{
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setUser(user);
		dataSource.setPassword(pwd);
		dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
		dataSource.setDriverClass(driverClass);
		return dataSource;
	}
	
	@Profile("dev")
	@Bean("devDataSource")
	public DataSource dataSourceDev(@Value("${db.password}")String pwd) throws Exception{
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setUser(user);
		dataSource.setPassword(pwd);
		dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/xian");
		dataSource.setDriverClass(driverClass);
		return dataSource;
	}
}

激活环境的几种方式

① 虚拟机参数

这里写图片描述


② 代码激活

@Test
public void test01(){
	//1、创建一个applicationContext
	AnnotationConfigApplicationContext applicationContext = 
			new AnnotationConfigApplicationContext();
	//2、设置需要激活的环境
	applicationContext.getEnvironment().setActiveProfiles("dev");
	
	//3、注册主配置类
	applicationContext.register(MainConfigOfProfile.class);
	//4、启动刷新容器
	applicationContext.refresh();
	
	String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class);
	for (String string : namesForType) {
		System.out.println(string);
	}
	
	Yellow bean = applicationContext.getBean(Yellow.class);
	System.out.println(bean);
	applicationContext.close();
}


③ web.xml

<!-- 在上下文中设置profile的默认值 -->
<context-param>
    <param-name>spring.profiles.default</param-name>
    <param-value>dev</param-value>
</context-param>

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 在servlet中设置profile的默认值 -->
    <init-param>
     <param-name>spring.profiles.default</param-name>
     <param-value>dev</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
### Spring Boot多环境配置方法 #### 使用`application-{profile}.properties/yml` 为了使Spring Boot应用程序能够适应不同部署环境的需求,可以为每种环境定义独立的属性文件。这些文件通常命名为`application-{profile}.yml`或`.properties`形式,在启动应用时指定激活哪个特定版本的设置。 例如: - `application-dev.yml`: 开发环境下使用的配置; - `application-prod.yml`: 生产环境中采用的不同参数设定; 当指定了活动概要(`active profile`)之后,框架会自动加载对应的自定义化资源文件并覆盖默认值[^4]。 ```yaml # application-dev.yml 示例 server: port: 8081 spring: datasource: url: jdbc:mysql://localhost:3306/devdb?useSSL=false&serverTimezone=UTC username: root password: secret ``` 对于Java代码内部,则可以通过`@ConfigurationProperties`注解绑定外部化的配置项至实体类字段上,或是借助于`Environment`接口获取单个key-value对。 #### 命令行参数与环境变量 除了静态地编写多个YAML/Properties文档外,还可以动态调整正在运行的应用程序的行为模式——即通过传递命令行选项给JVM进程来即时改变某些全局性的开关状态或者路径指向等重要信息。这同样适用于操作系统级别的ENV Variables机制,它们会在实例初始化阶段被读取进来作为补充数据源之一参与最终决策过程[^1]。 假设现在有一个名为`SPRING_PROFILES_ACTIVE`的环境变量设成了`prod`,那么即使存在其他同名却位于不同目录下的配置文件,默认情况下也只会优先考虑该生产版的内容。 #### @Profile 注解实践案例 针对题目提到的情况——即想要切换连接到MySQL、Oracle以及Sybase种不同类型的关系型数据库系统之间工作的话,就可以基于上述两种方式的基础上进一步引入面向切面编程的思想,也就是利用`@Profile`标签标记那些仅限于某几个场景下才允许实例化的组件bean对象。 具体做法如下所示: ##### 定义DataSource Bean 先分别建立个实现了相同接口但是各自对应着不一样的驱动器URL字符串以及其他必要的认证凭证细节的服务提供者实现类,并在其上方加上相应的限定符说明适用范围。 ```java @Configuration public class DataSourceConfig { @Bean(name="mysqlDS") @Profile("mysql") public DataSource mysqlDataSource() { HikariDataSource dataSource = new HikariDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://host:port/dbname"); dataSource.setUsername("user"); dataSource.setPassword("pass"); return dataSource; } @Bean(name="oracleDS") @Profile("oracle") public DataSource oracleDataSource(){ // Similar setup for Oracle... } @Bean(name="sybaseDS") @Profile("sybase") public DataSource sybaseDataSource(){ // Setup for Sybase... } } ``` 此时如果希望让整个工程处于“测试”状态下只启用MySQL链接池服务,只需要简单修改一下启动脚本中的额外参数部分即可完成转换操作:`--spring.profiles.active=mysql` 或者 设置环境变量 `export SPRING_PROFILES_ACTIVE=mysql`. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值