当前位置 博文首页 > blackball1998的博客:多环境下Bean的加载

    blackball1998的博客:多环境下Bean的加载

    作者:[db:作者] 时间:2021-06-20 12:10

    多环境下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

    下一篇:没有了