[Spring实战系列](14)Bean的自动检测

即使<context:annotation-config>有助于完全消除Spring注解中的<property>和<constructor-arg>元素,但是还是不能完全消除,仍然需要使用<bean>元素显示定义Bean。因此<context:component-scan>元素出现了,它除了完成<context:annotation-config>一样的工作,还允许Spring自动检测Bean定义Bean。这就意味着我们不使用<bean>元素,Spring应用中的大多数(或者所有)Bean都能够实现定义和装配。

为了配置Spring自动检测,需要使用<context:component-scan>元素来代替<context:annotation-config>元素:


<?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.xsd

		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	

	<context:component-scan base-package="">

	</context:component-scan>

 

</beans>

<context:component-scan>元素会扫描指定的包以及所有子包,并查找出能够自动注册为Spring Bean的类。base-package属性标示了<context:component-scan>元素所扫描的包。

为自动检测标注Bean

默认情况下,<context:component-scan>查找使用构造型(stereotype)注解所标注的类,这些特殊的注解如下:

类型 说明
@component 通用的构造型注解,标示该类为Spring 组件。
@Controller 标识将该类定义为Spring MVC controller。
@Repository 标识将该类定义为数据仓库(例如:Dao层)。
@Service 标识将该类定义为服务(例如:Service层)。

1. @component

假设我们应用上下文中仅仅包含Student和School两个Bean。我们可以配置<context:component-scan>元素并使用@Component注解标注Student和School类,从而消除显示的<bean>定义。


package com.sjf.bean;

 

import org.springframework.stereotype.Component;

 

/**

 * 学校实体类

 * @author sjf0115

 *

 */

@Component

public class School {

	private String name;

	private String location;

	

	...

}

Spring扫描com.sjf.bean包时,会发现使用Component注解所标注的School,并自动将它注册为Spring Bean。Bean的ID默认为无限定类名(第一个字母小写),School
Bean的ID为school。

下面我们标注Student类:


package com.sjf.bean;

 

import org.springframework.stereotype.Component;

 

/**

 * 学生实体类

 * @author sjf0115

 *

 */

@Component("studentBean")

public class Student {

	

	private String name;

	private int age;

	private School school;

	

	...

}

这种场景下,我们指定了一个Bean ID作为@Component注解的参数。该Bean 的ID不会使用默认的类名,而是显示的命名为studentBean。

当使用<context:component-scan>时,基于注解的自动检测只是一种扫描策略。下面让我们来了解其他的扫描策略来查找候选Bean。

2. 过滤组件扫描

在如何扫描来获得候选Bean方面,<context:component-scan>元素非常灵活。通过为<context:component-scan>配置<context:include-filter>和<context:exclude-filter>子元素,我们可以随意调整扫描行为。

假设我们基于注解让<context:component-scan>自动注册所有实现某个接口的类,我们不得不浏览每一个接口实现的类,并使用@Component来标注它们,非常不方便。所以我们替换掉基于注解的组件扫描策略,再增加一个包含过滤器来要求<context:component-scan>注册以及排除类。


<context:component-scan base-package="com.sjf.bean">

	<context:include-filter type="" expression=""/>

	<context:exclude-filter type="" expression=""/>

</context:component-scan>

<context:include-filter>的type和expression属性一起协作来定义组件扫描策略。我们还可以选择如下任意一种过滤器:

类型 说明
annotation 过滤器扫描使用指定注解标注的那些类,通过expression属性指定要扫描的注解
assignable 过滤器扫描派生于expression属性所指定类型的那些类。
aspectj 过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类。
custom 使用自定义的org.springframework.core.type.TypeFilter实现类,该类由expression属性指定。
regex 过滤器扫描类的名称与expression属性所指定的正则表达式所匹配的那些类。

除了使用<context:include-filter>告知<context:component-scan>哪些类需要注册为Spring Bean以外,我们还可以使用<context:exclude-filter>来告知<context:component-scan>哪些类不需要注册为Spring Bean。

我们实现了两个接口,一个是Worker接口(员工),一个是Performer(表演者)。然后根据这两个接口,分别实现了接口的实现类:


package com.sjf.bean;

/**

 * 农民实体类

 * @author sjf0115

 *

 */

public class Farmer implements Worker {

 

	public void work() {

		System.out.println("正在辛勤的耕地...");

	}

}

我们使用<context:include-filter>告知<context:component-scan>实现了Worker接口的实现类需要注册为Spring Bean,使用<context:exclude-filter>来告知实现了Perfomer接口的实现类不需要注册为Spring Bean。


<context:component-scan base-package="com.sjf.bean">

	<context:include-filter type="assignable" expression="com.sjf.bean.Worker"/>

	<context:exclude-filter type="assignable" expression="com.sjf.bean.Performer"/>

</context:component-scan>

我们测试一下上述过滤器是否起作用了:


Farmer farmer = (Farmer) context.getBean("farmer");

farmer.work();

运行结果:

正在辛勤的耕地...  


Singer singer = (Singer) context.getBean("singer");

singer.perform();

运行结果:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘singer‘ is defined  

参考:《Spring实战》

时间: 2024-10-10 04:28:56

[Spring实战系列](14)Bean的自动检测的相关文章

Skype For Business 2015实战系列14:创建Office Web App服务器场

Skype For Business 2015实战系列14:创建Office Web App服务器场 前面的操作中我们已经成功的安装了Office Web App Server,今天我们将创建Office Web App服务器场.具体步骤如下: 配置证书: 登陆到OWA服务器,打开服务器管理器,点击"工具"-"IIS管理器": 双击证书: 点击创建域证书: 输入通用名称及基本信息,点击下一步: 选择证书颁发机构并设置友好名称,点击完成: 完成以后我们的OWA使用的证

Spring基础系列5 -- bean的基本用法

Spring基础系列5 -- bean的基本用法 转载:http://www.cnblogs.com/leiOOlei/p/3532604.html 本篇讲述了Bean的基本配置方法,以及Spring中怎样运用Bean. 主要内容如下: 一.      Spring中Bean的相互引用 二.      Spring中给Bean属性注入value 三.      Spring Inner Bean—内部嵌套的Bean 四.      Spring Bean Scopes—Bean的作用域 五.  

[Spring实战系列](10)初探Bean生命周期

1. 生命周期流程图 Bean在Spring容器中从创建到销毁经历了若干个阶段,在每一个阶段都可以针对Spring如何管理Bean进行个性化定制. 正如你所见,在Bean 准备就绪之前,Bean 工厂执行了若干启动步骤. Spring 对Bean 进行实例化. Spring 将值和Bean 的引用注入进Bean 对应的属性中. 如果Bean 实现了BeanNameAware接口,Spring 将Bean的ID传递给setBeanName() 接口方法. 如果Bean 实现了BeanFactory

[Spring实战系列](6)配置Spring IOC容器的Bean

1. 简介 Spring提供了一个强大的IOC容器来管理组成应用的bean.为了利用容器服务,必须配置运行于Spring IOC容器中的Bean. 2. 解决方案 你可以通过XML文件,属性文件,注释甚至API来设置Spring IOC容器中的Bean. Spring允许你在一个或者多个bean配置文件中配置bean.对于简单的应用程序,可以在单个配置文件中集中配置bean.但是对于有许多bean的大型应用,你应该根据其功能将其分割到多个配置文件中. 3. 创建Spring配置 正如前面所讲的,

[Spring实战系列](18)注解切面

使用注解来创建切面是AspectJ 5所引入的关键特性.在AspectJ 5之前,编写AspectJ切面需要学习一种Java语言的扩展,但是AspectJ面向注解的模型可以非常简单的通过少量注解把任意类转变为切面. 回顾一下Audience类,没有任何地方让它成为一个切面,我们不得不使用XML声明通知和切点. 我们通过@AspectJ注解,我们再看看Audience类,不需要任何额外的类或Bean声明就能将它转换为一个切面. package com.sjf.bean; /** * 歌手实体类 *

[Spring实战系列](8)Spring注入方式之setter注入

通常,JavaBean 的属性是私有的,同时拥有一组存取器方法,以setXXX() 和getXXX() 形式存在.Spring 可以借助属性的set方法来配置属性的值,以实现setter方式的注入. 1. 注入简单值 在Spring 中我们可以使用<property> 元素配置Bean 的属性.<property>在许多方面都与<constructor-arg> 类似,只不过一个是通过构造参数来注入值,另一个是通过调用属性的setter 方法来注入值. 举例说明,让我们

[Spring实战系列](15)使用Spring基于Java的配置

并不是所有的开发人员都喜欢使用XML,所以Spring3.0 为这些人准备了一些特别的东西.可以几乎不使用XML而使用纯粹的Java代码来配置Spring应用.并且基于Java的配置拥有一些XML配置所不具有的技巧. 1. 创建基于Java的配置 即使Spring的Java配置可以让我们不使用XML就可以编写大多数的Spring配置,但是我们仍然需要极少量的XML来启用Java配置. <?xml version="1.0" encoding="UTF-8"?&

[Spring实战系列](11)SpEL使用表达式装配

到目前为止,我们为Bean 的属性和构造器参数装配的所有东西都是在Spring 的XML 配置文件中静态定义的. <bean id = "yoona" class = "com.sjf.bean.Student"> <property name="name" value = "yoona"/> <property name="hobby" value = "踢足球,打

[Spring实战系列](16)面向切面编程(AOP)概述

1. 简介 在软件中,有些行为对于大多数应用都是通用的.日志,安全和事务管理的确很重要,但他们是都是应用对象主动参与的行为呢?如果让应用对象只关注自己所针对的业务领域问题,而其他方面的问题由其他应用对象来处理,这样会不会更好? 在软件开发中,分布于应用中多处的功能被称为横切关注点.通常,这些横切关注点从概念上是与应用的业务逻辑相分离的(但是往往直接嵌入到应用的业务逻辑中).将这些横切关注点与业务逻辑相分离是面向切面编程索要解决的. 上图展示了一个被划分为模块的典型应用.每个模块的核心功能都是为特