如何使用@ComponentScan 注解扫描多个路径?
Posted
技术标签:
【中文标题】如何使用@ComponentScan 注解扫描多个路径?【英文标题】:How to scan multiple paths using the @ComponentScan annotation? 【发布时间】:2012-06-03 09:46:42 【问题描述】:我正在使用 Spring 3.1 并使用 @Configuration
和 @ComponentScan
属性引导应用程序。
真正的开始是用
new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);
这个配置类被注释了
@Configuration
@ComponentScan("com.my.package")
public class MyRootConfigurationClass
这很好用。但是我想更具体地了解我扫描的包,所以我尝试了。
@Configuration
@ComponentScan("com.my.package.first,com.my.package.second")
public class MyRootConfigurationClass
但是这失败了,错误提示我找不到使用 @Component
注释指定的组件。
我所追求的正确方法是什么?
谢谢
【问题讨论】:
据我所知,几乎同时给出了两个正确答案。我会接受 hage 只是因为他的分数较低,但谢谢你们俩。 如果您对 kotlin 版本有同样的疑问,请查看***.com/a/62818187/7747942 【参考方案1】:@ComponentScan 使用字符串数组,像这样:
@ComponentScan("com.my.package.first","com.my.package.second")
当你只在一个字符串中提供多个包名时,Spring会将其解释为一个包名,因此无法找到。
【讨论】:
【参考方案2】:还有另一个类型安全 替代可以将基本包位置指定为字符串。 See the API here,但我也在下面进行了说明:
@ComponentScan(basePackageClasses = ExampleController.class, ExampleModel.class, ExmapleView.class)
在你的类引用中使用 basePackageClasses 说明符会告诉 Spring 扫描那些包(就像提到的 alternatives 一样),但是这个方法是 type-安全,并为未来的重构添加了IDE支持——这在我的书中是一个巨大的优势。
从 API 中读取,Spring 建议在您希望扫描的每个包中创建一个无操作标记类或接口,除了用作此属性的引用/用作此属性的引用之外,别无其他目的。
IMO,我不喜欢标记类(但话又说回来,它们很像 package-info 类),但类型安全、IDE 支持和大幅减少毫无疑问,此扫描需要包含的基本软件包数量是一个更好的选择。
【讨论】:
有人可以解释为什么 @ComponentScan("com.app", "com.controllers") 对我不起作用,但 @ComponentScan(basePackageClasses ="com.controllers") 对我有用工作好吗?我觉得写每个班级的名字很无聊 您只需要在包中指定一个类,用于您要扫描的包。这称为标记类。如果您需要扫描层次结构中没有类的更高包,spring 建议使用“spring marker”接口或在该包中定义的最终类的技术,仅用于包扫描。 谢谢。我厌倦了用 string-magic/magic-strings 追踪#wheresWaldo。【参考方案3】:单独提供你的包名,包名需要String[]
。
而不是这个:
@ComponentScan("com.my.package.first,com.my.package.second")
使用这个:
@ComponentScan("com.my.package.first","com.my.package.second")
【讨论】:
Java 的“什么时候是逗号分隔”、“什么时候是字符串数组”、“什么时候是字符串可变参数”拼图有时让我发疯。【参考方案4】:另一种方法是使用basePackages
字段;这是 ComponentScan 注释中的一个字段。
@ComponentScan(basePackages="com.firstpackage","com.secondpackage")
如果您从 jar 文件中查看 ComponentScan 注释 .class,您将看到一个 basePackages 字段,该字段接受字符串数组
public @interface ComponentScan
String[] basePackages() default ;
或者您可以明确提及这些类。其中包含类数组
Class<?>[] basePackageClasses
【讨论】:
【参考方案5】:你使用 ComponentScan 来扫描多个包
@ComponentScan("com.my.package.first","com.my.package.second")
【讨论】:
【参考方案6】:你也可以使用@ComponentScans注解:
@ComponentScans(value = @ComponentScan("com.my.package.first"),
@ComponentScan("com.my.package.second") )
【讨论】:
请考虑在您的答案中添加解释【参考方案7】:确保您已在 pom.xml 中添加此依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
【讨论】:
谢谢,花了将近半个小时,这是缺少的依赖 Spring Context 是这些注解唯一需要的依赖。【参考方案8】:我用:
@ComponentScan(basePackages = "com.package1","com.package2","com.package3", "com.packagen")
【讨论】:
以上是关于如何使用@ComponentScan 注解扫描多个路径?的主要内容,如果未能解决你的问题,请参考以下文章
spring注解第02课 包扫描@ComponentScan@ComponentScans
Spring注解详解:@ComponentScan自动扫描组件使用