簡體   English   中英

對不同的注解進行 Spring Boot 掃描

[英]Make Spring Boot Scan for different Annotations

要利用 spring 魔法的全部力量,請使用@Component或任何派生的注釋來注釋您的活動組件,在 Spring 將您的應用程序連接在一起時向后靠並放松。

到現在為止還挺好。

現在我想根據 Clean Architecture/Hexagonal Architecture 模式構建我的應用程序,並希望讓 Spring 遠離我的核心圈,即域。 為了實現這一點,我可以簡單地放棄 spring 魔法並使用一些@Bean提供方法創建幾個@Configuration類。
也就是說,創建大量樣板代碼以及擁有足夠的領域知識來配置所有內容的必要性 - 所以不是我想要的。

我想:我想我的注釋域類型與像注釋@UseCase@Port@Service@Entity@EntityId@ValueObject等meaningfull注解,攜帶關於這些類的領域知識和意圖-和使用盡可能多的spring magic 在外層盡可能地自動化配置,繪制域層中聲明的必要知識。

我可以做到這一點,通過在@UseCase -Annotation 中隱藏一個@Component -Annotation 來隱藏 Spring Dependency,但是我的域部分仍然依賴於 spring - 只是有一些間接性。

我更喜歡的是,告訴 Spring 不要查找@Component而是查找@UseCase 我的想象力告訴我,Spring 的工作方式是這樣的:

for (class in classpath-with-matching-package) {
    if (class has annotation '@Component') {
        createBeanDefinitionForClass(class)
    }
}
createBeansForDefinitions()

我希望,可以通過配置或擴展來告訴執行檢查的方法,該類是否具有@Component -Annotation 以檢查它是否具有其他有意義的注釋。

但是,我不知道什么類和/或方法可能負責此任務。

問題簡述:

  • 哪個類負責查找我的 @Component 注釋類?
  • (如何)我可以影響他們找到 @UseCase 注釋的類,其中 @UseCase 不包含 @Component?

也隨意,恭敬地評論,為什么我的想法是愚蠢的。 那永遠是最有啟發性的!


這是對@Ghokun 的回答的回應,這似乎合理但失敗了

我的示例項目具有以下結構:

src/main/java/de/mycorp/group
 |-> /exampleapp
   |-> NoComponentDemoApp.java
   |-> UseCaseScan.java
 |-> /springless
   |-> SomeUseCase.java
   |-> UseCase.java

NoComponentDemoApp.java:

@SpringBootApplication
public class NoComponentDemoApp
{
    public static void main(String[] args)
    {
        SpringApplication.run(NoComponentDemoApp.class, args);
    }
}

用例掃描.java

@Configuration
@ComponentScan(
         useDefaultFilters = false,
         includeFilters = {
                  @ComponentScan.Filter(UseCase.class)}, // type default/annotation, value synonym of classes
         basePackages = "de.mycorp.group.springless"
)
public class UseCaseScan
{
}

一些用例.java

@UseCase
public class SomeUseCase
{
    private static final Logger logger = LoggerFactory.getLogger(SomeUseCase.class);
    public SomeUseCase()
    {
        logger.info("Some Actor created");
    }
}

用例.java

public @interface UseCase
{
}

辦公室當我啟用默認過濾器並使用@Component標記SomeUseCase.java ,它可以工作。 但有些事情失敗了。 為簡潔起見,我刪除了導入。 可以從結構中推斷出包信息。 如果認為有必要,我會添加它。

Spring 已經通過以下配置為您提供了該選項:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;


@ComponentScan(useDefaultFilters = false,
               includeFilters = {@Filter(type = FilterType.ANNOTATION, class= UseCase.class)})
public class AppConfig {}

文檔鏈接


編輯:

它適用於以下配置。 請檢查您的課程:

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;

@SpringBootApplication
@ComponentScan(useDefaultFilters = false, includeFilters = { @Filter(UseCase.class) })
public class DemoApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    
}

package demo;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@UseCase
public class AnnotatedClass {
    
    private static final Logger logger = LoggerFactory.getLogger(AnnotatedClass.class);
    
    @PostConstruct
    public void init() {
        logger.info("It Works!");
    }
}

package demo;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.stereotype.Indexed;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface UseCase {
    
}
...
2020-09-28 03:25:02.913  INFO 6829 --- [           main] demo.AnnotatedClass: It Works!
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM