【问题标题】:Conditional spring bean creation有条件的spring bean创建
【发布时间】:2015-07-02 20:49:50
【问题描述】:

我有一个关于 Spring 注解配置的问题。我有一颗豆子:

@Bean 
public ObservationWebSocketClient observationWebSocketClient(){
    log.info("creating web socket connection...");
    return new ObservationWebSocketClient();
}

我有一个属性文件:

@Autowired
Environment env;

在属性文件中我想要一个特殊的布尔属性

createWebsocket=true/false

标志是否应该创建一个 bean ObservationWebSocketClient。如果属性值为 false,我根本不想建立 Web 套接字连接。

是否有任何技术上的可能性来实现这一点?

【问题讨论】:

  • 无法直接回答您的问题,但弹簧型材是否适合您?因此 bean 仅在需要它的配置文件中创建(例如测试、开发、生产......)

标签: java spring properties


【解决方案1】:

虽然我没有使用过此功能,但您似乎可以使用 spring 4 的@Conditional annotation 来做到这一点。

首先,创建一个Condition 类,其中ConditionContext 可以访问Environment

public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, 
                           AnnotatedTypeMetadata metadata) {
        Environment env = context.getEnvironment();
        return null != env 
               && "true".equals(env.getProperty("createWebSocket"));
    }
}

然后注释你的bean:

@Bean
@Conditional(MyCondition.class)
public ObservationWebSocketClient observationWebSocketClient(){
    log.info("creating web socket connection...");
    return new ObservationWebSocketClient();
}

edit spring-boot 注解@ConditionalOnProperty 已经实现了这一点; Condition 的源代码用于评估它is available on github here 供感兴趣的人使用。如果您发现自己经常需要这种功能,建议您使用类似的实现,而不是制作大量自定义 Condition 实现。

【讨论】:

  • @chrylis 更好的解决方案是什么?从observationWebSocketClient 方法返回null
  • 已发布(在手机上输入需要一段时间)。
  • 请查看以下使用 ConditionalOnProperty 的建议。这似乎更有效。
  • 如果 createWebsocket=true/false 标志来自数据库怎么办?
【解决方案2】:

@ConditionalOnProperty("createWebSocket")注释你的bean方法。

请注意,Spring Boot 提供了许多预先打包的有用条件。

【讨论】:

  • 这是spring-boot 特定的吗?
  • @beerbajay 我不相信,如果是这样,可以在不启用自动配置的情况下包含注释。它本质上与您的建议非常相似,除了泛化和预先实现。
  • 嗯,似乎只有spring-bootjavadocs
  • 所以在注释中包含工件并且不要使用自动配置。 Boot 的妙处在于它只是核心条件系统之上的一组规则,可以零碎使用。
【解决方案3】:

对于 Spring Boot 2+,您可以简单地使用:

@Profile("prod")
or
@Profile({"prod","stg"})

这将允许您过滤所需的配置文件/配置文件,用于生产或登台以及使用该注释的底层 Bean,只有当您设置变量 spring.profiles.active 等于“prod”时,它才会由 Springboot 加载和(“prod”或“stg”)。该变量可以在 OS 上设置。环境变量或使用命令行,例如 -Dspring.profiles.active=prod。

【讨论】:

    【解决方案4】:

    对于我来说,这个问题可以通过使用 Spring 3.1 @Profiles 来解决,因为@Conditional 注解让你有机会定义一些条件 bean 注册策略(用户定义的条件检查策略),当 @Profiles只能基于 Environment 变量的逻辑。

    【讨论】:

      猜你喜欢
      • 2020-10-05
      • 1970-01-01
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 2012-06-04
      • 2017-04-17
      相关资源
      最近更新 更多