2

我有一个配置类,它根据一个非常简单的条件(检查 application.properties 中的属性值)注册 bean。配置类和条件如下:

@Configuration
@Conditional(DatabaseConfigurationCondition.class)
@ComponentScan(basePackageClasses = DBConfigComponents.class)
public class DatabaseConfigurationLoader {
    @Bean
    public DatabaseConfigurationRepository databaseConfigurationRepository() {
      return new DatabaseConfigurationRepository();
    }
}

public class DatabaseConfigurationCondition implements Condition {
  @Override
  public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
    return conditionContext.getEnvironment().getProperty("configuration.type").contains("db");
  }
}

除了在这个配置类中注册的 bean 之外,我还有组件扫描,它扫描其他组件。当条件不满足时,我希望配置类中定义的 bean 不会被注册(碰巧是这种情况),但我也希望其他用@Component(or @Repository, @Service, etc..) 注释的类和与不注册的标记接口在同一文件夹中DBConfigComponents.class,这不会发生。被扫描的 Bean 总是被注册,无论条件是否满足。

当我把它@Conditional(DatabaseConfigurationCondition.class)放在每个带@Component注释的类上时,它工作正常,但我不想把它单独放在每个类上。

有什么建议吗?

4

3 回答 3

2

实现这一点的最佳方法是不要使用@Component / @Service 和 @Repository注释来注释这些 bean 。相反,您应该将这些作为您设置的配置的一部分返回,即DatabaseConfigurationLoader. 请参阅下面的示例。

@Configuration
@Conditional(DatabaseConfigurationCondition.class)
public class DatabaseConfigurationLoader {
    @Bean
    public DatabaseConfigurationRepository databaseConfigurationRepository() {
        return new DatabaseConfigurationRepository();
    }

    @Bean
    public SomeService someService() {
        return new SomeService();
    }

    @Bean
    public SomeComponent someComponent() {
        return new SomeComponent();
    }
}

注意:通常@Configurationwith@Conditional用于您想要包含在 Spring Boot 应用程序中的库中。此类库不应与您的 Spring Boot 应用程序共享相同的包。@ComponentScan因此它们不应该被注释拾取。来自库的 Bean 不应使用@Component/ @Service/注释进行@Repository注释。Spring 建议为此使用 AutoConfiguration。请参阅https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.htmlhttps://docs.spring.io/spring-boot/docs/current /reference/html/boot-features-developing-auto-configuration.html

于 2018-08-03T12:44:56.533 回答
2

幸运的是,我设法解决了这个问题。我的问题是我@ComponentScan在其他 Maven 模块的其他配置类中放置了另一个注释 - 不以任何属性为条件。DBConfigComponents与标记接口在同一包中的组件实际上是由其他配置类扫描的。

工作方式@ComponentScan是在包级别。虽然,在不同的 Maven 模块中,两个配置类都在同一个包中。@ComponentScan@Conditional. 无需@Conditional单独放置在每个组件上。

于 2018-08-06T08:06:58.287 回答
0

不需要实现 Condition 接口,你需要使用'@ConditionalOnProperty'注解:

@Configuration
@ComponentScan(basePackageClasses = DBConfigComponents.class)
@ConditionalOnProperty(name = "configuration.type", havingValue = "db")
public class DatabaseConfigurationLoader {
    @Bean
    public DatabaseConfigurationRepository databaseConfigurationRepository() {
      return new DatabaseConfigurationRepository();
    }
}

您可以根据需要使用“前缀”而不是“haveValue”。

于 2018-08-03T12:42:49.747 回答