Dashboard > OpenSource Project > ... > Spring > 入門 05 - Constructor注入
OpenSource Project Log In   View a printable version of the current page.
入門 05 - Constructor注入
Added by 良葛格, last edited by 良葛格 on Nov 06, 2004
Labels: 
(None)

 Spring鼓勵的是setter injection,但也允許您使用constructor injection,使用setter或constructor來注入依賴關係視您的需求而定,這邊先來看看如何使用construtor injection,首先看看HelloBean:

HelloBean.java
package onlyfun.caterpillar;

public class HelloBean {
    private String helloWord = "hello";
    private String user = "NoBody";
   
    public HelloBean(String helloWord, String user) {
        this.helloWord = helloWord;
        this.user = user;
    }   
   
    public String sayHelloToUser() {
        return helloWord + "!" + user + "!";
    }
}

 為了突顯建構函式,我們這個HelloBean設計的簡陋,只提供了建構函式與必要的sayHelloToUser(),我們來看看bean的定義檔案:

bean.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="helloBean" class="onlyfun.caterpillar.HelloBean">
        <constructor-arg index="0"><value>Greeting</value></constructor-arg>
        <constructor-arg index="1"><value>Justin</value></constructor-arg>
    </bean>
</beans>

 在bean的定義檔案中,我們使用<constructor-arg>來表示我們將使用constructor injection,由於使用constructor injection時並不如setter injection時擁有setXXX()這樣易懂的名稱,所以我們必須指定參數的位置索引,index屬性就是用於指定我們的物件將注入至建構函式中的哪一個參數,索引值從0開始,符合Java索引的慣例。

 來看看測試程式:

Test.java
package onlyfun.caterpillar;

import java.io.*;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;

public class Test {
    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("bean.xml");
        BeanFactory factory = new XmlBeanFactory(is);
       
        HelloBean hello = (HelloBean) factory.getBean("helloBean");
        System.out.println(hello.sayHelloToUser());
    }
}

 實際的執行結果如下:

2004/10/21 下午 03:53:58 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
資訊: Loading XML bean definitions from resource for InputStream
2004/10/21 下午 03:54:02 org.springframework.beans.factory.support.AbstractBeanFactory getBean
資訊: Creating shared instance of singleton bean 'helloBean'
2004/10/21 下午 03:54:03 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory autowireConstructor
資訊: Bean 'helloBean' instantiated via constructor [public onlyfun.caterpillar.HelloBean(java.lang.String,java.lang.String)]
Greeting!Justin!

 要討論使用constructor或setter來完成依賴注入這個問題,其實就等於在討論一個古老的問題,要在物件建立時就準備好所有的資源,或是在物件建立好後,使用setter來進行設定。

 使用constructor的好處之一是,您可以在建構物件的同時一併完成依賴關係的建立,如果要建立的物件關係很多,使用 constructorinjection會在建構函式上留下一長串的參數,這時使用setter會是個不錯的選擇,另一方面, setter可以有明確的名稱可以瞭解注入的物件會是什麼,像是setXXX()這樣的名稱會比記憶constructor上某個參數位置代表某個物件來得好。

 然而使用setter由於提供了setXXX()方法,所以不能保證相關的field成員或資源在執行時期不會被更改設定,所以如果您想要讓一些field成員或資源變為唯讀或是私有,使用constructor injection會是個簡單的選擇。

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.1.5a Build:#411 Mar 16, 2006) - Bug/feature request - Contact Administrators