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

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/beans
	http://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/beans
	http://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/beans
	http://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/beans
	http://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/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/util
	http://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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值