Spring笔记(6)-----------注入参数详解

来源:互联网 发布:数据透视表高级技巧 编辑:程序博客网 时间:2024/03/28 17:17

Spring不但可以将String,int等字面值注入到Bean中,还可以将集合,Map等类型的数据注入到Bean中,还可以注入配置文件中其他定义的Bean。

注入字面值:

“字面值”一般是指可用字符串表示的值,这些值可以通过<value>标签注入。默认情况下,基本类型及其封装类,String等类型都可以采用字面值注入。Spring容器在内部为字面值提供了编辑器,它可以将字符串表示的字面值转换为内部变量的相应类型。

看个例子,使用属性注入,需要提供相应的settr方法和默认的构造器:

<?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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="car" class="com.baobaobao.Car"><property name="brand"><value><![CDATA[红旗&CA72]]></value></property><property name="color"><value>red</value></property></bean></beans>
这儿有个特殊点:brand的属性值包含XML的特殊符号“&”XML的特殊符号一共有5个<>&"',想要在属性值里使用它要么在属性值外面加<![CDATA[属性值]]>,要么使用转义序列,不加会报错,如下:

特殊符号转义序列特殊符号转移序列<&lt;"&quot;>&gt;'&apos;&&amp;  

如果使用转义序列,就可以这么写:

<property name="brand"><value>红旗&amp;CA72</value></property>

引用其他Bean:

Spring容器中的Bean可以互相引用,IOC容器则充当“红娘”,看如下的例子,Boss类有一个Car类型的属性:

<?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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="boss" class="com.baobaobao.Boss"><property name="name"><value>james</value></property><property name="car"><ref bean="car"/></property></bean><bean id="car" class="com.baobaobao.Car"><property name="brand"><value>红旗&CA72</value></property><property name="color"><value>red</value></property></bean></beans>
Boss的Bean通过ref建立起对car的依赖,

<ref>元素可以通过以下三个属性引用容器的bean。

bean:通过该属性可以引用同一容器或父容器的bean,最常见

local:通过该属性可以引用同一配置文件中定义的Bean,它可以利用XML解析器自动检测引用的合法性,配置时能即使发现错误。

parent:引用父容器的bean

下面来看一个子容器对父容器bean引用的例子,beans2.xml被父容器加载:

beans2.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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="car" class="com.baobaobao.Car"><property name="brand" value="奥迪A6"></property><property name="maxSpeed" value="200"></property><property name="price" value="300000"></property></bean></beans>
beans1.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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="boss" class="com.baobaobao.Boss"><property name="name"><value>james</value></property><property name="car"><ref parent="car"/></property></bean><bean id="car" class="com.baobaobao.Car"><property name="brand"><value>红旗&CA72</value></property><property name="maxSpeed"><value>200</value></property><property name="price"><value>10000</value></property></bean></beans>

这俩配置文件都有一个名叫car的bean。。

使用该类运行,

public class ParentBeanTest {public static void main(String[] args) {ClassPathXmlApplicationContext pFactory = new ClassPathXmlApplicationContext(new String[]{"classpath:beans2.xml"});//pFactory作为factory的父容器ApplicationContext factory = new ClassPathXmlApplicationContext(new String[]{"classpath:beans1.xml"}, pFactory);Boss boss = (Boss) factory.getBean("boss");System.out.println(boss.getCar().getBrand());}}

就会打印出父容器中配置的brand的属性。

内部Bean:

如果car Bean只被boss Bean引用而不会被容器中其他Bean引用,则可以将car以内部Bean的方式注入到Boss中:

配置文件如下:

<bean id="boss" class="com.baobaobao.Boss"><property name="car"><bean class="com.baobaobao.Car"><property name="brand" value="奥迪A6"/><property name="price" value="200000" /></bean></property></bean>

Null值:

如果想给car的brand属性注入一个null值,如果这么配置:

<bean id="car" class="com.baobaobao.Car"><property name="brand" value="奥迪A6"><value></value></property></bean>

这么配置会解析为空字符串,不可行,这么做即可,如下:

<bean id="car" class="com.baobaobao.Car"><property name="brand" ><null /></property></bean>


级联属性:

Spring支持级联属性的配置,假如我们想要在定义Boss时直接为Car的属性注入值,如下配置:

<bean id="boss4" class="com.baobaobao.Boss"><property name="car.brand" value="吉利CT50"></property></bean>

这样,Spring将调用Boss.getCar().setBrand("吉利GT50")方法进行属性的注入操作,,必须为Boss类声明一个初始化的对象,否则,级联属性注入时会抛出异常。

例如:在Boss类中声明属性的时候初始化它,private Car car = new Car();

集合类型属性:

Spring为java常用集合类:List,Set,Map,Properties提供了专门的配置元素标签。

1)List:

给Boss类增加如下属性:

private List favorites = new ArrayList();public List getFavorites() {return favorites;}public void setFavorites(List favorites) {this.favorites = favorites;}
在配置文件中配置如下:

<bean id="boss4" class="com.baobaobao.Boss"><property name="car.brand" value="吉利CT50"></property><property name="favorites"><list><value>读书</value><value>看报</value><value>打高尔夫</value></list></property></bean>

这样便把List属性注入到bean里了,可以通过value注入字符串,也可以通过ref注入到其他bean中。

2)Set:
配置如下:

<property name="favorites"><set><value>读书</value><value>看报</value><value>打高尔夫</value></set></property>

3)Map:

我们为Boss添加一个Map类型的jobs属性,文件配置如下:

<property name="jobs"><map><entry><key><value>AM</value></key><value>会见客户</value></entry><entry><key><value>PM</value></key><value>公司内部会议</value></entry></map></property>

如果key和value都是对象,可以写成如下形式:

<map><entry><key><ref bean="keyBean"/></key><ref bean="valueBean"/></entry></map>

4)Properties

Properties可以看成是Map类型的特例,Map元素的键和值可以是任何类型的对象,而Properties的键和值只能为字符串,如下,我们为Boss类增加一个mail属性:

private Properties mails = new Properties();public Properties getMails() {return mails;}public void setMails(Properties mails) {this.mails = mails;}

配置文件如下配置:

<property name="mails"><props><prop key="jobmail">jihaixiao@163.com</prop><prop key="lifeemail">xinyi_zhankuang@yahoo.com</prop></props></property>
注意:值的配置里面没有value标签。。。

5)强类型集合
JDK5.0提供的新功能。允许为集合元素指定类型,例如Boss类的jobTime,如下:

private Map<String, Integer> jobTime = new HashMap<String, Integer>();public Map<String, Integer> getJobTime() {return jobTime;}public void setJobTime(Map<String, Integer> jobTime) {this.jobTime = jobTime;}
配置跟上面一样,如下,Spring会判断配置元素类型,自动转换。

<property name="jobTime"><map><entry><key><value>会见客户</value></key><value>124</value></entry></map></property>

6)集合合并

Spring2.0新增集合合并的功能,允许子<bean>继承父<bean>的同名属性集合元素,并将子<bean>中配置的集合属性值和父<bean>中配置的同名属性值合并起来作为最终的Bean的属性值。配置文件如下:

<bean id="parentBoss" class="com.baobaobao.Boss"><property name="favorites"><set><value>读书</value><value>看报</value><value>打高尔夫</value></set></property></bean><bean id="childBoss" parent="parentBoss"><property name="favorites"><set merge="true"><value>爬山</value><value>打球</value></set></property></bean>

在子bean的集合下增加merge属性为true表示子bean跟父bean中同名的属性值进行合并,只对子bean有效果。。。。

7)通过util命名空间配置集合类型的Bean

如果想要配置一个集合类型的Bean,而非一个集合类型的属性,那么可以通过util命名空间进行配置。

先配置头文件中如下:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-3.0.xsd">

几种集合Bean的配置如下,使用id指定名字,xxx-class指定对应集合的实现类:

<util:list id="favoriteList1" list-class="java.util.LinkedList"><value>读书</value><value>看报</value><value>高尔夫</value></util:list><util:set id="favoriteSet1"><value>爬山</value><value>打球</value></util:set><util:map id="emails"><entry key="AM" value="会见客户"></entry><entry key="PM" value="内部会议"></entry></util:map>

简化配置方式:

Spring为字面值,引用Bean和集合都提供了简化的配置方式,下面提供了简化前和简化后的版本:

1)字面值属性:

 简化前简化后字面值属性<property name="maxSpeed">
<value>200</value>
</property><property name="maxSpeed" value="200" />构造函数参数<constructor-arg type="java.lang.String">
<value>奥迪</value>
</constructor-arg><constructor-arg type="java.lang.String" value="奥迪"/>集合元素<property name="jobs">
<map>
<entry>
<key><value>AM</value></key>
<value>内部会议</value>
</entry>
</map>
</property><property name="jobs">
<map>
<entry key="AM" value="内部会议" />
</map>
</property>
2)引用对象属性:

 简化前简化后字面值属性<property name="car">
<ref parent="car"/>
</property><property name="car" ref="car" />构造函数参数<constructor-arg>
<ref bean="car"/>
</constructor-arg><constructor-arg ref="car" />集合元素
<map>
<entry>
<key><ref bean="keyBean"/></key>
<ref bean="valueBean"/>
</entry>
</map><map>
<entry key-ref="keyBean" value-ref="valueBean" />
</map>

<ref>的简化形式对应<ref bean="XXX"> 而<ref local="XXX">和<ref parent="XXX">则没有对应的简化方式。

3)使用p命名空间

为了简化XML文件的配置,越来越多的xml采用属性而非子元素配置信息。Spring从2.5开始引入一个新的p命名空间,简化配置文件。

在头文件中加入xmlns:p="http://www.springframework.org/schema/p"

对于字面值属性,采用p:属性名=“XXX”

对于引用值属性,采用p:属性名-ref=“XXX”

正是由于p命名空间中的属性名是可变的,所以p命名空间没有对应的Schema定义文件,也无需从xsi:schemaLocation为p的命名空间指定Schema定义的文件。


0 0
原创粉丝点击