I noticed a problem with Spring's @ComponentScan
annotation when used as a meta-annotation.
In the following example project structure, both the FirstHandler
and SecondService
classes should be scanned as components and registered as beans:
org/example/
|_ ExampleContext.java
|___ api/
| |___ ExampleCommand.java
|___ application/
|___ FirstHandler.java
|___ SecondService.java
// --- ExampleContext.java ---
@ContextConfiguration
public class ExampleContext { }
// --- api/ExampleCommand.java ---
public class ExampleCommand extends Command {
// -snip-
}
// --- application/FirstHandler.java ---
public class FirstHandler implements CommandHandler<ExampleCommand> {
// -snip-
}
// --- application/SecondService.java ---
@CommandService
public class SecondService {
@CommandMethod(ExampleCommand.class)
public void handle(ExampleCommand command) {
// -snip-
}
}
The Command
and related classes are custom, and not relevant to the question at hand. For the purpose of this question, they function as markers and reside in a module which does not depend on Spring, ergo can not be meta-annotated themselves.
The custom annotation ContextConfiguration
is supposed to scan all classes either implementing CommandHandler<C>
or annotated with CommandService
:
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScans({
// Scan for CommandHandler implementations
@ComponentScan(includeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
CommandHandler.class,
})
}),
// Scan for @CommandService annotated classes
@ComponentScan(includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
CommandService.class,
})
})
})
public @interface ContextConfiguration { }
But what actually happens is that only the first @ComponentScan
annotation is used, and the second annotation is simply ignored.
By changing the order of annotations or removing one, I can change which one is ignored/active, but only one of the classes is scanned by Spring.
Is this a known issue? Are there any solutions/workarounds?
Thank you and have a nice day,
Alex.