当前位置 博文首页 > blackball1998的博客:多环境下Bean的加载
在实际开发中,我们往往需要区分不同的环境,比如开发环境,测试环境,线上环境,在各个环境中使用的Bean,或者Bean的设置都是不一样的。使用@Profile
注解,可以区分在不同环境下需要添加到IOC容器的Bean。
我们将三个Person类型的Bean添加到IOC容器中,并在方法上添加@Profile
注解,以区分不同的开发环境需要激活的Bean
@Configuration
public class MyConfiguration {
@Bean
@Profile("default")
public Person defaultPerson() {
return new Person(18, "wang");
}
@Bean
@Profile("test")
public Person testPerson() {
return new Person(22, "liu");
}
@Bean
@Profile("dev")
public Person devPerson() {
return new Person(20, "zhang");
}
}
假如我们现在没有添加@Profile
注解,那么默认的Bean激活环境就是default,如果我们没有配置Spring的启动环境,那么默认的启动环境也是default
使用以下测试用例,测试默认的default域下的Bean是否生效
@SpringBootTest
class DemoApplicationTests {
@Autowired
Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
默认激活的Bean被加载进IOC容器当中,而我们使用@Autowired
去获取Person类的唯一Bean也没有报错
现在我们将Spring的激活环境切换到别的环境,然后再测试取出的Bean是哪个Bean
在Spring Boot给出的配置文件application.properties中配置激活的环境
spring.profiles.active=test
再次使用上一个测试用例,发现取出的Bean变成test域下的Bean
这时候如果我们试图用指定Bean名字的方式去获取别的Bean,就会获取不到,说明其他未激活环境下的Bean确实没有被添加到IOC容器中
@SpringBootTest
class DemoApplicationTests {
@Autowired(required = false)
@Qualifier("defaultPerson")
Person person;
@Test
void contextLoads() {
System.out.println(person);//null
}
}
另外,@Profile
也可以添加在整个自定义配置类之上,如果这么使用,Spring会根据@Profile
的属性激活自定义配置类中的所有Bean或者不激活自定义配置类中的所有Bean
打开@Profile
的声明可以看到,这个注解的属性其实是一个数组
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({ProfileCondition.class})
public @interface Profile {
String[] value();
}
所以当我们想配置一个Bean在多环境下生效,直接给@Profile
的属性赋一个数组就行了
@Configuration
public class MyConfiguration {
@Bean
@Profile({"default", "test"})
public Person defaultPerson() {
return new Person(18, "wang");
}
@Bean
@Profile("dev")
public Person devPerson() {
return new Person(20, "zhang");
}
}
在test激活环境下,使用以上测试用例,仍然可以得到Bean