Spring / boot,profiles,java config和bean创建顺序(意外行为??)

时间:2015-10-20 22:05:10

标签: spring spring-boot spring-java-config spring-profiles

我正在开发一个春季启动应用程序。我们有每个环境的属性文件(dev,int,qa,prd等)。至于bean,有些需要以不同的方式为生产创建。所以我们有这个配置:

@Configuration
class MyBeans {
    @Bean(name="someBean")
    @Profile("prd")
    MyBean someBeanProd() {
        ...
    }

    @Bean(name="someBean")
    MyBean someBeanDev() {
        ...
    }
}

MyBean自动装配如下:

@Component
public class SomeService 
{
    @Autowired
    private MyBean someBean;
}

使用以下命令启动应用程序时

  

-Dspring.profiles.active = PRD

' someBeanProd'方法被调用(如预期的那样),并且正在加载相关的属性文件(application-prd.properties)。对于任何其他个人资料&some; abeBeanDev'被调用(如期望)并加载相关的属性文件。

但是,如果我更改配置中方法的顺序如下所示,' someBeanDev'方法被称为ALWAYS(即使活动配置文件是prd),但正在使用正确的属性文件。

@Configuration
class MyBeans {
    @Bean(name="someBean")
    MyBean someBeanDev() {
        ...
    }

    @Bean(name="someBean")
    @Profile("prd")
    MyBean someBeanProd() {
        ...
    }
}

这是正确/预期的行为吗?无论配置文件中的方法顺序如何,我都希望spring能够创建正确的bean。

有没有办法为一个配置文件定义一个bean,而任何其他配置文件都应该回退到'默认'轮廓?

在另一个Java配置类中创建prd bean也无法正常工作。

2 个答案:

答案 0 :(得分:0)

您可以使用@Primary(不指定bean'名称):

@Bean
public MyBean someBeanDev() {
    return new MyBean("dev");
}

@Primary
@Profile("prd")
@Bean
public MyBean someBeanProd() {
    return new MyBean("prod");
}

在这种情况下,如果profile是&#34; prd&#34;则调用两个@Bean方法。但是任何@Autowired MyBean都只有someBeanProd()返回的MyBean。 如果您还想拥有@Autowire Collection<MyBean>,则此案例非常有用。

或者将@ConditionalOnMissingBean与bean名称(或具有value属性的bean类)一起使用:

@Configuration
public class ConfProd {

    @Profile("prd")
    @Bean(name = "someBean")
    public MyBean someBeanProd() {
        return new MyBean("prod");
    }
}

@Configuration
public class ConfDev {

    @ConditionalOnMissingBean(name = "someBean")
    @Bean(name = "someBean")
    public MyBean someBeanDev() {
        return new MyBean("dev");
    }
}

在这种情况下,只有一个@Bean方法被调用,取决于指定的配置文件。

答案 1 :(得分:0)

我也注意到了这种行为,一种解决方法是将不同的配置文件bean保存在不同的@Profile注释类中(这有点麻烦,但我记得它工作正常)

E.g。

让我们假设您在生产配置文件中有两个bean1和bean2实现,以及您的暂存配置文件有两个不同的实现

你想要创造 两个配置类

angular.module('quiip.directives')
    .directive('subscribeToNewsletter', subscribeToNewsletterDirective);

    function subscribeToNewsletterDirective() {
        return {
            link: link
        }

        function link(scope, element, attrs) {
            element.addClass('subscribe-to-newsletter');
        }
    }

在您的默认application.properties中 将生产(或任何您喜欢的)设置为活动配置文件

spring.profiles.active = production,有一个&#39;后退&#39;喜欢的行为

试一试