Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring/boot、概要文件、java配置和bean创建顺序(意外行为??)_Spring_Spring Boot_Spring Java Config_Spring Profiles - Fatal编程技术网

Spring/boot、概要文件、java配置和bean创建顺序(意外行为??)

Spring/boot、概要文件、java配置和bean创建顺序(意外行为??),spring,spring-boot,spring-java-config,spring-profiles,Spring,Spring Boot,Spring Java Config,Spring Profiles,我正在开发一个spring boot应用程序。我们有每个环境的属性文件(dev、int、qa、prd等)。至于豆子,需要为生产创建不同的豆子。我们有这样的配置: @Configuration class MyBeans { @Bean(name="someBean") @Profile("prd") MyBean someBeanProd() { ... } @Bean(name="someBean") MyBean someBe

我正在开发一个spring boot应用程序。我们有每个环境的属性文件(dev、int、qa、prd等)。至于豆子,需要为生产创建不同的豆子。我们有这样的配置:

@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”方法(如预期),并且正在加载相关属性文件(应用程序prd.properties)。对于任何其他配置文件,将调用“someBeanDev”(如预期的那样),并加载相关属性文件

但是,如果我更改配置中方法的顺序,如下所示,“someBeanDev”方法始终被调用(即使活动概要文件是prd),但使用的是正确的属性文件

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

    @Bean(name="someBean")
    @Profile("prd")
    MyBean someBeanProd() {
        ...
    }
}
这是正确的/预期的行为吗?我希望spring能够创建正确的bean,而不考虑配置文件中方法的顺序

是否有一种方法可以为一个概要文件定义bean,而任何其他概要文件都应该回退到“默认”概要文件


在其他Java配置类中创建prd bean也不起作用。

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

在这种情况下,如果profile是“prd”,则调用两个@Bean方法,但是任何
@Autowired MyBean
都将只有someBeanProd()返回的MyBean。 如果您还希望使用
@Autowire Collection
,则此案例非常有用

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


在这种情况下,只有一个@Bean方法被称为依赖于指定的概要文件。

您可以使用
@Primary
(不指定Bean的名称):

在这种情况下,如果profile是“prd”,则调用两个@Bean方法,但是任何
@Autowired MyBean
都将只有someBeanProd()返回的MyBean。 如果您还希望使用
@Autowire Collection
,则此案例非常有用

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


在这种情况下,只有一个@Bean方法被称为依赖于指定的概要文件。

我也注意到了这种行为,一个解决方法是将不同的概要文件Bean保留在不同的@profile注释类中(这有点麻烦,但我记得它工作正常)

例如

假设您在生产概要文件中有两个用于bean1和bean2的实现,在暂存概要文件中有两个不同的实现

您想要创建 两个配置类

@Configuration
@Profile({"production"})
public class ConfigProduction {
  @Bean Bean1 bean1(){ return prod impl;}]
  @Bean Bean2 bean2(){ return prod impl;}
}

@Configuration
@Profile({"staging"})
public class ConfigStaging {
  @Bean Bean1 bean1(){ return staging impl;}]
  @Bean Bean2 bean2(){ return staging impl;}
}
在默认的application.properties中 将production(或任何您喜欢的内容)设置为活动配置文件

spring.profiles.active=生产,具有类似“回退”的行为


试试看

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

例如

假设您在生产概要文件中有两个用于bean1和bean2的实现,在暂存概要文件中有两个不同的实现

您想要创建 两个配置类

@Configuration
@Profile({"production"})
public class ConfigProduction {
  @Bean Bean1 bean1(){ return prod impl;}]
  @Bean Bean2 bean2(){ return prod impl;}
}

@Configuration
@Profile({"staging"})
public class ConfigStaging {
  @Bean Bean1 bean1(){ return staging impl;}]
  @Bean Bean2 bean2(){ return staging impl;}
}
在默认的application.properties中 将production(或任何您喜欢的内容)设置为活动配置文件

spring.profiles.active=生产,具有类似“回退”的行为


试试看

我用@AutoConfigureAfter尝试了这种方法,但仍然不起作用。很抱歉,太早按enter键……感谢您的回复。我用@AutoConfigureAfter尝试了这种方法,但仍然不起作用。有趣的是,如果prd config类按字母顺序排在dev config类之后,那么spring将使用正确的bean(带或不带AutoConfigureAfter注释)。例如:DevConfig,ProdConfig=working fine DevConfig,Config=not working我没有尝试第一种方法,因为我不想在不需要的情况下创建bean。我的行为与您的行为相同,这在我看来并不简单。无论如何,我编辑了我的答案(第二种方法),而这一种应该有效。是的,使用!prd it正在运行,但不符合我们的要求。理想情况下,我们需要一个“回退”bean,该bean仅在没有为其他活动概要文件创建时创建(我们有多个活动概要文件)。我不明白为什么config类中方法的顺序会影响bean的创建。我再次更新了我的答案(第二种方法),这一次,它应该能够满足您的需要。我还尝试使用两个独立的配置类(具有不同的类名),它具有相同的行为。我尝试了@AutoConfigureAfter的方法,但仍然不起作用。抱歉,太早按enter键…感谢您的回复。我用@AutoConfigureAfter尝试了这种方法,但仍然不起作用。有趣的是,如果prd config类按字母顺序排在dev config类之后,那么spring将使用正确的bean(带或不带AutoConfigureAfter注释)。例如:DevConfig,ProdConfig=working fine DevConfig,Config=not working我没有尝试第一种方法,因为我不想在不需要的情况下创建bean。我的行为与您的行为相同,这在我看来并不简单。无论如何,我编辑了我的答案(第二种方法),而这一种应该有效。是的,使用!prd it正在运行,但不符合我们的要求。理想情况下,我们需要一个“回退”bean,该bean仅在没有为其他活动概要文件创建时创建(我们有多个活动概要文件)。我不明白为什么config类中方法的顺序会影响bean的创建。我再次更新了我的答案(第二种方法),这一次,它应该能够满足您的需要。我还尝试使用两个独立的配置类(具有不同的类名),它具有相同的行为。
@Configuration
@Profile({"production"})
public class ConfigProduction {
  @Bean Bean1 bean1(){ return prod impl;}]
  @Bean Bean2 bean2(){ return prod impl;}
}

@Configuration
@Profile({"staging"})
public class ConfigStaging {
  @Bean Bean1 bean1(){ return staging impl;}]
  @Bean Bean2 bean2(){ return staging impl;}
}