如何使用@ComponentScan批注扫描多个路径?


89

我正在使用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注释指定的组件。

做我追求的正确方法是什么?

谢谢


据我所知,大约在同一时间给出了两个正确答案。我会因为他的得分少而让接受者拥抱,但谢谢你们俩。
编程专家

如果您想知道Kotlin版本是否具有相同的功能,请检查此stackoverflow.com/a/62818187/7747942
Sylhare

Answers:


159

@ComponentScan使用字符串数组,如下所示:

@ComponentScan({"com.my.package.first","com.my.package.second"})

当您仅在一个字符串中提供多个包名称时,Spring会将其解释为一个包名称,因此找不到它。


48

还有一种类型安全的 替代方法,可以将基本程序包的位置指定为String。请参阅此处的API,但下面也进行了说明:

@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})

使用 basePackageClasses说明符与您的类引用一起使用将告诉Spring扫描那些包(就像提到的替代方法一样),但是此方法既是类型安全的,又为将来的重构添加了IDE支持-这对我的书来说是一个很大的优点。

从API读取,Spring建议在您希望扫描的每个程序包中创建一个无操作标记类或接口,该类或接口除了用作/为此属性的引用之外,没有其他用途。

IMO,我不喜欢标记类(但是再说一次,它们非常像package-info类)但是类型安全,IDE支持并大大减少了此扫描所需的基本软件包数量毫无疑问,这是一个更好的选择。


有人可以解释为什么@ComponentScan({“ com.app”,“ com.controllers”})对我不起作用,但是@ComponentScan(basePackageClasses = {“ com.controllers”})可以正常工作吗?我发现每个班级名称都写得很无聊
xaverras 2015年

3
您只需要在软件包中为要扫描的软件包指定一个类。这称为标记类。如果您需要在没有类的层次结构中扫描更高级别的软件包,则spring建议仅在软件包扫描中使用“ spring marker”接口或该软件包中定义的最终类的技术。
Prancer

17

分别提供您的软件包名称,String[]对于软件包名称,需要输入。

代替这个:

@ComponentScan("com.my.package.first,com.my.package.second")

用这个:

@ComponentScan({"com.my.package.first","com.my.package.second"})

10

另一种方法是使用basePackages字段。这是ComponentScan批注中的一个字段。

@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})

如果您从jar文件中查看ComponentScan批注.class,您将看到一个包含字符串数组的basePackages字段

public @interface ComponentScan {
String[] basePackages() default {};
}

或者,您可以明确提及这些类。这需要类的数组

Class<?>[]  basePackageClasses

4

您可以使用ComponentScan扫描多个软件包,方法是:

@ComponentScan({"com.my.package.first","com.my.package.second"})



1

我用:

@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})

0

您还可以使用@ComponentScans批注:

@ComponentScans(value = { @ComponentScan("com.my.package.first"),
                          @ComponentScan("com.my.package.second") })

4
请考虑在您的答案中添加解释
yeya
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.