Spring装配Bean ---环境相关的bean

看Spring实战(第4版)笔记

存疑:激活profile 

在开发软件的时候,有一个很大的挑战就是将应用程序从一个环境迁移到另外一个环境 。

有些bean就是在不同的环境需要不同的配置,也就是环境相关的bean。比如数据库配置、加密算法以及与外部系统的集成 都是在跨环境部署时可能会发生变化。

要解决这个问题,有一个种方式 是在单独的配置类(XML配置文件)中配置每个bean,然后在构建阶段确定要将哪一个配置编译到可部署的应用中。    这种方式的问题 是 要为每种环境重新构建应用。但是重新构建可能会引入bug

Spring为环境相关的bean所提供的解决方案 是 根据环境决定该创建哪个bean和不创建哪个bean。

不是在构建时作出决策,而是等到运行时再来确定。这样呢,就可以保证同一个部署单元(比如war文件)能适用于所有的环境,没有必要重新构建。

1.JavaConfig配置 profile bean----@Profile注解 

       配置profile bean 总共有4种方式:(1)为每个环境创建一个配置类,JavaConfig配置 @Profile注解在类级别(2)JavaConfig配置 @Profile注解在方法级别, (3)  为每个环境都创建一个profile XML文件 profile属性 用在xml配置文件根配置上 <beans profile="">(4)xml配置文件 profile属性bean定义上<beans profile="">。

        在JavaConfig配置中 @Profile注解 如果配置在类级别上,那就是告诉Spring 这个配置类里所有的bean都是 特定 profile激活时才会创建。如果 特定 profile没有激活,这类配置类 所有的@Bean注解的方法都会被忽略。Spring3.2开始 @Profile注解 也可以放在方法级别。   

 以下的例子 这里有两个bean,类型都是 DataSource,并且ID都是dataSource。但是在运行时,只会创建一个bean,这取决于处于激活状态的是哪个profile。   

public class DateSource {

}

             在类级别上使用@Profile注解 配置dev环境的bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
@Profile("dev") 
public class DevProfileConfig {
	@Bean
	public DateSource devDateSource() {
		System.out.println("this is devDateSource ");
		return new DateSource();
	}
}

               在类级别上使用@Profile注解 配置prd环境的bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
@Profile("prd")
public class PrdProfileConfig {
	@Bean
	public DateSource prdDateSource() {
		System.out.println(" this is prdDateSource");
		return new DateSource();
	}

}

               或者在方法级别上使用@Profile注解 在同一个配置类定义dev和prd环境的bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;

@Configuration
public class SystemConfig {

	@Bean
	@Profile("dev")
	public DateSource devDateSource() {
		System.out.println(" this is devDateSource  for method @Profile");
		return new DateSource();
	}
	
	@Bean
	@Profile("prd")
	public DateSource prdDateSource() {
		System.out.println(" this is prdDateSource for method @Profile");
		return new DateSource();
	}
}

2.激活profile ---- @ActiveProfiles注解       

     Spring在确定哪个profile处于激活状态时,需要依赖两个独立的属性:spring.profiles.active和spring.profiles.default。

     如果设置了spring.profiles.active属性的话,那么它的值就会用来确定哪个profile是激活的。

     但如果没有设置spring.profiles.active属性的话,那Spring将会查找spring.profiles.default的值。

     如果spring.profiles.active和spring.profiles.default均没有设置的话,那就没有激活的profile,因此只会创建那些没有定义在
profile中的bean。


      有多种方式来设置这两个属性
          作为DispatcherServlet的初始化参数;
          作为Web应用的上下文参数;
          作为JNDI条目;
          作为环境变量;
          作为JVM的系统属性;
          在集成测试类上,使用@ActiveProfiles注解设置。


 测试 上述JavaConfig配置的 环境相关的bean

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@Configuration
@ActiveProfiles("dev")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { DevProfileConfig.class, PrdProfileConfig.class })
public class Test {

	@Autowired
	private DateSource DateSource;

	@org.junit.Test
	public void test() {		 
		System.out.println("nothing");
	}

}

 

posted on 2019-04-16 17:14  dreamstar  阅读(90)  评论(0编辑  收藏  举报