首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring -多个Profiles活动

Spring -多个Profiles活动
EN

Stack Overflow用户
提问于 2016-06-30 21:48:33
回答 5查看 101.5K关注 0票数 42

我在Spring中基本上有一个bean,我只想在2个概要文件处于活动状态时激活它。基本上,这就像:

代码语言:javascript
复制
@Profile({"Tomcat", "Linux"})
public class AppConfigMongodbLinux{...}

@Profile({"Tomcat", "WindowsLocal"})
public class AppConfigMongodbWindowsLocal{...}

所以我希望当我使用-Dspring.profiles.active=Tomcat,WindowsLocal时,它会尝试只使用AppConfigMongodbWindowsLocal,但是它仍然尝试注册AppConfigMongodbLinux

代码语言:javascript
复制
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfigMongodbLinux': Injection of autowired dependencies failed

是否有可能仅在两个配置文件都处于活动状态或我是否不正确地使用它时才将bean注册?)

谢谢!!

编辑:张贴完整的堆栈。

错误实际上发生在属性上缺少的属性上,但是这个bean会被激活吗?我想要理解这一点,以确保我没有激活一个错误的豆子。

代码语言:javascript
复制
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
    ...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfigMongodbLinux': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.Integer mycompany.config.AppConfigMongodbLinux.mongoPort; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'mongo.port' in string value "${mongo.port}"
    ... 40 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.Integer mycompany.config.AppConfigMongodbLinux.mongoPort; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'mongo.port' in string value "${mongo.port}"
    ...
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'mongo.port' in string value "${mongo.port}"
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-06-30 22:05:37

不幸的是,如果列出的配置文件是活动的,@Profile会激活。有几种方法可以解决这个问题。

  • 将常见的@Profile("Tomcat")注释应用于顶级配置类,然后将@Profile("Windows")应用于嵌套配置类(或@Bean方法)。
  • 如果Spring是可以接受的依赖项,那么使用@AllNestedConditions创建一个注释,它是和而不是OR。

如果您使用的是Spring自动配置类,那么您尝试编写的内容似乎是干净的;如果在应用程序生命周期的这个阶段引入自动配置是可行的,我建议您考虑一下。

票数 26
EN

Stack Overflow用户

发布于 2018-11-18 13:55:23

SpringVersion5.1及更高版本为指定更复杂的配置文件字符串表达式提供了附加功能。在您的情况下,可以通过以下方式实现所需的功能:

代码语言:javascript
复制
@Profile({"Tomcat & Linux"})
@Configuration
public class AppConfigMongodbLinux {...}

有关更多信息,请阅读Spring参考文档中的使用@Profile章节。

Update (方法级概要表达式):实际上,我已经测试了一些@Bean方法级别配置文件表达式,所有这些都很有魅力:

代码语言:javascript
复制
/**
 * Shows basic usage of {@link Profile} annotations applied on method level.
 */
@Configuration
public class MethodLevelProfileConfiguration {

    /**
     * Point in time related to application startup.
     */
    @Profile("qa")
    @Bean
    public Instant startupInstant() {
        return Instant.now();
    }

    /**
     * Point in time related to scheduled shutdown of the application.
     */
    @Bean
    public Instant shutdownInstant() {
        return Instant.MAX;
    }

    /**
     * Point in time of 1970 year.
     */
    @Profile("develop & production")
    @Bean
    public Instant epochInstant() {
        return Instant.EPOCH;
    }
}

集成测试:

代码语言:javascript
复制
/**
 * Verifies {@link Profile} annotation functionality applied on method-level.
 */
public class MethodLevelProfileConfigurationTest {

    @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = MethodLevelProfileConfiguration.class)
    @ActiveProfiles(profiles = "qa")
    public static class QaActiveProfileTest {

        @Autowired
        private ApplicationContext context;

        @Test
        public void shouldRegisterStartupAndShutdownInstants() {
            context.getBean("startupInstant", Instant.class);
            context.getBean("shutdownInstant", Instant.class);

            try {
                context.getBean("epochInstant", Instant.class);
                fail();
            } catch (NoSuchBeanDefinitionException ex) {
                // Legal to ignore.
            }
        }
    }

    @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = MethodLevelProfileConfiguration.class)
    @ActiveProfiles(profiles = {"develop", "production"})
    public static class MethodProfileExpressionTest {

        @Autowired
        private ApplicationContext context;

        @Test
        public void shouldRegisterShutdownAndEpochInstants() {
            context.getBean("epochInstant", Instant.class);
            context.getBean("shutdownInstant", Instant.class);

            try {
                context.getBean("startupInstant", Instant.class);
                fail();
            } catch (NoSuchBeanDefinitionException ex) {
                // Legal to ignore.
            }
        }
    }
}

对Spring5.1.2版本进行了测试。

票数 41
EN

Stack Overflow用户

发布于 2018-10-17 07:38:08

代码语言:javascript
复制
@ConditionalOnExpression("#{environment.acceptsProfiles('Tomcat') && environment.acceptsProfiles('Linux')}")

学分:春季源代码。使用IDE查找@ConditionalOnExpression,然后“查找用法”,以查看源代码中的相关示例。这将使您成为一个更好的开发人员。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38133808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档