【发布时间】:2021-11-14 03:49:21
【问题描述】:
我注意到 Spring 的 @ComponentScan 注释在用作元注释时存在问题。
在以下示例项目结构中,FirstHandler 和 SecondService 类都应作为组件进行扫描并注册为 bean:
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-
}
}
Command 和相关类是自定义的,与手头的问题无关。出于这个问题的目的,它们充当标记并驻留在不依赖于 Spring 的模块中,因此不能对自身进行元注释。
自定义注释ContextConfiguration 应该扫描所有实现CommandHandler<C> 或使用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 { }
但实际发生的是只使用了第一个@ComponentScan注解,而第二个注解被简单地忽略了。
通过更改注释的顺序或删除一个,我可以更改哪个被忽略/激活,但 Spring 只扫描其中一个类。
这是一个已知问题吗? 有什么解决方案/变通办法吗?
谢谢你,祝你有美好的一天,
亚历克斯。
【问题讨论】:
-
注意:如果需要完整的项目示例,我可以创建一个公共 GitHub 示例项目,尽管这将比上面给出的示例更详细。
标签: java spring-boot annotations component-scan