追蹤
在城市的一角低調喧嘩。
關於部落格
在數位的城市裡,尋找那遺落各地一點一滴的人文元素。
  • 115879

    累積人氣

  • 7

    今日人氣

    5

    追蹤人氣

[Spring技術手冊] 筆記(3) - Spring注入的方法

以下使用ClassPathXmlApplicationContext作範例呼叫bean定義檔(放在/src之下):
Test1.java
--------------------------------------
package com.aidc.main;

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

import com.aidc.bean.TestBean1;

public class Test1 {
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  TestBean1 testBean1 = (TestBean1)context.getBean("testBean1");

  System.out.println("testString is: " + testBean1.getTestString());
 }
}
--------------------------------------

透過此產生的context,可使用getBean("xxx")來取得bean定義檔中的bean實例。但取出後是Object類別,要手動做casting。


Type 3 (Constructor) IoC

若要在bean定義檔中實現Constructor Injection,則在類別中要增加constructor setting的方式來設定field的值,記得,若增加了非default constructor,要自行增加一個「無參數」的constructor(即使沒有程式內容)以符合bean規則。
TestBean1.java:
--------------------------------------
package com.aidc.bean;

public class TestBean1 {
 private String testString;

 public TestBean1() {
 }
 
 public TestBean1(String testString) {
  this.testString = testString;
 }

 public String getTestString() {
  return testString;
 }

 public void setTestString(String testString) {
  this.testString = testString;
 }
}
--------------------------------------

在bean定義檔中,我們使用constructor-arg來設定constructor的參數,而index表示第幾個參數(index值由0開始起算)。例如我們在testBean1_cons實例中使用constructor injection,將testString注入。
applicationContext.xml:
--------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
 <bean id="testBean1" class="com.aidc.bean.TestBean1">
  <property name="testString" value="Hello!!"></property></bean>
 <bean id="testBean1_cons" class="com.aidc.bean.TestBean1">
  <constructor-arg index="0" value="Rexmen!"></constructor-arg></bean>
</beans>
--------------------------------------

而實作的程式碼如下,呼叫constructor injection的bean時並沒有什麼不同:
Test1.java:
--------------------------------------
package com.aidc.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.aidc.bean.TestBean1;

public class Test1 {
 public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  TestBean1 testBean1 = (TestBean1)context.getBean("testBean1");
  System.out.println("bean1 testString is: " + testBean1.getTestString());
  
  TestBean1 testBean1_cons = (TestBean1)context.getBean("testBean1_cons");
  System.out.println("bean1_cons testString is: " + testBean1_cons.getTestString());
 
 }
}
--------------------------------------

而執行結果如下:
--------------------------------------
bean1 testString is: Hello!!
bean1_cons testString is: Rexmen!
--------------------------------------


屬性參考的注入

若要注入的屬性是另一個在bean定義檔中定義的bean,可使用<ref>來完成參考屬性的注入。
例如我們把TestBean1加入一個Date類別的field,名為date(並設定其setter以及getter)。並且在bean定義檔中增加一個Date的bean。
applicationContext.xml:
--------------------------------------
...(略)
 <bean id="dateBean1" class="java.util.Date"></bean>
 <bean id="testBean1" class="com.aidc.bean.TestBean1">
   <property name="testString" value="Hello!!"></property>
   <property name="date" ref="dateBean1"></property>
</bean>
...(略)
--------------------------------------

在程式碼我們將此注入的屬性列出。(會列出目前的時間)
Test1.java:
--------------------------------------
...(略)
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  TestBean1 testBean1 = (TestBean1)context.getBean("testBean1");
  System.out.println("bean1 testString is: " + testBean1.getTestString());
  System.out.println("Current date is: " + testBean1.getDate());
...(略)
--------------------------------------

執行結果如下:
--------------------------------------
bean1 testString is: Hello!!
Current date is: Fri Feb 02 10:03:31 CST 2007
--------------------------------------

註:
若以上的Date屬性不想參考bean定義檔先定義好的 bean實例,而是想要直接在注入時依照Date類別直接產生一個instance,直可以直接使用<bean>作為注入方法。
applicationContext.xml:
--------------------------------------
...(略)
 <bean id="testBean1" class="com.aidc.bean.TestBean1">
   <property name="testString" value="Hello!!"></property>
   <property name="date">
      <bean class="java.util.Date"></bean>
   </property>

</bean>
...(略)
--------------------------------------


自動綁定功能

Spring提供透過Type或者Name的方式自動綁定某個Bean實例,但我個人覺得這種方式有模稜兩可的感覺,省掉幾個步驟,但卻讓定義檔不清不楚的,因此我在此不多提此作法。



注入集合物件

我們來談談若是以集合物件作為參數時怎麼注入呢?所謂的集合物件就是陣列(Array)、List、Map、Set等等的物件。依照不同的集合物件在bean定義檔中有不同的注入宣告方法。

a. 陣列(Array)與List:
均使用<list>標籤,並使用<value>指定其字串,或者使用<ref>來參考到其他的Bean的instance。
applicationContext.xml:
--------------------------------------
...(略)
<property name="someStrArray">
        <list>
                <value>Spring</value>
                <value>Framework</value>
        </list>

</property>

<property name="someObjArray">
        <list>
                <ref bean="someBean1" />
                <ref bean="someBean2" />
        </list>

</property>


<property name="someList">
        <list>
                <value>ListTest</value>
                <ref bean="someBean1" />
                <ref bean="someBean2" />
        </list>

</property>
...(略)
--------------------------------------

b. Map:
使用<map>標籤,並使用<entry>標籤指定key,然後在其下使用<value>來指定字串, 相同的,可使用<ref>來參考到其他的Bean的instance。
applicationContext.xml:
--------------------------------------
...(略)
<property name="someMap">
        <map>
                <entry key="MapTest">
                        <value>Test</value>
                </entry>
                <entry key="someKey1">
                        <ref bean="some1">
                </entry>        
        </map>

</property>
...(略)
--------------------------------------


c. Set:
使用<set>標籤,然後在其下使用<value>來指定字串, 相同的,可使用<ref>來參考到其他的Bean的instance。
applicationContext.xml:
--------------------------------------
...(略)
<property name="someSet">
        <set>
                <value>SetTest</value>
                <ref bean="someBean1" />
                <ref bean="someBean2" />
        </set>

</property>
...(略)
--------------------------------------

相簿設定
標籤設定
相簿狀態