簡體   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