javascript
Spring bean依赖注入、bean的装配及相关注解
依賴注入
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.xsdhttp://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.xsdhttp://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;}@Overridepublic 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.xsdhttp://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;}@Overridepublic 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.xsdhttp://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;}@Overridepublic 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.xsdhttp://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;}@Overridepublic 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.xsdhttp://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;@Autowiredpublic void setLicense(License license) {this.license = license;}@Overridepublic String toString() {return "Driver [license=" + license + "]";}//getter }構造方法上
@Component("driver") public class Driver {private License license;@Autowiredpublic Driver(License license){this.license = license;}@Overridepublic String toString() {return "Driver [license=" + license + "]";} }屬性上
@Component("driver") public class Driver {@Autowiredprivate License license;//getter,setter @Overridepublic String toString() {return "Driver [license=" + license + "]";} }@Resource(根據名稱裝配)
@Component("application") public class Application {@Resource(name="applicationUser")private ApplicationUser user;@Overridepublic String toString() {return "Application [user=" + user + "]";} }@Qualifier(與@Autowired結合使用,實現按名稱裝配)
例子背景::存在兩個Car接口的實現類,其中一個Car接口的實現類已被注冊為bean,且name為Mustang
@Component public 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 @Overridepublic String toString() {return "Driver [license=" + license + "]";} }基于以上原因,雖然@Autowired注解與@Resource功能類似,但是@Autowired還是比@Resource強大了那么一點點,個人建議使用@Autowired注解。
本文轉自風一樣的碼農博客園博客,原文鏈接:http://www.cnblogs.com/chenpi/p/6222595.html,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的Spring bean依赖注入、bean的装配及相关注解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 04、Vue.js---自定义过滤器
- 下一篇: 烂泥:centos安装及配置DNS服务器