繁体   English   中英

如何禁用在 Spring 中使用 @Component 注释创建 bean?

[英]How can I disable creating bean with @Component annotation in Spring?

我的项目中有一些用于重构逻辑的通用接口。 它看起来像这样:

public interface RefactorAwareEntryPoint {

    default boolean doRefactor() {
        if (EventLogService.wasEvent(getEventType())) {
            return true;
        }
        boolean result = doRefactorInternal();
        if (result) {
            EventLogService.registerEvent(eventType);
        }
        return result;
    }

    String getEventType();
    
    boolean doRefactorInternal();
}

然后,当我需要编写一些重构时 - 我用方法实现这个接口,标记类@Component ,并且 Spring 循环评估每个接口实现并将其注册到数据库中。 但是我们有很多重构(每年 - 200-300 个新)。 手动禁用旧的实现很难,而且我们的 spring 上下文中有很多 bean。 我们可以做些什么,例如,使用一些注释——这将在某些条件下禁用组件创建?

例如:

@Component
@Enabled(YEAR.2020)
public class CustomRefactor implements RefactorAwareEntryPoint {
 // Code implementation
}

这个注解会像这样工作(伪代码):

if (YEAR.2020) {
  create bean -> new CustomRefactor()
}

什么时候是YEAR.2021 - 在春季背景下,我们将没有来自YEAR.2020 bean。

使用注释@Profile使应用程序配置和 bean 在某些环境中可用。

您可以在Spring Boot 2.4.0 参考文档中找到更多信息:3. Profiles

Spring Profiles 提供了一种分离应用程序配置部分并使其仅在某些环境中可用的方法。 任何@Component、@Configuration 或@ConfigurationProperties 都可以用@Profile 标记以限制加载时

将每年视为一个单独的环境。

@Component
@Profile("2020")
public class CustomRefactor2020 implements RefactorAwareEntryPoint {
 // Code implementation
}
@Component
@Profile("2021")
public class CustomRefactor2021 implements RefactorAwareEntryPoint {
 // Code implementation
}

除了我们同事提供的答案,请考虑 spring 称为“Stereotype annotations”的特性。 这就是像@Service这样著名的注解在 spring 中定义的方式。

通常,使用@Component批注标记类这一事实允许您将该类作为 spring bean 加载,因为带批注的类成为称为“组件扫描”过程的主题 - 当您启动应用程序上下文时会发生一个过程。

从 spring 4 开始,有一个条件接口基本上可以实现类似于您所说的@Enabled(YEAR.2020)的逻辑。

您可以使用内置的“@ConditionalOnProperty”将 2020 年映射到属性,甚至实现自定义条件逻辑 我假设您已将自定义条件实现为@ConditionalOnYear

现在,有趣的是(这是我在文章开头提到的“刻板印象”功能)是您可以使用自定义“条件”逻辑创建自己的“组件”注释并“好像”使用它它是一个普通的豆子:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ConditionalOnYear(2020)
@Component
public @interface Year2020OnlyComponent {

    @AliasFor(annotation = Component.class)
    String value() default "";

}
@Year2020OnlyComponent
public class CustomRefactor implements RefactorAwareEntryPoint {
 // Code implementation
}

您还可以通过巧妙地使用@AliasFor注释来改进它,例如:

@SinceYearComponent(2020)
public class CustomRefactor implements RefactorAwareEntryPoint {
 // Code implementation
}

但这有点超出了这个问题的范围 - 所以我在这里只提到一个方向。

当然,即使没有此“定型”注释功能,也可以仅使用您建议的两个注释:

@Component
@SinceYear(2020) // a custom conditional
public class CustomRefactor implements RefactorAwareEntryPoint {
 // Code implementation
}

查看 BeanFactoryPostprocessor 接口。 可能您可以在创建 bean 之前将其删除。

否则,您可能会实现自己的 BeanFactory 并使用您的实现创建 ApplicationContext。

您可以使用 spring boot 提供的 excludeFilter 注释。

  1. 正如其他人所提到的,您始终可以使用@Profile注释来启用/禁用配置文件。
  2. 另一种选择是excludeFilter

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM