Spring:設值注入用法

  首先明確Java中什麼是依賴關係:

  類A依賴類B的意思是,如果A的對象要完成某一操作,必須使用B的對象的某些操作來幫忙,才能完成。簡言之,B作爲A的某個方法的方法參數存在。如下:

class A{
       public void f(B b){
 
}
}
class B{
 
}
  


 Spring的作用就是管理JavaEE中的各個組件,並把所有的Java對象都稱之爲Bean,因此完全可以把任何的Java類都部署在Spring中,但是Java類中必須有相應的構造器。 

  設值注入通過<property/>元素驅動Spring執行setter方法,爲參數傳入參數值,而Java類的成員變量又可以是各種數據類型,除了基本的數據類型外,還可以是其他Java實例,也可以是Spring容器中其他Bean實例,甚至是Java集合,數組等,因此Spring允許如下元素爲setter方法、構造器參數指定參數值。

1:value  用於注入基本數據類型

2:ref   當注入的成員變量屬於Sping容器中的其他Bean實例則應使用ref元素。

3:bean  稱之爲注入嵌套Bean,當某個Bean所依賴的Bean不想被容器訪問,則可以使用嵌套Bean,其本質與ref一樣

4:list、set、map、props 當注入的成員變量屬於集合時則使用這些元素。

  Spring可以爲任何Java對象注入任何類型的屬性,只要該Java對象爲該屬性提供了相應的setter方法,Spring就是通過該方法,完成的相應賦值和注入。

一:當注入普通屬性時—————value元素的使用

1:我們定義一個Bean實例的實現類 Test.java

package com.mao.test;

public class Test {
	private String userName;
	//爲Spring容器注入普通屬性提供setter方法
	public void setUserName(String userName) {
		this.userName = userName;
	}

	public void input(){
		System.out.println("正在調用setUserName()方法,傳入的參數爲:"userName);
	}
}


該類中聲明瞭一個普通屬性 userName,並提供了set方法,Spring容器也正是通過該方法完成的屬性注入。

2:我們的配置文件beans.xml

<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
	<!-- 創建一個id爲test的Bean實例 -->
	<bean id="test" class="com.mao.test.Test">
	  <!-- 通過setName方法爲參數賦值  參數值爲VipMao -->
	  <property name="userName" value="VipMao"></property>
	</bean>
</beans>

說一下配置文件,我們定義了一個id爲test的Bean實例,他的實現類是com.mao.test包下的Test.java(也就是上面那個程序),然後<bean>內定義了個<property>標籤,name屬性的值表示調用哪個屬性的set方法進行注入賦值,value屬性得值表示傳入的參數是什麼。上面的配置文件就是:有一個test的Bean實例,然後Spring容器通過setUserName方法,將VipMao參數注入給userName屬性。咱們僅僅需要提供一個setter方法,然後"坐等"Spring通過該setter方法完成賦值並注入給userName屬性。

3:我們的測試類 TestManager.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestManager {
	public static void main(String[]args){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
		//獲取Bean實例
		Test t=(Test) ctx.getBean("test");
		//執行input方法
		t.input();
	}
}

4:執行結果

正在調用setUserName()方法,傳入的參數爲:VipMao


  可以看出,在主程序測試類中我們並沒有通過代碼設置name屬性的值,而是<property/>元素驅動Spring容器通過相應的set方法,將value元素的值注入給屬性,但是前提是:

(1):在Bean 實例中提供了相應的setter方法(Spring容器通過該方法注入)

(2):該屬性爲普通屬性(上面的name屬性爲String型)


二:注入的屬性爲Spring中的另一個Bean屬性----ref元素的使用

如果我們在一個Bean實例中的一個方法中使用了另一個Bean實例,也就是上面說的依賴關係,或者說需要爲Bean設置的屬性值是容器中的另一個Bean的實例,則應該使用ref元素。如下例子:

1:Bean實例 Person.java

package com.mao.test;

public class Person {
	private Chinese chinese;

	public Person() {
		System.out.println("----------Spring容器通過調用無參構造函數創建Bean實例----------");
	}

	public void setChinese(Chinese chinese) {
		this.chinese = chinese;
	}
	public void useChinese(){
		System.out.println(chinese.say());
	}
}
上面聲明瞭一個Chinese屬性,並提供了setter方法,在Person類useChinese()方法中用到了chinese實例,接下來我們看一下Spring容器怎麼通過ref元素將Chinese實例注入給chinese

2:我們的配置文件beans.xml

<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
        <!-- 定義chinesePerson Bean實例,實現類Chinese類 -->
	<bean id="chinesePerson" class="com.mao.test.Chinese"></bean>
	<!-- 創建一個person Bean 實現類Person類-->
	<bean id="person" class="com.mao.test.Person">
	  <!-- 驅動調用person的setChinese()方法,將容器中的chinesePerson Bean實例作爲傳入參數 -->
	  <property name="chinese" ref="chinesePerson"></property>
	</bean>
</beans>
配置文件中先定義了一個chinesePerson Bean實例,實現類是Chinese類,然後定義了一個person的Bean實例,<property>內的name和ref元素值就是:通過Person類的setChinese方法將容器中的chinesePerson Bean實例作爲參數注入給chinese,這就相當於執行了 Chinese chinese=new Chinese(); 只不過這個過程是Spring通過set方法實現的。

3:被引用的chinese Bean實例 Chinese.java

package com.mao.test;

public class Chinese {
	public String say(){
		return"我是中國人";
	}
}<span style="font-size:14px;">
</span>

4:測試程序 PersonManager.java

public class PersonManager {
	public static void main(String[]args){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
		//獲取person Bean實例
		Person p=(Person) ctx.getBean("person", Person.class);
		p.useChinese();
}
}


5:輸出結果:


可以看出,我們並沒有在主程序中通過new的方式創建Chinese對象,這一切都是Spring容器通過ref引用chinesePerson的Bean實例,將該實例作爲參數通過setter方法完成賦值和注入,通過輸出結果我們也可以發現Spring容器是通過無參數構造器來創建Bean實例的

三:注入嵌套Bean

   當某個Bean所依賴的Bean不想被Spring容器直接訪問時,例如上一個例子person的Bean實例需要依賴chinese的Bean實例,則可以使用嵌套Bean,將chinese的Bean實例嵌套進person的Bean實例,因爲嵌套Bean實例的本質是和ref引用容器是一樣的,因此我們完成上一個例子,僅需稍微修改一下配置文件beans.xml


<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
	<!-- 創建一個person Bean 實現類Person類-->
	<bean id="person" class="com.mao.test.Person">
	  <!-- 驅動調用person的setChinese()方法,將容器中的chinesePerson Bean實例作爲傳入參數 -->
	  <property name="chinese">
	  <!-- 定義chinesePerson Bean實例,實現類Chinese類 -->
	  <bean class="com.mao.test.Chinese"></bean>
	  </property>
	</bean>
</beans>

如上,將chinese的Bean實例嵌套到person Bean的<property>子元素,那麼該chinese Bean就僅僅作爲setter注入的參數,由於不需要容易訪問該Bean,因此也就不需要指定id屬性。

其他代碼不用改,運行結果依舊:


四:注入集合值

  當我們需要注入集合值時,我們則可以使用集合元素<list/><set/><map/><props>分別爲List、Set、Map、和Properties的集合設置屬性值,如下:

1:Chinese.java

package com.mao.collection;

import java.util.*;

public class Chinese implements Person{

	// 下面是系列集合類型的成員變量
		private List<String> schools;
		private Map scores;
		private Map<String , Axe> phaseAxes;
		private Properties health;
		private Set axes;
		private String[] books;

		public Chinese()
		{
			System.out.println("Spring實例化主調bean:Chinese實例...");
		}

		// schools的setter方法
		public void setSchools(List schools)
		{
			this.schools = schools;
		}
		// scores的setter方法
		public void setScores(Map scores)
		{
			this.scores = scores;
		}
		// phaseAxes的setter方法
		public void setPhaseAxes(Map<String , Axe> phaseAxes)
		{
			this.phaseAxes = phaseAxes;
		}
		// health的setter方法
		public void setHealth(Properties health)
		{
			this.health = health;
		}
		// axes的setter方法
		public void setAxes(Set axes)
		{
			this.axes = axes;
		}
		// books的setter方法
		public void setBooks(String[] books)
		{
			this.books = books;
		}

		// 訪問上面全部的集合類型的成員變量
		public void test()
		{
			System.out.println("----開始輸出List集合--------");
			Iterator it=schools.iterator();
			while(it.hasNext()){
				System.out.println(it.next());
			}
			System.out.println("--------開始輸出Map集合---------- ");
			System.out.println(scores);
			System.out.println("---------開始遍歷<String,Axe集合>----------");
			System.out.println(phaseAxes);
			System.out.println("---------開始遍歷Properties----------");
			System.out.println(health);
			System.out.println("---------開始遍歷Set集合----------");
			Iterator itSet=axes.iterator();
			while(itSet.hasNext()){
				System.out.println(itSet.next());
			}
			System.out.println("-----開始遍歷Array數組集合-------------");
			System.out.println(java.util.Arrays.toString(books));
			for(String array:books){
				System.out.println(array);
			}
			
		}

}

2:下面分別用<list/><set/><map/><props>來在配置文件beans.xml中爲集合設置參數值。

<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
	<bean id="steelAxe" class="com.mao.collection.SteelAxe"></bean>
	<bean id="stoneAxe" class="com.mao.collection.StoneAxe"></bean>
	<bean id="chinese" class="com.mao.collection.Chinese">
	  <property name="schools">
	    <list>
	      <value>菜鳥學院</value>
	      <value>大牛學院</value>
	      <value>大神學院</value>
	    </list>
	  </property>
	  <property name="scores">
	    <map>
	      <entry key="語文" value="86"/>
	      <entry key="數學" value="95"/>
	      <entry key="英語" value="100"/>
	    </map>
	  </property>
	  <property name="phaseAxes">
	    <map>
	      <entry key="原始社會" value-ref="stoneAxe"/>
	      <entry key="農業社會" value-ref="steelAxe"/>
	    </map>
	  </property>
	  <property name="health">
	    <props>
	      <prop key="血壓">正常</prop>
	      <prop key="身高">175</prop>
	    </props>
	  </property>
	  <property name="axes">
	    <!-- 爲調用setAxes()方法配置Set集合作爲參數值 -->
			<set>
				<!-- 每個value、ref、bean..都配置一個Set元素 -->
				<value>普通的字符串</value>
				<bean class="com.mao.collection.SteelAxe"/>
				<ref bean="stoneAxe"/>
				<!-- 爲Set集合配置一個List集合作爲元素 -->
				<list>
					<value>20</value>
					<!-- 再次爲List集合配置一個Set集合作爲元素 -->
					<set>
						<value type="int">30</value>
					</set>
				</list>
			</set>
	  </property>
	  <property name="books">
	    <list>
	      <value>Java從入門到精通</value>
	      <value>輕量級JavaEE企業應用實戰</value>
	      <value>經典JavaEE企業應用實戰</value>
	    </list>
	  </property>
	</bean>
	<bean id="example" class="com.mao.fuhe.Example">
	  <property name="person.name" value="VipMao"></property>
	</bean>
</beans>

Spring容器也是通過<property>的name屬性調用相應的setter方法,完成相應集合的賦值注入。

3:主程序 TestManager.java


package com.mao.collection;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestManager {
	public static void main(String[]args){
		ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
		Chinese chinese=(Chinese) ctx.getBean("chinese");
		chinese.test();
	}
}

4:運行結果:


總結:

Spring框架本質就是通過xml配置文件來驅動Java代碼,當程序要調用setter方法時,總需要傳入參數值,隨着參數值不同,Spring配置文件也要改變:

1:形參類型是基本數據類型:String ,日期等  使用value

2:形參類型是符合類型:使用ref或者嵌套Bean

3:形參類型是集合,使用<list/><set/><map/><props>來注入集合參數值


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章