将包添加到组件扫描

时间:2014-08-18 16:02:57

标签: java spring component-scan

我有一个带有Spring容器的项目。假设此项目名为my-common-library,并使用名称空间my.common。它会扫描此命名空间中的所有组件,如common-context.xml中所示,如下所示

<beans ...>
    <context:component-scan base-package="my.common"/>
</beans>

此扫描会检测用@MyComponent注释的类。

现在我想尽可能完全重用这个项目。假设我开始在命名空间my-client中使用的新项目my.clientmy-client主要由使用@MyComponent注释的组件组成。

在理想世界中,我只会添加依赖项my-common-library,并且将扫描并注册所有@MyComponent。唯一的问题是原始my-common-library未知新命名空间。

我知道的一个解决方案是将更新后的common-context.xml添加到my-client,看起来像

<beans ...>
    <context:component-scan base-package="my.common,my.client"/>
</beans>

这肯定有用,但似乎很脆弱。是否有更优雅的解决方案?

2 个答案:

答案 0 :(得分:10)

在我看来,尝试通过组件扫描从库实现组件注册总是很脆弱。

如果您只是重用代码,我建议明确导入my-common-library依赖项。例如,使用基于Java的Spring配置:

@Configuration
@ComponentScan("my.common") 
public class MyCommonLibraryConfig {


}

在'my-client`上:

@Configuration
@Import(MyCommonLibraryConfig.class)
@ComponentScan("my.client") 
public class MyClientConfig {

}

由于my-client始终取决于my-library,因此最好明确定义依赖关系。

另一方面,如果您真正想要的是实现类似插件系统的东西,那么您将需要使用一些基于包的约定来发现依赖关系,因为使用依赖关系的组件在运行之前不知道它的依赖关系-时间。

在这种情况下,我建议定义一个注册包名称,例如my.plugin,然后依赖于插件的组件的Spring配置只需要在my.plugin上定义组件扫描,并且每个插件只需要在同一个@Components包中定义其@Configurations或其my.plugin bean。

如果需要更多控制,可以在组件扫描中添加一个过滤器,以便只注册带有特定注释的bean。例如,假设您定义了@MyPlugin注释:

@ComponentScan(
   basePackages = {"my.plugin"},
   includeFilters = @ComponentScan.Filter(
      value= MyPlugin.class, 
      type = FilterType.ANNOTATION
   )
)

答案 1 :(得分:1)

我认为 Ricardo Veguilla 提出了不错的选择。但另一种(有时更好)的方法是为此目的使用弹簧启动器。您可以在依赖项内的 spring.factories 文件中声明 bean,并在主代码外预先配置所需的 bean。