diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/classes/spring/annotations/AnnotationClassScanner.java b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/classes/spring/annotations/AnnotationClassScanner.java index d56f570f6..0bd8816e4 100644 --- a/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/classes/spring/annotations/AnnotationClassScanner.java +++ b/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/scanners/classes/spring/annotations/AnnotationClassScanner.java @@ -12,6 +12,7 @@ import org.springframework.util.StringUtils; import java.lang.annotation.Annotation; +import java.util.Arrays; import java.util.Optional; import java.util.Set; @@ -28,8 +29,8 @@ public class AnnotationClassScanner implements ClassScanne @Override public Set> scan() { - String basePackage = asyncApiDocketService.getAsyncApiDocket().getBasePackage(); - if (!StringUtils.hasText(basePackage)) { + String basePackages = asyncApiDocketService.getAsyncApiDocket().getBasePackage(); + if (!StringUtils.hasText(basePackages)) { throw new IllegalArgumentException("Base package must not be blank"); } @@ -38,12 +39,15 @@ public Set> scan() { provider.addIncludeFilter(new AnnotationTypeFilter(annotation)); - log.debug("Scanning for {} classes in {}", annotation.getSimpleName(), basePackage); - return provider.findCandidateComponents(basePackage).stream() - .map(BeanDefinition::getBeanClassName) - .map(this::getClass) - .filter(Optional::isPresent) - .map(Optional::get) + return Arrays.stream(basePackages.replaceAll("\\s", "").split(",")) + .flatMap(basePackage -> { + log.debug("Scanning for {} classes in {}", annotation.getSimpleName(), basePackage); + return provider.findCandidateComponents(basePackage).stream() + .map(BeanDefinition::getBeanClassName) + .map(this::getClass) + .filter(Optional::isPresent) + .map(Optional::get); + }) .collect(toSet()); } diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/configuration/docket/AsyncApiDocket.java b/springwolf-core/src/main/java/io/github/springwolf/core/configuration/docket/AsyncApiDocket.java index 9cb2470fa..3ff016e4b 100644 --- a/springwolf-core/src/main/java/io/github/springwolf/core/configuration/docket/AsyncApiDocket.java +++ b/springwolf-core/src/main/java/io/github/springwolf/core/configuration/docket/AsyncApiDocket.java @@ -16,7 +16,8 @@ public class AsyncApiDocket { /** - * The base package containing the declarations of consumers and producer beans. + * The base package(s) containing the declarations of consumers and producer beans. + * Comma-separated for multiple base packages. */ private final String basePackage; diff --git a/springwolf-core/src/main/java/io/github/springwolf/core/configuration/properties/SpringwolfConfigProperties.java b/springwolf-core/src/main/java/io/github/springwolf/core/configuration/properties/SpringwolfConfigProperties.java index faad3e335..b503820c1 100644 --- a/springwolf-core/src/main/java/io/github/springwolf/core/configuration/properties/SpringwolfConfigProperties.java +++ b/springwolf-core/src/main/java/io/github/springwolf/core/configuration/properties/SpringwolfConfigProperties.java @@ -117,7 +117,8 @@ public static class ConfigDocket { public static final String DEFAULT_CONTENT_TYPE = "application/json"; /** - * The base package to scan for listeners which are declared inside a class annotated with @Component or @Service. + * The base package(s) to scan for listeners which are declared inside a class annotated with @Component or @Service. + * Comma-separated for multiple base packages. * * @see AsyncApiDocket.AsyncApiDocketBuilder#basePackage(String) */ diff --git a/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/classes/spring/ComponentClassScannerIntegrationTest.java b/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/classes/spring/ComponentClassScannerIntegrationTest.java index b63992356..99443cbde 100644 --- a/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/classes/spring/ComponentClassScannerIntegrationTest.java +++ b/springwolf-core/src/test/java/io/github/springwolf/core/asyncapi/scanners/classes/spring/ComponentClassScannerIntegrationTest.java @@ -6,6 +6,7 @@ import io.github.springwolf.core.asyncapi.scanners.classes.TestComponent; import io.github.springwolf.core.asyncapi.scanners.classes.TestConditionalComponent; import io.github.springwolf.core.asyncapi.scanners.classes.TestOtherConditionalComponent; +import io.github.springwolf.core.asyncapi.scanners.classes2.TestComponent2; import io.github.springwolf.core.configuration.docket.AsyncApiDocket; import io.github.springwolf.core.configuration.docket.AsyncApiDocketService; import org.junit.jupiter.api.BeforeEach; @@ -49,7 +50,8 @@ void setUp() { .title("ComponentClassScannerTest-title") .version("ComponentClassScannerTest-version") .build()) - .basePackage("io.github.springwolf.core.asyncapi.scanners.classes") + .basePackage("io.github.springwolf.core.asyncapi.scanners.classes, " + + "io.github.springwolf.core.asyncapi.scanners.classes2") .build()); } @@ -62,7 +64,7 @@ void getComponents() { assertThat(components) .doesNotContain(TestBeanConfiguration.TestBean.class) - .contains(TestComponent.class) + .contains(TestComponent.class, TestComponent2.class) .doesNotContain(TestConditionalComponent.class) .doesNotContain(TestOtherConditionalComponent.class); } @@ -76,7 +78,7 @@ void getComponentsIncludesConditional() { assertThat(components) .doesNotContain(TestBeanConfiguration.TestBean.class) - .contains(TestComponent.class) + .contains(TestComponent.class, TestComponent2.class) .contains(TestConditionalComponent.class) .doesNotContain(TestOtherConditionalComponent.class); }