Spring框架学习笔记-注入参数详解

本文详细介绍了Spring框架中Bean的注入参数,包括字面值、引用其他Bean、内部Bean、null值、级联属性、集合类型属性以及简化配置方式。内容涵盖了如何注入基本类型、引用、集合以及级联属性等,并提供了XML配置的各种示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

1.字面值

所谓“字面值”一般是指可用字符串表示的值,这些值可以通过< value >元素标签进行注入。在默认情况下,基本数据类型及其封装类、String等类型都可以采取字面注入的方式。
在下面的示例中,我们为Car注入了两个属性值并在Spring配置文件中使用字面值提供配置值:

<bean id="car" class="com.baobaotao.attr.Car">
<property name="maxSpeed"><value>200</value></property>
<property name="brand"><value><![CDATA[红旗&CA72]]></value></property>
</bean>

由于brand属性值value:红旗&CA72里面包含了一个XML特殊符号,因此我们特意在属性值外添加了一个 <![CDATA[]]> 的XML特殊处理标签,<![CDATA[]]>的作用是让XML解析器将标签中的字符串当作普通的文本对待,以防止某些字符串对XML格式造成破坏。
XML中共有5个特殊的字符,分别是 & < > " ’ 。如果配置文件中的注入值包括这些特殊字符,就需要特殊的处理。处理方式包括1.使用上面使用过的< ![CDATA[]] >这一特殊处理标签。2.使用XML转义序列表示这些特殊的字符,这5个特殊字符所对应的XML转移序列见下表:

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

如果使用XML转义序列,我们可以使用以下的配置进行替换:

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

同时,我们还需要注意:一般情况下,XML解析器会忽略元素标签内部字符串的前后空格,但Spring却不忽略元素标签内部字符串的前后空格,如我们通过以下的配置为brand属性提供注入值:

<property name="brand"><value>空格红旗CT72空格</value></property>

Spring会将”红旗CT72“连同前后空格一起赋给brand属性。

2.引用其他Bean

Spring IoC容器中定义的Bean可以相互引用,IoC容器充当着红娘的作用。下面我们创建一个新的Boss类,Boss类中拥有一个Car类型的属性:

package com.baobaotao.attr;

public class Boss {
	private Car car;
	public void setCar(Car car){
		this.car=car;
	}	
}

boss的Bean通过< ref >元素引用car Bean,建立其boss对car的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<bean id="car" class="com.baobaotao.attr.Car"/>

<bean id="boss" class="com.baobaotao.attr.Boss">
<property name="car"> <ref bean="car"></ref></property>
</bean>

< ref >元素可以通过以下三个属性引用容器中的其他Bean。
1.bean:通过该属性可以引用同一容器或父容器的Bean,这是最常见的形式。
2.local:通过概述性只能引用同一配置文件中定义的Bean,它可以利用XML解析器自动检查引用的合法性,以便在开发编写配置时能够即使发现并纠正配置的错误。
3.parent:引用父容器中的Bean,如< ref parent=“car”>的配置说明car的Bean是父容器中的Bean。
为了说明子容器对父容器中的Bean的引用,我们来看一个具体的例子。
假设有两个配置文件:beans1.xml以及beans2.xml,其中beans1.xml被父容器加载,其配置内容如下:

<bean id="car" class="com.baobaotao.attr.Car">
<property name="brand" value="红旗CA72"/>
<property name="maxSpeed" value="200"/>
<property name="price" value="2000.00"/>
</bean>

而beans2.xml被子容器加载,其配置如下内容所示:

<bean id="car" class="com.baobaotao.attr.Car">
<property name="brand" value="吉利CT5"/>
<property name="maxSpeed" value="100"/>
<property name="price" value="1000.00"/>
</bean>
<bean id="boss" class="com.baobaotao.attr.Boss">
<property name="car" ><ref parent="car"/></property>
</bean>

在beans1.xml中配置了一个car Bean,在beans2.xml中也配置了一个car Bean。分别通过父子容器加载beans1.xml和beans2.xml,beans2.xml中的boss通过< ref parent=“car” >将引用到父容器中的car。

3.内部Bean

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

<bean id="boss" class="com.baobaotao.attr.Boss">
	<property name="car">
		<bean id="car" class="com.baobaotao.attr.Car">
			<property name="maxSpeed" value="200"/>
			<property name="price" value="2000.00"/>
		</bean>
	</property>
</bean>

内部Bean和Java代码中匿名内部类很相似,即没有名字,也不能被其他Bean引用,只能在声明处为外部Bean提供实例注入。

4.null值

如果用户尝试通过以下的配置方式为car的brand属性注入一个null值,将会得到一个令人失望的结果:

<bean id="car" class="com.baobaotao.attr.Car">
	<property name="brand"><value></value></property>
</bean>

Spring会将< value >以及< /value >解析为一个空字符串,那如何为属性设置一个null的注入值呢?
答案是必须使用专用的< null/ >元素标签,通过它可以为Bean的字符串或其他对象类型注入null值:

<property name="brand"><null/></property>

上面的配置等同于调用car.setBrand(null)的方法。

5.级联属性

Spring支持级联属性的配置。
假设我们希望在定义Boss时直接为Car的属性提供注入值,则可以采取以下的配置方式:

<bean id="boss3" class="com.baobaotao.attr.Boss">
	<property name="car.brand" value="吉利CT50"/>
</bean>

Spring没有对级联属性的层级数进行限制,只要配置的Bean拥有对应于级联属性的类结构,就可以配置任意层及的级联属性,如< property name=“car.wheel.brand” value=“双星”/>定义了具有三层结构的级联属性。

6.集合类型属性

java.util包中的集合类时最常用的数据结构类型,主要包括List、Set、Map、Properties,Spring为这些集合类型属性提供了专门的配置元素标签。

List

我们为Boss添加一个List类型的favorites属性:

package com.baobaotao.attr;
public class Boss{
	private List favorites=new ArrayList();
	public List getFavorites(){
		return favorites;
	}
	public void setFavorites(List favorites){
		this.favorites=favorites;
	}
}

对用Spring中的配置片段如下所示:

<bean id="boss1" class="com.baobaotao.attr.Boss">
	<property name="favorites">
		<list>
			<value>看报</value>
			<value>赛车</value>
			<value>高尔夫</value>
		</list>
	</property>
</bean>

List属性既可以通过< value >注入字符串,也可以通过< ref >注入容器中其他的Bean。

Set

如果Boss的favorites属性是java.util.Set,则采用如下的配置方式:

<bean id="boss1" class="com.baobaotao.attr.Boss">
	<property name="favorites">
		<set>
			<value>看报</value>
			<value>赛车</value>
			<value>高尔夫</value>
		</set>
	</property>
</bean>

Map

下面,我们为Boss添加一个Map类型的jobs属性:

public class Boss{
	private Map jobs=new HashMap();
	public Map getJobs(){
		return jobs;
	}
	public void  setMap(Map jobs){
		this.jobs=jobs;
	}
}

在配置文件中,可以通过以下方式为jobs属性提供配置值:

<bean id="boss1" class="com.baobaotao.attr.Boss">
	<property name="jobs">
		<map>
			<entry>
				<key><value>AM</value></key>
				<value>会见客户</value>
				<key><value>PM</key></value>
				<value>公司内部会议</value>
			</entry>
		</map>
	</property>
</bean>

假如某一Map元素的键和值都是对象,则可以采用以下的配置方式:

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

Properties

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

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

下面的配置片段为mails提供了配置:

<bean id="boss1" class="com.baobaotao.attr.Boss">
	<property name="mails">
		<props>
			<prop key="jobMail">john-office@baobaotao.com</prop>
			<prop key="lifeMail">john-life@baobaotao.com</prop>
		</prop>
	</property>
</bean>

因为Properties键值对只能是字符串,因此其配置比Map的配置要简单一些,注意值的配置没有< value >子元素标签。

强类型集合

下面的Boss类中的jobTime属性就采用了强类型的Map类型:元素的键为String类型:而值为Integer类型。

public class Boss{
	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中的配置和非强类型集合相同:

<bean id="boss1" class="com.baobaotao.attr.Boss">
	<property name="jobTime">
		<map>
			<entry>
				<key><value>会见客户</value></key>
				<value>124</value>
			</entry>
		</map>
	</property>
</bean>

但是Spring容器在注入强类型集合时,会判断元素的类型,将设置值转换为对应的数据类型。

集合合并

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

<bean id="parentBoss" abstract="true" class="com.baobaotao.attr.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> 

在代码中通过merge="true"属性只是子< bean >和父< bean >中同名的属性值进行合并,即子Bean的favorites集合将最终拥有5个元素。如果设置为merge=“false”,则不会和父< bean >同名集合属性进行合并,即子Bean的favorites属性只有两个元素。

7.简化配置方式

前面我们都采用了完整配置格式的配置方式,但是Spring为字面值、引用Bean以及集合都提供了简化的配置方式。如果没有用到完整配置格式的特殊功能,用户可以使用简化的配置方式。下面我们分别为上面的配置方式提供简化版的配置写法:

字面值属性值

关于字面值属性:

<property name="maxSpeed"><value>200</value></property>//简化前
<property name="maxSpeed" value="200"/>

关于构造函数参数:

<constructor-arg type="java.lang.String"><value>红旗CA72</value></constructor-arg>//简化前
<constructor-arg type="java.lang.String" value="红旗CA72"/>//简化后

关于集合元素:

<map>
	<entry>
		<key><value>AM</value></key>
		<value>会见客户</value>
	</entry>
</map>//简化前

<map>
	<entry key="AM" value="会见客户"/>
</map>//简化后

引用对象属性

关于字面值属性:

<property name="car"><ref bean="car"></ref></property>//简化前
<property name="car" ref bean="car"/>

关于构造函数参数:

<constructor-arg><ref bean="car"></ref></constructor-arg>//简化前
<constructor-arg ref bean="car"/>//简化后

关于集合元素:

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

<map>
	<entry key-ref="keyBean" value-ref="valueBean"/>
</map>//简化后

需要注意< ref >的简化形式对应于< ref bean=“XXX” >,而< ref local=“XXX” >以及< ref parent=“XXX” >没有对应的简化形式。

使用p命名空间

为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息,Spring2.5开始引入了一个新的p命名空间,可以通过< bean >元素属性的方式配置Bean的属性。
使用p命名空间之前:

<bean id="car" class="com.baobaotao.ditype.Car">
	<property name="brand" value="红旗CA72"/>
	<property name="maxSpeed" value="200"/>
	<property name="price" value="20000.00"/>
</bean>
<bean id="boss" class="com.baobaotao.ditype.Boss">
	<property name="car" ref="car"/>
</bean>

使用p命名空间后:

<bean id="car" class="com.baobaotao.ditype.Car" p:brand="红旗CA72" p:maxSpeed="200" p:price="20000.00"/>
<bean id="boss" class="com.baobaotao.ditype.Boss" p:car-ref="car"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值