javascript
Spring-注入参数详解-[字面值及引用其他Bean]
- 概述
- 字面值
- XML中的特殊符號的處理
- 5個特殊符號
- 特殊符號的處理方式
- 關于注入值空格的處理
- XML中的特殊符號的處理
- 引用其他Bean
- 實例
- ref元素的3個屬性
- 引用父容器中的Bean實例
- 內部Bean
- null值
- 級聯屬性
概述
在Spring配置文件中,不但可以將String、int等字面值注入bean中,還可以將集合、map等類型的數據注入Bean中, 此外還可以注入配置文件中其他定義的Bean.
字面值
所謂字面值一般指的是可以用字符串表示的值,這些值可以通過<value>元素標簽進行注入。
在默認情況下,基本數據類型及其封裝類、String等類型都可以采用字面值注入的方式。
比如前幾篇博文中經常使用的案例:
<bean id="plane" class="com.xgj.ioc.inject.set.Plane"><property name="brand"><value><![CDATA[Airbus&A380]]></value><!-- 或者使用轉義序列<value>Airbus&A380</value>--></property><property name="color"><value>red</value></property><property name="speed"><value>700</value></property></bean>XML中的特殊符號的處理
5個特殊符號
XML共有5個特殊符號 & < > " '
特殊符號的處理方式
| < | < |
| > | > |
| & | & |
| “ | " |
| ‘ | ' |
關于注入值空格的處理
一般情況下,xml解析器會忽略元素標簽內部字符串的前后空格,但是Spring不會忽略空格。
舉個例子:
<property name="brand"><value> Airbus&A380 </value></property>運行結果如下:
引用其他Bean
Spring IoC容器中定義的Bean可以相互引用,IoC容器充當“紅娘”的角色。
實例
警察類中有槍類型的屬性
POJO類
package com.xgj.ioc.inject.construct.ref;public class Police {private Gun gun;public void setGun(Gun gun) {this.gun = gun;}public void userGun() {gun.fire();}}POJO類
package com.xgj.ioc.inject.construct.ref;public class Gun {public void fire() {System.out.println("Gun Fires");}}配置文件
<?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.xsd"><bean id="police" class="com.xgj.ioc.inject.construct.ref.Police"><property name="gun"><!-- 通過ref應用容器中的gun ,建立police和gun的依賴關系 --><ref bean="gun" /></property></bean><bean id="gun" class="com.xgj.ioc.inject.construct.ref.Gun" /> </beans>測試類
package com.xgj.ioc.inject.construct.ref;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class RefTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/ioc/inject/construct/ref/police-gun.xml");Police police = ctx.getBean("police", Police.class);police.userGun();}}運行結果
ref元素的3個屬性
bean:通過該屬性可以應用同一容器或者父容器中的bean,這是最常見的形式
local:通過該屬性只能引用同一個配置文件中定義的Bean,它可以利用XML解析器自動檢查引用的合法性,以便開發人員在編寫配置文件時及時發現錯誤
parent:引用父容器中的Bean,如<ref parent="gun">的配置說明gun的Bean是父容器中的Bean
引用父容器中的Bean實例
演示子容器對父容器Bean的引用。
其中 beans_father.xml被父容器加載,beans_son.xml被子容器加載。
POJO類
package com.xgj.ioc.inject.construct.refParentBean;public class Gun {private String brand;private int bulletNum;private double price;public void setBrand(String brand) {this.brand = brand;}public void setBulletNum(int bulletNum) {this.bulletNum = bulletNum;}public void setPrice(double price) {this.price = price;}public void gunInfo() {System.out.println("Gun Information brand:" + brand + ",bulletNum:"+ bulletNum + ",price:" + price);} }POJO類
package com.xgj.ioc.inject.construct.refParentBean;public class Police {private Gun gun;public void setGun(Gun gun) {this.gun = gun;}public void introduceGun() {gun.gunInfo();} }beans_father.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.xsd"><bean id="gun" class="com.xgj.ioc.inject.construct.refParentBean.Gun"><property name="brand" value="父容器--伯萊塔92F" /><property name="bulletNum" value="11" /><property name="price" value="2888" /></bean></beans>beans_son.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.xsd"><bean id="gun" class="com.xgj.ioc.inject.construct.refParentBean.Gun"><property name="brand" value="柯爾特M2000" /><property name="bulletNum" value="7" /><property name="price" value="999" /></bean><bean id="police" class="com.xgj.ioc.inject.construct.refParentBean.Police"><property name="gun"><!-- 通過parent屬性,引用父容器中的gun,如果定義為bean="gun"則引用本容器中的gun --><ref parent="gun"/></property></bean></beans>測試類
package com.xgj.ioc.inject.construct.refParentBean;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class RefParentBeanTest {public static void main(String[] args) {// 父容器ApplicationContext pFather = new ClassPathXmlApplicationContext("classpath:com/xgj/ioc/inject/construct/refParentBean/beans_father.xml");// 指定pFather為該容器的父容器ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] { "com/xgj/ioc/inject/construct/refParentBean/beans_son.xml" },pFather);Police police = ctx.getBean("police", Police.class);// 觀察是否輸出為父容器設置的屬性police.introduceGun();}}運行結果
內部Bean
如果某個bean只會被其中一個引用,而不會被容器中的其它Bean引用,可以以內部Bean的方式注入。
內部bean和Java匿名內部類相似,既沒有名字,也不會被前臺bean引用,只能在聲明處為外部Bean提供實例注入。
內部Bean即使提供了id、name、scope等屬性,也會被忽略,scope默認prototype類型
舉例:
其他類同上,區別僅在于beans的配置文件。
<?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.xsd"><bean id="police" class="com.xgj.ioc.inject.construct.innerBean.Police"><property name="gun"><!-- 如果gun bean只會被police引用,而不會被容器中的其它Bean引用,可以以內部Bean的方式注入 --><bean class="com.xgj.ioc.inject.construct.innerBean.Gun"><property name="brand" value="柯爾特M2000"/><property name="bulletNum" value="7"/><property name="price" value="788"/></bean></property></bean></beans>運行結果
null值
如果希望往一個屬性中注入一個null值? 使用專用的<null/>元素標簽
POJO類
package com.xgj.ioc.inject.construct.nullValue;public class Pilot {private Plane plane;public void setPlane(Plane plane) {this.plane = plane;}public void drivePlane() {System.out.println("Pilot is driving plane....");plane.info();} }POJO類
package com.xgj.ioc.inject.construct.nullValue;public class Plane {private String brand;public void setBrand(String brand) {this.brand = brand;}public void info() {System.out.println("Plane brand:" + brand);} }配置文件
<?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.xsd"><bean id="plane" class="com.xgj.ioc.inject.construct.nullValue.Plane"><!-- 設置brand為 null --><property name="brand" value="null" /><!-- 或者 <property name="brand"> <null/> </property> --><!-- 錯誤的寫法,這是spring會將 <value></value>解析為一個空字符串<property name="brand"><value></value></property>--></bean><bean id="pilot" class="com.xgj.ioc.inject.construct.nullValue.Pilot"><property name="plane"><ref bean="plane" /></property></bean></beans>測試類
package com.xgj.ioc.inject.construct.nullValue;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class NullValueTest {public static void main(String[] args) {// TODO Auto-generated method stubApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/ioc/inject/construct/nullValue/beans.xml");Pilot pilot = ctx.getBean("pilot", Pilot.class);pilot.drivePlane();} }運行結果:
級聯屬性
Spring支持級聯屬性的配置,假設我們希望在定義Pilot時,直接為Plane的屬性提供注入值,可以采取如下方式:
<bean id="pilot" class="com.xgj.ioc.inject.construct.cascadeProperty.Pilot"><!-- 以圓點的方式定義級別屬性 --><property name="plane.brand" value="A380"/></bean>上述配置的含義:Spring將調用Pilot.getPlane().setBrand(“A380”)方法進行屬性的注入操作。
此時,必須對Pilot的類進行改造,為Plane屬性聲明一個初始化對象。
實例:
POJO類
package com.xgj.ioc.inject.construct.cascadeProperty;public class Pilot {// 聲明初始化對象private Plane plane = new Plane();// 獲取實例public Plane getPlane() {return plane;}public void setPlane(Plane plane) {this.plane = plane;}public void introduce() {plane.info();}}POJO類
package com.xgj.ioc.inject.construct.cascadeProperty;public class Plane {private String brand;public void setBrand(String brand) {this.brand = brand;}public void info() {System.out.println("【Plane brand:】" + brand);} }配置文件
<?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.xsd"><bean id="pilot" class="com.xgj.ioc.inject.construct.cascadeProperty.Pilot"><!-- 以圓點的方式定義級別屬性 --><property name="plane.brand" value="A380"/></bean> </beans>測試類
package com.xgj.ioc.inject.construct.cascadeProperty;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class CascadePropertyTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/ioc/inject/construct/cascadeProperty/beans.xml");Pilot pilot = ctx.getBean("pilot", Pilot.class);pilot.introduce();} }運行結果
如果沒有未Plane屬性提供Plan對象,Spring在設置級聯屬性時將拋出NullValueInNestedPathException異常。
我們在Plane類中 ,不對Plane進行new實例化操作,僅僅聲明,再次運行NullValueInNestedPathException異常。
Caused by: org.springframework.beans.NullValueInNestedPathException: Invalid property 'plane' of bean class [com.xgj.ioc.inject.construct.cascadeProperty.Pilot]: Value of nested property 'plane' is nullSpring對級聯屬性的層級沒有限制。
總結
以上是生活随笔為你收集整理的Spring-注入参数详解-[字面值及引用其他Bean]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring-依赖注入
- 下一篇: JavaScript-回调函数