Dependency Injection,即依赖注入,为Spring的主要特色之一,其通过XML文件配合Annotation配置各类bean,以达到松耦合,易扩展的目的。
先介绍下Spring Container中bean的生命周期,若POJO实现了这些接口,则相应的方法将会被调用:
用于定义bean的XML文件基本结构如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- Bean declarations go here --> <bean id="duke" class="com.springinaction.springidol.Juggler" /> </beans>
常用的命名空间有以下几种:
命名空间 | 功能 |
aop | AOP功能 |
beans | 主要核心空间,用于bean的装配 |
context | 用于application context的配置,支持基于Annotation的bean自动匹配 |
jee | 支持Java EE API,例如JNDI,EJB |
jms | 声明message-driven POJOs |
lang | 声明通过Groovy,JRuby,或BeanShell scripts实现的bean |
mvc | 支持spring mvc框架 |
oxm | 支持Object-to-XML映射 |
tx | 支持transaction |
util | 一些通用功能,如properties文件导入数据 |
以上的例子列出了一个最简单的bean声明:<bean id="duke" class="com.springinaction.springidol.Juggler" />,Spring将会调用Juggler类的default constructor用于生成bean。
然大多数情况下,我们需要的bean会更复杂,为此spring提供了更为丰富的配置方法:
配置constructor参数:
- 引用类型用ref关键词,通过bean id匹配
- 基本类型用value关键词
- 支持内部bean声明
Spring在配置文件中是不进行类型判断的,而是尝试匹配所有拥有对应数目参数的constructor,并将String类型的参数转化为对应的类型,一旦匹配成功则不再继续,若无一匹配成功则抛出BeanCreationException
<bean id="poeticDuke" class="com.springinaction.springidol.PoeticJuggler"> <constructor-arg value="15" /> //基本类型 <constructor-arg ref="sonnet1" /> //引用类型 <constructor-arg> <bean class="com.springinaction.springidol.Sonnet"> //内建bean </constructor-arg> </bean>
对于没有public constructor的类,如singleton,可以指定factory method来获取实例
<bean id="theStage" class="com.springinaction.springidol.Stage" factory-method="getInstance" />
配置property,需要在POJO中声明对应的setter函数,配置方式和constructor类似
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist"> <property name="song" value="Jingle Bells" /> //基本类型 <property name="instrument" ref="saxophone" /> //引用类型 <property name="sonnet"> <bean class="com.springinaction.springidol.Sonnet"> //内建bean </property> </bean>
Spring提供了 命名空间p来简化property的配置,以上bean可简化为:
<bean id="kenny" class="com.springinaction.springidol.Instrumentalist" p:song="Jingle Bells" p:instrument-ref="saxophone" />
当需要处理 数组型的参数时,我们有如下选择:
- <list>:对应POJO中数组属性或任何使用了java.util.Collection接口的类,并不一定是java.util.List类
element可重复,基本类型使用<value="">标签,应用类型使用<ref bean="">标签,空值使用<null />标签,支持内建bean - <set>:类似于list,区别在于element不可重复
- <map>:key-value类型的参数,key和value均可以是任何类型,POJO中对应java.util.Map接口的实现
内部元素标签为<entry key/key-ref="" value/value-ref="" />,基本类型是key/value,引用类型为key-ref/value-ref - <props>:类似于map,但key和value均只能是String,POJO中对应java.util.Properties类
内部元素标签为<prop key="">value</prop>
<bean>标签还可以定义 init-method, destroy-method,如<bean ... init-method="" destroy-method="">,此种方式优于实现InitializingBean,DisposableBean接口,后者将使POJO限制于Spring框架。<beans>标签支持default-init-method,default-destroy-method,可用于所有bean通用的init,destroy方法
以上介绍了Spring常用配置bean的方式,应该可以满足大多数情况了,但还没有结束,如果你需要到运行时才能确定bean的参数的话,就需要Spring Expression Language(SpEL)的帮助了,我将在下一篇读书笔记中介绍这个Spring特性
参考书目:Spring in Action 3rd Edition by Craig Walls