如何使用@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 注解扫描多个路径?的主要内容,如果未能解决你的问题,请参考以下文章

ComponentScan注解的扫描范围及源码解析

spring注解第02课 包扫描@ComponentScan@ComponentScans

Spring注解详解:@ComponentScan自动扫描组件使用

002 包扫描注解@ComponentScan

Spring注解——使用@ComponentScan自动扫描组件

注解@componentscan