Spring bean依賴注入、bean的裝配及相關註解,springbean

來源:互聯網
上載者:User

Spring bean依賴注入、bean的裝配及相關註解,springbean
依賴注入

Spring主要提供以下兩種方法用於依賴注入

  • 基於屬性Setter方法注入
  • 基於構造方法注入
Setter方法注入

例子:

public class Communication {     private Messaging messaging;           /*     * DI via Setter     */    public void setMessaging(Messaging messaging){        this.messaging = messaging;    }     public void communicate(){        messaging.sendMessage();    }}

如上Communication類有一個messaging屬性,並含有setMessaging方法,那麼使用Setter方法注入的時候,只需要使用如下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:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">     <bean id="activeMqMessaging" class="com.websystique.spring.domain.impl.ActiveMQMessaging" />     <bean id="communication" class="com.websystique.spring.Communication">        <property name="messaging">            <ref bean="activeMqMessaging" />        </property>    </bean> </beans>

這裡省略了ActiveMQMessaging的定義,實際上ActiveMQMessaging類是Messaging介面的一個實作類別。

構造方法注入

例子

public class Communication {     private Encryption encryption;         /*     * DI via Constructor Injection     */    public Communication(Encryption encryption){        this.encryption = encryption;    }      public void communicate(){        encryption.encryptData();    } }

注意以上Communication類有一個構造方法Communication(Encryption encryption),且含有一個入參,類型為Encryption,那麼使用構造方法注入的時候,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:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">     <bean id="rsaEncryption" class="com.websystique.spring.domain.impl.RSAEncryption" />     <bean id="communication" class="com.websystique.spring.Communication">        <constructor-arg type="com.websystique.spring.domain.Encryption">            <ref bean="rsaEncryption" />        </constructor-arg>    </bean> </beans>

注意,這裡省略了RSAEncryption的定義,不用在意這些細節,該類是Encryption介面的一個實作類別。

另外,為了避免構造方法重載帶來的歧義,這裡指定了入參類型為com.websystique.spring.domain.Encryption。

裝配

bean的裝配有兩種方式,手動裝配和自動裝配。注意,不要混淆,bean的裝配是依賴注入的具體行為,依賴注入的時候需要根據bean的名稱或類型等進行裝配。

手動裝配:通過在<property> 或者 <constructor>標籤中使用ref屬性,在上一小節的“依賴注入”部分使用的就是手動裝配;

<!-- default example (autowire="no") --><bean id="driver" class="com.websystique.spring.domain.Driver">    <property name="license" ref="license"/></bean> <bean id="license" class="com.websystique.spring.domain.License" >    <property name="number" value="123456ABCD"/></bean>

自動裝配:在<bean>標籤中使用autowire屬性;

<bean id="application" class="com.websystique.spring.domain.Application" autowire="byName"/>

本小節主要關注自動裝配,自動裝配有以下四種方式:

  • autowire="byName" : 根據名稱
  • autowire="byType" : 根據類型
  • autowire="constructor" : 根據構造方法入參類型
  • autowire="no" : 不使用自動裝配,即預設,手動裝配
autowire="byName"

例子:

public class Application {     private ApplicationUser applicationUser;     public ApplicationUser getApplicationUser() {        return applicationUser;    }     public void setApplicationUser(ApplicationUser applicationUser) {        this.applicationUser = applicationUser;    }     @Override    public String toString() {        return "Application [applicationUser=" + applicationUser + "]";    }}

該類有一個屬性叫applicationUser,那麼根據名稱自動裝配的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:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">     <!-- byName example -->    <bean id="application" class="com.websystique.spring.domain.Application" autowire="byName"/>     <bean id="applicationUser" class="com.websystique.spring.domain.ApplicationUser" >        <property name="name" value="superUser"/>    </bean>
</beans>
autowire="byType"

例子

public class Employee {     private EmployeeAddress address;     public EmployeeAddress getAddress() {        return address;    }     public void setAddress(EmployeeAddress address) {        this.address = address;    }     @Override    public String toString() {        return "Employee [address=" + address + "]";    }}

該類有一個屬性類型為EmployeeAddress,那麼根據類型自動裝配的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:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">     <!-- byType example -->    <bean id="employee" class="com.websystique.spring.domain.Employee" autowire="byType"/>     <bean id="employeeAddress" class="com.websystique.spring.domain.EmployeeAddress" >        <property name="street" value="112/223,SantaVila"/>        <property name="city" value="Nebraska"/>    </bean> </beans>
autowire="constructor"

例子

public class Performer {         private Instrument instrument;         public Performer(Instrument instrument){        this.instrument = instrument;    }     @Override    public String toString() {        return "Performer [instrument=" + instrument + "]";    }}

該類有一個構造方法,入參的類型為Instrument,那麼根據構造方法自動裝配的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:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">     <!-- constructor example -->    <bean id="performer" class="com.websystique.spring.domain.Performer" autowire="constructor"/>     <bean id="instrument" class="com.websystique.spring.domain.Instrument" >        <property name="name" value="PIANO"/>    </bean> </beans>
autowire="no"
public class Driver {     private License license;         public void setLicense(License license) {        this.license = license;    }     public License getLicense() {        return license;    }     @Override    public String toString() {        return "Driver [license=" + license + "]";    }}

該類有一個屬性license,由於我們不打算使用自動裝配功能,那麼只能使用手動裝配了,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:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">     <!-- default example (autowire="no") -->    <bean id="driver" class="com.websystique.spring.domain.Driver" autowire="no">        <property name="license" ref="license"/>    </bean>     <bean id="license" class="com.websystique.spring.domain.License" >        <property name="number" value="123456ABCD"/>    </bean> </beans>

注意,如果不配置license的ref引用的話,license將為null。

相關註解

主要涉及以下三個註解

  • @Autowired
  • @Resource
  • @Qualifier

@Autowired可應用於構造方法、屬性、setter方法或配置類@Configuration的方法上,該註解根據bean的資料類型進行裝配,如果你想希望根據bean的名稱進行裝配可以使用帶name屬性的@Resource註解;另外@Qualifier註解經常與@Autowired註解結合使用,用於解決一個應用中存在多個同種類型的bean的情況,下面將給出各個註解的樣本。

@Autowired(根據類型自動裝配)

setter方法上

@Component("driver")public class Driver {     private License license;         @Autowired    public void setLicense(License license) {        this.license = license;    }     @Override    public String toString() {        return "Driver [license=" + license + "]";    }    //getter}

構造方法上

@Component("driver")public class Driver {     private License license;         @Autowired    public Driver(License license){        this.license = license;    }         @Override    public String toString() {        return "Driver [license=" + license + "]";    }}

屬性上

@Component("driver")public class Driver {    @Autowired    private License license;         //getter,setter     @Override    public String toString() {        return "Driver [license=" + license + "]";    }}
@Resource(根據名稱裝配)
@Component("application")public class Application {     @Resource(name="applicationUser")    private ApplicationUser user;     @Override    public String toString() {        return "Application [user=" + user + "]";    }}
@Qualifier(與 @Autowired結合使用,實現按名稱裝配)

例子背景::存在兩個Car介面的實作類別,其中一個Car介面的實作類別已被註冊為bean,且name為Mustang

@Componentpublic class Bond {     @Autowired    @Qualifier("Mustang")    private Car car;         public void showCar(){        car.getCarName();    }}

注意,以上例子如果不使用@Qualifier限定的話,將拋出如下異常,表明存在多個類型相同的bean:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.websystique.spring.domain.Car] is defined: expected single matching bean but found 2: Ferari,Mustang
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:970)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
    ... 14 more

最後提醒下,被@Autowired註解標註預設情況下能保證成功注入,如果注入不成功(往往是找不到,或存在歧義),Spring會拋出異常。當然,有時候可能會有特殊需求,不希望bean被強制裝配,那麼可以在@Autowired上添加required=false屬性,表明該bean的裝配是可選的,找不到的話,就為null吧,如下樣本:

@Component("driver")public class Driver {    @Autowired(required=false)    private License license;         //getter,setter     @Override    public String toString() {        return "Driver [license=" + license + "]";    }}

基於以上原因,雖然@Autowired註解與@Resource功能類似,但是@Autowired還是比@Resource強大了那麼一點點,個人建議使用@Autowired註解。

參考資料

http://websystique.com/spring/spring-dependency-injection-example-with-constructor-and-property-setter-xml-example/

http://websystique.com/spring/spring-beans-auto-wiring-example-using-xml-configuration/

http://websystique.com/spring/spring-dependency-injection-annotation-beans-auto-wiring-using-autowired-qualifier-resource-annotations-configuration/

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.