[英]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 以檢查它是否具有其他有意義的注釋。
但是,我不知道什么類和/或方法可能負責此任務。
問題簡述:
也隨意,恭敬地評論,為什么我的想法是愚蠢的。 那永遠是最有啟發性的!
這是對@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.