排除由多个spring @Profiles同时管理的bean

时间:2016-07-22 14:28:35

标签: java spring spring-boot

我可以控制是否根据传递给应用程序的参数实例化我的应用程序上下文中的Spring bean吗?

示例:

如果我在

中设置了弹簧配置文件

ANT的build.xml jvmarg: -Dspring.profiles.active=P1,P2

对于Configuration类中的以下代码段:

@Bean
@Profile({"!P1", "!P2"})
public String P3() {
    String s = "Check1:P3";
    System.out.println(s);
    return s;
}

@Bean
@Profile({"!P1", "!P3"})
public String P2() {
    String s = "Check2:P2";
    System.out.println(s);
    return s;
}


@Bean
@Profile({"!P2", "!P3"})
public String P1() {
    String s = "Check3:P1";
    System.out.println(s);
    return s;
}

@Bean
@Profile("P3")
public String P3_1() {
    String s = "Check4:P3";
    System.out.println(s);
    return s;
}

@Bean
@Profile("P1")
public String P1_1() {
    String s = "Check5:P1";
    System.out.println(s);
    return s;
}
@Bean
@Profile("P2")
public String P2_1() {
    String s = "Check6:P2";
    System.out.println(s);
    return s;
}

我得到的输出为:

Check2:P2
Check3:P1
Check5:P1
Check6:P2

这是正确的。

但是当我在build.xml中将配置文件设置为:

-Dspring.profiles.active=P1

Output:
Check1:P3
Check2:P2
Check3:P1
Check5:P1

但按照我的期望,我希望得到如下输出:

Check3:P1
Check5:P1

(即)只有P1()bean在运行时启动。

如果可以使用@Profiles,有人可以建议我吗? 我可以根据配置文件的排除规则控制运行时启动的bean吗? 或者我怎样才能做到这一点?

基本要求是,如果有' n'豆子。我可以根据传递给环境/服务器目标的参数控制1个bean在运行时启动。

我正在尝试使用可以由不同环境使用的共享代码(其中定义了所有bean)(每个环境需要一个bean才能用于特定环境)?

2 个答案:

答案 0 :(得分:1)

可能个人资料对此不利。

您可能只使用普通的属性。

检查@Conditional批注(Spring 4),甚至更方便的@ConditionalOnExpression(“$ {P1}”)(仅在Spring启动时可用)。

另一个选项 - @Configuration类中的一些手动逻辑,例如:

@Value("${P1}") boolean isP1;

@Bean String p1OrP2() {
    return (isP1) ? "P1" : "P2";
}

对于常见情况,这可能就足够了,例如:这样你可以控制是否使用某些功能(使用完整的实现bean)或不使用(使用一些具有最小行为的bean)。

答案 1 :(得分:0)

通过混合ServiceLocatorFactoryBean和Spring Profiles的概念,我能够通过共享协调代码库来解决我的应用程序按需引导服务于各种业务的问题。

链接: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.html http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html

Spring配置文件帮助按照环境/应用程序上下文和定位器工厂中的指定创建了bean,并创建了一个实现该接口的动态代理,委托给底层BeanFactory,从而通过使用将BeanFactory API与调用代码解耦一个合适的自定义定位器接口