4.10 类路径扫描和管理的组件

本章中的大多数示例都使用了 XML 来指定配置元数据在 Spring 的容器中生产每一个 BeanDefinition。之前的章节(4.9 节,“基于注解的容器配置”)表述了如何通过代码级 的注解来提供大量的配置信息。尽管在那些示例中,“基础的”bean 的定义都是在 XML 文 件中来明确定义的,而注解仅仅进行依赖注入。本节来说明另外一种通过扫描类路径的方式 来隐式检测候选组件。候选组件是匹配过滤条件的类库,并有在容器中注册的对应的 bean 的定义。这就可 以不用 XML 来执行 bea n 的注册了 ,那么你就 可以使用注 解(比如 @Component),AspectJ 风格的表达式,或者是你子定义的过滤条件来选择那些类会有在容 器中注册的 bean。

注意

从 Spring 3.0 开始,很多由 Spring JavaConfig 项目提供的特性作为 Spring Framework 核心 的一部分了。这就允许你使用 Java 而不是传统的 XML 文件来定义 bean 了。看一看 @Configuration,@Bean,@Import 和@DependsOn 注解的例子来使用它们的新特性。

4.10.1 @Component 和更多典型注解

在 Spring 2.0 版之后,@Repository 注解是任意满足它的角色或典型(比如熟知的数 据访问对象,DAO)库的类的标记。在这个标记的使用中,就是在 14.2.2 节,“表达式翻译” 中描述的表达式自动翻译。

Spring 2. 5 引 入 了 更 多 的 注 解 : @Component , @Service 和 @Controller 。

@Component 是对 Spring 任意管理 组件的通用刻 板。@Repository ,@Service 和 @Controller 是对更多的特定用例@Component 的专业化,比如,在持久层,服务层和 表现层。因此,你可以使用@Component 注解你的组件类,但是使用@Repository, @Service 或@Controller 注解来替代的话,那么你的类更合适由工具来处理或和不同的方面相关联。比如,这些刻板注解使得理想化的目标称为切入点。而且@Repository, @Service 和@Controller 也可以在将来 Spring Framework 的发布中携带更多的语义。因此,如果对于服务层,你在@Component 或@Service 中间选择的话,那么@Service 无 疑是更好的选择。相似地,正如上面提到的,在持久层中,@Repository 已经作为自动异 常翻译的表示所被支持

4.10.2 自动检测类和 bean 的注册

Spring 可 以 自 动 检 测 刻 板 类 并 在 ApplicationContext 中 注 册 对 应 的BeanDefinition。比如,下面的两个类就是自动检测的例子:

@Service
public class SimpleMovieLister {
    private MovieFinder movieFinder;
    @Autowired
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}
@Repository
public class JpaMovieFinder implements MovieFinder {
    //为了清晰省略了实现
}

要 自 动检 测这 些类 并注 册对 应的 bean ,你 需要 包含 如下 的 XML 元素 ,其 中 的 base-package 元素通常是这两个类的的父包。(也就是说,你可以指定以逗号分隔的列表来 为每个类引入父包。)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema -instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring -beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan base-package="org.example"/>
</beans>

注意

对类路径包的扫描需要存在类路径下对应的目录。当你使用 Ant 来构建 JAR 包时,要保 证你没有激活 JAR 目标中的 files-only 开关。

此 外 , 当 你 使 用 component-scan ( 组 件 - 扫 描 , 译 者 注 ) 时 , AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 二者都是隐式包含的。这就意味着两个组件 被自动检测之后就装配在一起了-而不需要在 XML 中提供其它任何 bean 的配置元数据。

注意

你 可 以 将 annotation-config 属 性 置 为 false 来 关 闭 AutowiredAnnotationBeanPostProcessor 的 CommonAnnotationBeanPostProcessor 注册。

4.10.3 使用过滤器来自定义扫描

默认情况下,使用@Component,@Repository,@Service,@Controller 注解 或使用了进行自定义的@Component 注解的类本身仅仅检测候选组件。你可以修改并扩展 这 种 行 为, 仅仅 应 用自 定 义的 过 滤器 就 可以 了。 在 component-scan 元素中添加 include-filter 或 exclude-filter 子元素就可以了。每个过滤器元素需要 type 和 expression 属性。下面的表格描述了过滤选项。

表 4.5 过滤器类型