8.2 Spring的”零配置”支持
以前的Java
框架大多采用XML
作为配置文件,时至今日,也许是受Rails
框架的启发,几乎所有的主流Java
框架都打算支持"零配置"
特性。现在要介绍的Spring
,都开始支持使用注解来代替XML
配置文件。
8.2.1 搜索Bean类
既然不再使用Spring
配置文件来配置任何Bean
实例,那么只能希望Spring
会自动搜索某些路径下的Java
类,并将这些Java
类注册成Bean
实例。
Rails框架的做法
Rails
框架的处理比较简单,它采用一种所谓的”约定优于配置”的方式,它要求将不同组件放在不同路径下,而Rails
框架中是加载固定路径下的所有组件。
Spring框架的做法
Spring
没有采用”约定优于配置”的策略,** Spring
依然要求程序员显式指定搜索哪些路径下的Java
类, **Spring
将会把合适的Java
类全部注册成Spring Bean
。
标注Bean类的注解
那现在的问题是:Spring
怎么知道应该把哪些Java
类当成Bean
类处理呢?这就需要使用注解了, Spring
通过使用一些特殊的注解来标注Bean
类。Spring
提供了如下几个注解来标注Spring Bean
。
注解 | 描述 |
---|---|
@Component |
标注一个普通的Spring Bean 类。 |
@Controller |
标注一个控制器组件类。 |
@Service |
标注一个业务逻辑组件类。 |
@Repository |
标注一个DAO 组件类。 |
如果需要定义一个普通的Spring Bean ,则直接使用@Component 标注即可。但如果用@Reepository 、@Service 或@Controller 来标注这些Bean 类,这些Bean 类将被作为特殊的Java EE 组件对待,也许能更好地被工具处理,或与切面进行关联。例如,这些典型化的注解可以成为理想的切入点目标。 |
|
@Controller 、@Service 和@Repository 能携带更多语义,因此,如果需要在Java EE 应用中使用这些标注时,应尽量考虑使用@Controller 、@Service 和@Repository 来代替通用的 @Component 标注。 |
|
## 使用context Schema指定搜索路径 ## | |
指定了某些类可作为Spring Bean 类使用后,最后还需要让Spring 搜索指定路径,此时需要在Spring 配置文件中导入 context Schema ,并指定一个简单的搜索路径。 |
下面示例定义了一系列Java
类,并使用@Component
来标注它们。
1 | package org.crazyit.app.service.impl; |
1 | package org.crazyit.app.service.impl; |
这些Java
类与前面介绍的Bean
类没有太大区别,只是每个Java
类都使用了@Component
标注,这表明这些Java
类都将作为Spring
的Bean
类。
接下来需要在Spring
配置文件中指定搜索路径, Spring
将会自动搜索该路径下的所有Java
类,并根据这些Java
类来创建Bean
实例。本应用的配置文件如下。
1 |
|
上面的配置文件中最后一行代码指定Spring
将会把org.crazyit.app.service
包及其子包下的所有Java
类都当成Spring Bean
来处理,并为每个Java
类创建对应的Bean
实例。经过上面的步骤, Spring
容器中自动就会增加三个Bean
实例(前面定义的三个类都是位于org.crazyit.app.service.impl
包下的)。
主程序如下:
1 | package lee; |
上面程序中输出了Spring
容器中所有Bean
实例的名称,运行上面的程序,将看到如下输出结果:
1 | chinese |
使用注解方式时将类名首字母变小写得到Bean的名称
从上面的运行结果可以看出, Spring
容器中三个Bean
实例的名称分别为chinese
、 steelAxe
和stoneAxe
,那么这些名称是从哪里来的呢?
- 在基于
XML
配置方式下,每个Bean
实例的名称都由其id
属性指定的; - 在基于注解的方式下,
Spring
通过将该Bean
类的类名的首字母变成小写,其他字母不变的规则得到Bean
的名称。
使用注解设置Bean的名称
当然Spring
也允许在使用@Component
标注时指定Bean
实例的名称,例如如下代码片段:
1 | "axe") ( |
上面程序中的粗体字代码指定该Bean
实例的名称为axe
.
在默认情况下, Spring
会自动搜索所有以@Component
、@Controller
、@Service
和@Repository
标注的Java
类,并将它们当成Spring Bean
来处理。
@Lookup注解执行方法注入
Spring
还提供了@Lookup
注解来执行lookup
方法注入,其实 @Lookup
注解的作用完全等同于<lookup-method>
元素。
lookup-method元素复习
使用<lookup-method>
元素。需要指定如下两个属性
lookup-method 元素属性 |
描述 |
---|---|
name |
指定要执行lookup 方法注入的方法名。 |
bean |
指定lookup 方法要注入的Bean 的id 。 |
### @Lookup注解通过value属性指定要注入的Bean的id ### | |
而@Lookup 注解则直接修饰需要执行lookup 方法注入的方法,因此不需要指定name 属性,该@Lookup 注解要指定一个value 属性, value 属性就等同于<lookup-method> 元素的bean 属性,也就是用来指定lookup 方法要注入Bean 的id 。 |
扫描bean的时候对bean进行过滤
除此之外,还可通过为<component-scan>
元素添加<include-filter>
或<exclude-filter>
子元素来指定Spring Bean
类,其中:
<include-filter>
用于强制Spring
处理某些Bean
类,即使这些类没有使用Spring
注解修饰;<exclude-filter>
则用于强制将某些Spring
注解修饰的类排除在外。
include-filte元素
<include-filter>
元素用于指定满足该规则的Java
类会被当成Bean
类处理,<exclude-filter>
指定满足该规则的Java
类不会被当成Bean
类处理。使用这两个元素时都要求指定如下两个属性:
属性 | 描述 |
---|---|
type |
指定过滤器类型。 |
expression |
指定过滤器所需要的表达式。 |
Spring
内建支持如下4种过滤器。
过滤器 | 描述 | ||
---|---|---|---|
annotation |
注解过滤器,该过滤器需要指定一个注解名,如lee.AnnotationTest |
||
assignable |
类名过滤器,该过滤器直接指定一个Java 类。 |
||
regex |
正则表达式过滤器,该过滤器指定一个正则表达式,匹配该正则表达式的Java 类将满足该过滤规则,如org\.example\.Default.* 。 |
||
aspectj |
Aspectj 过滤器,如org.example..* Service+ 。 |
||
# 程序示例 # | |||
|
例如,下面配置文件指定所有以Chinese
结尾的类、以Axe
结尾的类都将被当成Spring Bean
处理。
beans.xml
1 |
|