在Spring中,对象无需自己负责查找或创建与其关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象。创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入的本质。
1.声明Bean
1.1 创建Spring配置
在XML文件中声明Bean时,Spring配置文件的根元素是来源于Spring beans命名空间所定义的<beans>元素。以下是一个典型的Spring 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" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"> <!-- Bean declaration go here --> </beans>
在<beans>元素内,可以放置所有的Spring配置信息,包括<bean>元素的声明。
Spring核心框架自带的10个命名空间配置如下:
1.2 声明一个简单的Bean
<bean>元素是Spring中最基本的配置单元,通过该元素Spring将创建一个对象。Spring使用反射来创建Bean。
1.3 通过构造器注入
1) 通过构造器注入对象引用
<bean id="zookeeperSources" class="com.dangdang.config.service.easyzk.support.spring.ZookeeperSourceFactoryProxy" > <constructor-arg name="appName" value="${server.name}" /> <constructor-arg name="configFactory" ref="configFactory" /> <constructor-arg name="nodes" value=""/> </bean>
<bean id="zookeeperSources" class="com.dangdang.config.service.ZookeeperSource" factory-method="create"/>
1.4 Bean的作用域
所有的Spring Bean默认都是单例。当容器分配一个Bean时,它总返回Bean的同一个实例。为了让Spring在每次请求时都为Bean产生一个新的实例,我们只需配置Bean的scope属性为prototype。
<bean id="zookeeperSources" class="com.dangdang.config.service.ZookeeperSource" scope="prototype"/>
1.5 初始化和销毁Bean
为Bean定义初始化和销毁操作,只需使用init-method和destroy-method参数来配置<bean>元素。init-method属性指定了在初始化Bean时要调用的方法,destroy-method属性指定了Bean从容器移除前要调用的方法。
<bean id="auditor" class="com.springinaction.springidol.Auditor" init-method="turnOnLights" destroy-method="turnOffLights" />
<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/spring-beans-3.1.xsd" default-init-method=" turnOnLights" default-destroy-method="turnOffLights"> </beans>
2.注入Bean属性
2.1注入简单值
<bean id =“kenny" class="com.ouc.springinaction.test"> <property name ="song" value="Bells" /> </bean>
一旦test被实例化,Spring就会调用<property>元素所指定属性的setter方法为该属性注入值。
2.2 引用其他Bean
<bean id =“saxon" class="com.ouc.springinaction.saxontest"></bean> <bean id =“kenny" class="com.ouc.springinaction.test2"> <property name ="song" value="Bells" /> <property name ="saxonIns" ref="saxon" /> </bean>
2.3 注入内部Bean
<bean id =“saxon" class="com.ouc.springinaction.saxontest"></bean> <bean id =“kenny" class="com.ouc.springinaction.test2"> <property name ="song" value="Bells" /> <property name ="saxonIns"> <bean class="com.ouc.springinaction.saxontest"> /property> </bean>
内部Bean没有ID属性,使用内部Bean的最大缺点:不能被复用,内部Bean仅适用于一次注入,而且不能被其他Bean所引用。
2.4 使用Spring的命名空间p装配属性
命名空间p的schema URI为http://www.springframework.org/schema/p.
<bean id =“kenny" class="com.ouc.springinaction.test3"> p:song = "Bells" p:saxonIns-ref = "saxon" /> </bean>
2.5 装配集合
Spring提供了4种类型的集合配置元素。
<props>要求键和值都必须为String类型,而<map>允许键和值可以是任意类型
装配Map集合
<bean id =“hank" class="com.ouc.springinaction.test4"> <property name ="ins"> <set> <ref bean = "guitar" /> <ref bean = "cymbal" /> <ref bean = "harmonica" /> <ref bean = "harmonica" /> </set> </property> </bean> <bean id =“hank" class="com.ouc.springinaction.test4"> <property name ="ins"> <list> <ref bean = "guitar" /> <ref bean = "cymbal" /> <ref bean = "harmonica" /> </list> </property> </bean>
<bean id =“hank" class="com.ouc.springinaction.test4"> <property name ="ins"> <map> <entry key="GUITAR" value-ref = "guitar" /> <entry key="GUITAR1" value-ref = "guitar1" /> <entry key="GUITAR2" value-ref = "guitar2" /> </map> </property> </bean>
装配Properties集合
<bean id =“hank" class="com.ouc.springinaction.test4"> <property name ="ins"> <props> <prop key="GUITAR"> STRUM </prop> <prop key="CYMBAL"> CRASH </prop> </props> </property> </bean>
● <props> 元素用于定义一个java.util.Properties类型的集合值。
● <prop> 元素用于定义<props>集合的一个成员。
装配空值
为了覆盖自动装配的值或不能完全确定属性的值是否为null,此时,必须显示地为该属性装配一个null值。
<property name ="nullIns"><null/></property>
2.6 使用表达式装配
Spring表达式语言(SpEL)拥有许多特性,包括:
● 使用Bean的ID来引用Bean;
● 调用方法和访问对象的属性;
● 对值进行算术、关系和逻辑运算;
● 正则表达式匹配;
● 集合操作。
字面值
<property name="cappacity" value="#{1e4}" />
引用Bean、Properties和方法
<property name="ins" value="#{saxno.song}" /> <property name="ins" value="#{saxno.song()?.toUpperCase()}" />
操作类
使用T()运算符会调用类作用域的方法和常量,通过该运算符可以访问指定类的静态方法和常量。
使用SpEL进行数值运算
比较值
<property name="mathplier" value="#{T(java.lang.Math).PI}" /> <property name="randomNum" value="#{T(java.lang.Math).random()}" />
<property name="area" value="#{T(java.lang.Math).PI * circle.radius ^ 2}" />
<property name="hasCap" value="#{count.total le 10000}" />
<property name="outStock" value="#{!pro.available}" /> <property name="outStock" value="#{not pro.available}" />
<property name="song" value="#{keny.song != null ? keny.song : 'Green'}" /> <property name="song" value="#{keny.song ?: 'Green'}" />
<property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.com'}" />
<util:list id ="cities"> <bean class="com.habuma.spel.city" p:name="Chicago" p:state="IL" p:population="2556321" /> p:name="Chicago1" p:state="IL1" p:population="2556312" /> p:name="Chicago2" p:state="IL2" p:population="2556311" /> </util:list>
<property name="choseCity" value="#{cities[2]}" /> <property name="choseCity" value="#{cities['Chicago']}" />
systemEnvironment包含了应用程序所在机器上的所有环境变量。
<property name="homePath" value="#{systemEnvironment['HOME']}" />
systemProperties包含了Java应用程序启动时所设置的所有属性。
查询集合成员
从城市集合中查询人口多于10000的城市。
使用查询运算符(.?[])
<property name="homePath" value="#{systemProperties['app.home']}" />
从城市集合中查询人口多于10000的城市。
使用查询运算符(.?[])
<property name="bigCities" value="#{cities.?[population gt 10000]}" />
投影集合
集合投影是从集合的每一个成员中选择特定的属性放入一个新的集合中。
用(.![])投影运算符投影集合。
<property name="cityNames" value="#{cities.![name]}" />