在Spring中,扫描的方式一是基于XML,二是基于Annotation,它们既可以混合使用,又可以隔离使用,但在技术框架的使用中,需要精准地控制它们的扫描范围,一方面可以避免重复注册,另一方面可以避免漏掉核心的服务Bean。
更重要的是,在诸如事务控制的场景中,精准地控制ApplicationContext的扫描一方面可以提高系统性能,加快程序启动速度,另一方面可以避免操作范围混淆,尤其是在Spring 3及之前的版本,必须隔离Web ApplicationContext与Root ApplicationContext,否则事务将无法成功。
下面以XML为例,控制Controller的扫描范围
<context:component-scan base-package="com.stixu" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController"/>
</context:component-scan>
上面的代码片段将ApplicationContext扫描范围局限在Controller与RestController上,需要注意的是,即使此时系统中有@Configuration的类,其定义的@Bean也无法激活。
如果要激活@Configuration,需要在配置中添加如下片段:
<context:component-scan base-package="com.stixu" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController"/>
<!-- 激活@Configuration -->
<context:include-filter type="annotation" expression="org.springframework.context.annotation.Configuration"/>
</context:component-scan>
而在@Configuration中激活XML配置,就太简单了,代码如下:
// 基于Annotation的配置
@Configuration
// XML中的Bean将自动激活
@ImportResource({"classpath:/META-INF/springContext/mvc-context.xml",
"classpath:/META-INF/springContext/booter-context.xml"
})
public class AppConfig {
}
结论
精准控制Spring ApplicationContext的扫描范围可以提高程序的性能,其关键配置是context:include-filter,但要注意,别忽略了@Configuration与XML配置的差异与联系。