有条件的 spring bean 创建

Conditional spring bean creation

我对 Spring 注释配置有疑问。我有一颗豆子:

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

我有一个 属性 文件:

@Autowired
Environment env;

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

createWebsocket=true/false

标志是否应创建 bean ObservationWebSocketClient。如果 属性 值为 false 我根本不想建立网络套接字连接。

有技术实现的可能性吗?

虽然我没有使用过此功能,但您似乎可以使用 spring 4 的 @Conditional annotation

首先,创建一个 Condition class,其中 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 实现。

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

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

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

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

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

这将允许您过滤所需的 profile/profiles,用于生产或暂存以及使用该注释的底层 Bean,它只会在您设置变量 [=] 时由 Springboot 加载19=] 等于 "prod" 和("prod" 或 "stg")。该变量可以在 O.S 上设置。环境变量或使用命令行,例如 -Dspring.profiles.active=prod.