註釋配置相對於 XML 配置具備不少的優點:html
它能夠充分利用 Java 的反射機制獲取類結構信息,這些信息能夠有效減小配置的工做。如使用 JPA 註釋配置 ORM 映射時,咱們就不須要指定 PO 的屬性名、類型等信息,若是關係表字段和 PO 屬性名、類型都一致,您甚至無需編寫任務屬性映射信息——由於這些信息均可以經過 Java 反射機制獲取。java
註釋和 Java 代碼位於一個文件中,而 XML 配置採用獨立的配置文件,大多數配置信息在程序開發完成後都不會調整,若是配置信息和 Java 代碼放在一塊兒,有助於加強程序的內聚性。而採用獨立的 XML 配置文件,程序員在編寫一個功能時,每每須要在程序文件和配置文件中不停切換,這種思惟上的不連貫會下降開發效率。程序員
所以在不少狀況下,註釋配置比 XML 配置更受歡迎,註釋配置有進一步流行的趨勢。Spring 2.5 的一大加強就是引入了不少註釋類,如今您已經可使用註釋配置完成大部分 XML 配置的功能。在這篇文章裏,咱們將向您講述使用註釋進行 Bean 定義和依賴注入的內容。web
Java EE5中引入了「Java平臺的公共註解(Common Annotations for the Java Platform)」,並且該公共註解從Java SE 6一開始就被包含其中。 2006年5月,BEA系統宣佈了他們在一個名爲Pitchfork的項目上與Interface21的合做,該項目提供了基於Spring的Java EE 5編程模型的實現,包括支持用於注入(injection)、攔截( interception)和事務處理(transactions)的JSR-250註解和EJB 3註解(JSR-220)。 在2.5版本中,Spring框架的核心(core)如今支持如下JSR-250註解:正則表達式
@Resource spring
@PostConstructexpress
@PreDestroyapache
結合Spring,這些註解在任何開發環境下均可以使用——不管是否有應用程序服務器——甚至是集成測試環境均可以。激活這樣的支持僅僅是註冊一個單獨的Spring post-processor的事情:編程
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/> ruby
@Resource 註解被用來激活一個命名資源(named resource)的依賴注入,在JavaEE應用程序中,該註解被典型地轉換爲綁定於JNDI context中的一個對象。 Spring確實支持使用@Resource 經過JNDI lookup來解析對象,默認地,擁有與@Resource 註解所提供名字相匹配的「bean name(bean名字)」的Spring管理對象會被注入。 在下面的例子中,Spring會向加了註解的setter方法傳遞bean名爲「dataSource」的Spring管理對象的引用。
@Resource(name="dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
直接使用@Resource 註解一個域(field)一樣是可能的。經過不暴露setter方法,代碼愈發緊湊而且還提供了域不可修改的額外益處。正以下面將要證實的,@Resource 註解甚至不須要一個顯式的字符串值,在沒有提供任何值的狀況下,域名將被看成默認值。
@Resource
private DataSource dataSource; // inject the bean named 'dataSource'
該方式被應用到setter方法的時候,默認名是從相應的屬性衍生出來,換句話說,命名爲'setDataSource'的方法被用來處理名爲'dataSource'的屬性。
private DataSource dataSource;
@Resource
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
當@Resource 沒有顯式提供名字的時候,若是根據默認名字找不到對應的Spring管理對象,注入機制會回滾至類型匹配(type-match)。若是恰好只有一個Spring管理對象符合該依賴的類型,那麼它會被注入。經過設置CommonAnnotationBeanPostProcessor 的‘fallbackToDefaultTypeMatch’屬性爲「false」(默認值是「true」)能夠禁用這一特性。
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="fallbackToDefaultTypeMatch" value="false"/>
</bean>
正如上文所提到的,在解析標有@Resource 註解的依賴時,Spring支持JNDI-lookup。如若要強制對全部使用@Resource 註解的依賴進行JNDI lookup,那也只要將CommonAnnotationBeanPostProcessor的'alwaysUseJndiLookup' 標識設置爲true就能夠了(默認值是false)。
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true"/>
</bean>
另外一個選擇是,激活指定爲‘resource-ref-mappings’的依據全局JNDI名的查找,在@Resource 註解內提供‘mappedName’屬性。即便目標對象其實是一個JNDI資源,仍然推薦引入一個Spring管理對象,這樣能夠提供一個間接層而且所以下降耦合程度。自Spring2.0開始添加命名空間以來,定義一個委託Spring處理JNDI lookup的bean也變得愈發簡練:
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
這個方法的優勢在於間接層帶來了巨大的部署彈性。好比說,一個單獨的系統測試環境應該再也不須要JNDI註冊。在這種狀況下,在系統測試配置中能夠提供以下的bean定義:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
順便提一下,上面的例子中,實際的JDBC鏈接屬性從一個屬性文件(properties file)解析而來,在這個屬性文件裏,關鍵字與提供的${佔位符}互相對應,這須要註冊一個名爲PropertyPlaceholderConfigurer的BeanFactoryPostProcessor實現來完成。這是具體化那些屬性(一般是針對特定環境的屬性)經常使用的技術,這些屬性可能比其餘配置修改得更爲頻繁。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
Srping2.5中新加入了‘context’命名空間,這個命名空間讓咱們可以獲得更爲簡潔的方式來實現屬性佔位符(property placeholder)的配置:
<context:property-placeholder location="classpath:jdbc.properties"/>
@PostConstruct 和@PreDestroy註解分別用來觸發Spring的初始化和銷燬回調。這個特性在原有基礎上獲得了擴展,但並無替代在Spring2.5以前版本中提供的一樣的回調的另兩個選項。第一個選項是實現Spring的InitializingBean 和DisposableBean 接口中的一個或兩個。這兩個接口都須要一個回調方法的實現(分別是afterPropertiesSet()和destroy() )。這種基於接口的方法利用了Spring自動識別任何實現這些接口的Spring管理對象的能力,於是再也不須要另外的配置。另外一方面,Spring的一個關鍵目標是儘量的非侵入。所以,許多Spring用戶並不採用實現這些Spring特定接口的方法,而利用第二個選項,那就是提供他們本身的初始化和銷燬方法。儘管入侵性小,但缺點在於使用這個方式的話就必須顯式聲明bean元素的init-method或destroy-method屬性。顯式配置有時候是必須的,例如當回調須要在開發人員控制能力以外的代碼上被調用的時候。PetClinic應用程序很好地說明了這個場景。當它和JDBC配置一塊兒運行的時候,會用到一個第三方DataSource,而且它顯式聲明瞭一個destroy-method。另外要注意到的是,單獨的鏈接池數據源是dataSource的另外一個部署選項,而且不須要修改任何代碼。
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"p:url="${jdbc.url}"p:username="${jdbc.username}"p:password="${jdbc.password}"/>
在使用Spring2.5的過程當中,若是一個對象須要調用一個初始化的回調方法的話,這個回調方法能夠採用@PostConstruct來註解。例如一個假想的例子,一個後臺任務須要在啓動的時候就開始對一個文件目錄進行輪詢:
public class FilePoller {
@PostConstruct
public void startPolling() {
}
}
相似地,一個在Spring管理對象上用@PreDestroy註解的方法會在這個對象寄宿的應用程序上下文(application context)關閉的時候被調用。
public class FilePoller {
@PreDestroy
public void stopPolling() {
}
}
在添加了對JSR-250註解的支持之後,如今的Spring2.5結合前面提到的兩種生命週期方法的長處。將@PostConstruct和@PreDestroy做爲方法層註解加入,足能夠實如今受Spring管理的上下文(context)中觸發回調。換句話說,不須要另外基於XML的配置。同時,這兩個註解是Java語言自己的一部分(甚至被包括在Java SE 版本6中),因此無需引入特定Spring包。這兩個註解擁有在其餘環境中也能理解的標識語義的優勢,隨着時間的推移,Java開發人員可能會發現這些註解在第三方開發庫中被愈來愈多的運用到。最後,基於註解生命週期回調的其中一個有趣的結果是,不止一個方法能夠帶有這兩個註解中的任何一個,而且全部註解了的方法會被調用。
激活剛剛描述的關於@Resource 、@PostConstruct和@PreDestroy註解的全部行爲,正如上文提到的,須要爲Spring的CommonAnnotationBeanPostProcessor提供一個bean定義。但另外一個更簡練的方法則多是使用2.5中的新的context命名空間:
<context:annotation-config/>
引入這個單個元素將不僅僅註冊一個CommonAnnotationBeanPostProcessor,也會像下文將敘述的那樣激活自動裝配(autowire)行爲。CommonAnnotationBeanPostProcessor也爲@WebServiceRef 和@EJB註解提供支持。這些將在本文系列的第三篇中和Spring2.5爲企業集成提供的其餘新特性一塊兒討論。
涵蓋Spring對自動裝配支持的文檔中經常會提到因爲自動裝配機制的粗粒度而伴隨有不少限制性。Spring2.5以前,自動裝配能夠經過不少不一樣的方式來配置:構造器,類型setter,名字setter,或者自動偵測(在該方式中Spring選擇自動裝配一個構造器或者類型setter)。這些不一樣的選擇確實提供了很大程度的靈活性,但它們中沒有一個方法可以提供細粒度控制。換句話說,Spring2.5以前還不可能自動裝配某個對象setter方法的特定子集,或者經過類型或名字來自動裝配它的一些屬性。結果,許多Spring用戶意識到將自動裝配應用到構建原型和測試中的好處,但當提到在產品中維護和支持系統時,大部分人認爲,加入冗長的顯式配置對於澄清它所擔負的職責是很是值得的。
然而,Spring2.5大幅度地改變了佈局。如上文所述,自動配置選項如今已經被擴展,支持JSR-250 @Resource 註解來激活在每一個方法或域基礎上被命名資源的自動裝配。然而,@Resource 註解若單獨使用的話有不少限制。所以,Sring2.5引進了一個名爲@Autowired的註解進一步提升控制級別。爲激活這裏所講的行爲須要註冊一個單獨的bean定義:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
另外如上文提到的,context命名空間提供了一個更簡明的方法。它將激活本文所討論的兩個post-processor(AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor)和咱們在Spring2.0中引入的基於註解的post-processor:RequiredAnnotationBeanPostProcessor和PersistenceAnnotationBeanPostProcessor。
<context:annotation-config/>
利用@Autowired 註解能夠對相應類型注入依賴。域、構造器和方法均可以激活此行爲。實際上,aotowired方法並不必定要是setter方法,且能夠接受多個參數。下面這個例子是完整的可接受的用法:
@Autowired
public void setup(DataSource dataSource, AnotherObject o) { }
默認地,標有@Autowired註解的依賴被認爲是必須的。然而,也能夠將required屬性值設置爲false來聲明它們中的任何一個。在下面這個例子中,DefaultStrategy只有在context命名空間中沒有SomeStrategy類型的Spring管理對象時才能被使用。
@Autowired(required=false)
private SomeStrategy strategy = new DefaultStrategy();
經過類型進行的自動裝配明顯地在Spring context包含多於一個指望類型的對象的時候形成歧義。默認地,若是一個必須的依賴沒不是剛好一個bean與之對應的話,自動裝配機制就會失敗。一樣的,對於任何一個可選屬性,若是它擁有一個以上的候選,也都會失敗(若是屬性可選且沒有任何候選可用的話,該屬性則會被簡單地跳過)。有不少不一樣的配置選項能夠避免這些衝突。
若Context中擁有一個指定類型的一個主關鍵實例,對這個類型定義的bean定義應該包含‘primary’屬性。當Context中含有其餘可用實例的時候這個方法就很適用,但那些非主關鍵實例老是顯式配置的。
<bean id="dataSource" primary="true" />
在須要更多控制的時候,任何autowired的域、構造參數、或者方法參數能夠進一步加註@Qualifier註解。qualifier能夠包含一個字符串值,在這種狀況下,Spring會試圖經過名字來找到對應的對象。
@Autowired
@Qualifier("primaryDataSource")
private DataSource dataSource;
@Qualifier做爲一個獨立註解存在的主要緣由是它能夠被應用在構造器參數或方法參數上,但上文提到的@Autowired註解只能運用在構造器或方法自己。
@Autowired
public void setup(@Qualifier("primaryDataSource") DataSource dataSource, AnotherObject o) { }
事實上,@Qualifier做爲一個單獨的註解在定製化方面提供了更多的好處。用戶自定義的註解在自動裝配過程當中也能夠起到qualifier的做用,最簡單的實現方式是在運用自定義註解的同時將@Qualifier做爲它的元註解。
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface VetSpecialty { }
自定義註解能夠選擇包含一個值來提供經過名字匹配的功能,但更廣泛的用法是將它做爲「標記」註解或定義一個對qualifier過程提供一些更多含義的值。例如,下面這個摘錄則描繪了一個域,它應該和經過名字匹配獲得的結果中合格的對象進行自動裝配。
@Autowired
@VetSpecialty("dentistry")
private Clinic dentistryClinic;
在使用XML配置來達到依賴解析的目標時,'qualifier' 子元素能夠被加註到bean定義中。在下文的組件掃描部分,咱們將呈現一個可供選擇的非XML方法。
<bean id="dentistryClinic" class="samples.DentistryClinic">
<qualifier type="example.VetSpecialty" value="dentistry"/>
</bean>
爲了不對@Qualifier註解的任何依賴性,能夠在Spring context中提供一個CustomAutowireConfigurer的bean定義並直接註冊全部自定義註解類型:
<bean class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>example.VetSpecialty</value>
</set>
</property>
</bean>
如今,自定義修飾符被顯式聲明瞭,就再也不須要@Qualifier這個元註解符了。
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface VetSpecialty { }
其實,在配置AutowiredAnnotationBeanPostProcessor的時候,取代@Autowired註解都是有可能的。
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
<property name="autowiredAnnotationType" value="example.Injected"/>
</bean>
大部分狀況下,定義自定義‘標記’註解的能力結合經過名字或其餘文法值進行匹配選項,足以完成自動裝配過程的細粒度控制。但Spring還支持在qualifier註解上任意數目的任意屬性。好比,下面是一個極爲細粒度修飾的例子。
@SpecializedClinic(species="dog", breed="poodle")
private Clinic poodleClinic;
自定義修飾符的實現應該定義這些屬性:
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface SpecializedClinic {
String species();
String breed();
}
自定義修飾符屬性能夠匹配那些XML中bean定義的qualifier註解的屬性子元素。這些元素一般以鍵/值對方式提供。
<bean id="poodleClinic" class="example.PoodleClinic">
<qualifier type="example.SpecializedClinic">
<attribute key="species" value="dog"/>
<attribute key="breed" value="poodle"/>
</qualifier>
</bean>
目前爲止,關於autowire的描述都只是針對單獨的實例,其實也支持集合。在任何須要獲得全部context中某種特定類型的Spring管理對象的時候,只須要簡單地在一個強類型(strongly-typed)集合上加註@Autowired 註解。
@Autowired
private List<Clinic> allClinics;
本章節最後一個值得指出的特性是自動裝配的使用替代了Spring的Aware接口。在Spring2.5以前,若是某個對象須要一個Spring context的ResourceLoader的引用,它能夠經過實現ResourceLoaderAware的方式使得Spring經過setResourceLoader(ResourceLoader resourceLoader)方法來提供該依賴。藉助一樣的方法能夠獲得Spring管理的MessageSource的引用,甚至能夠獲得ApplicationContext自己。對於Spring2.5用戶而言,這個行爲如今經過autowiring獲得全面支持(須要指出的是包含這些Spring特定依賴的時候應該考慮周到,特別是它們只能用於從業務邏輯清楚地分割出來的基礎構架代碼中)。
@Autowired
private MessageSource messageSource;
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private ApplicationContext applicationContext;
從2.0版本開始,Spring引入了構造型(stereotype)註解的概念以及將@Repository註解做爲數據訪問代碼的標記的方法。在此基礎上,Spring2.5又加入了兩個新的註解 —— @Service 和@Controller 來完成爲一般的三層架構(數據訪問對象、服務、web控制器)角色委任。Spring2.5也引入了泛型@Component註解,其餘構造型可從邏輯上對其進行擴展。經過清晰地指明應用程序的角色,這些構造型方便了Spring AOP和post-processor的使用,這些post-processor給基於這些角色的加了註解的對象提供了附加行爲。好比,Spring2.0引入了PersistenceExceptionTranslationPostProcessor對任何帶有@Repository 註解的對象自動激活其數據訪問異常轉換。
這些註解一樣能夠結合Spring2.5其餘一些新性能來使用:自動偵測classpath上的組件。儘管XML已經成爲最多見的Spring元數據的格式,但它決不是惟一選擇。實際上,Spring容器內的元數據是由純Java來表示的,當XML被用來定義Spring管理對象時,在實例化過程以前,那些定義會被解析並轉化成Java對象。Spring2.5的一個巨大的新功能是支持從源碼層註解讀取元數據。於是,上文描述的自動裝配機制使用註解的元數據來注入依賴,但它仍然須要註冊至少一個bean定義以便提供每一個Spring管理對象的實現類。組件掃描功能則使得這個XML中最起碼的bean定義都再也不存在需求性。
正如上面所示,Spring註解驅動的自動裝配能夠在不犧牲細粒度控制的前提下極大程度地減小XML的使用。組件偵測機制將這個優勢更發揚光大。全面替代XML中的配置再也不必要,組件掃描反而能夠處理XML元數據來簡化總體配置。結合XML和註解驅動技術能夠獲得一個平衡優化的方法,這在2.5版本的PetClinic範例中有詳細闡述。在該範例中,基礎構架組件(數據源、事務管理等)結合上文提到的外化屬性在XML中定義。數據訪問層對象也有部分在XML中定義,它們的配置也都利用了@Autowired註解來簡化依賴注入。最後,web層控制器徹底不在XML中顯式定義,相反,下面提供的這段配置被用來觸發全部web控制器的自動偵測:
<context:component-scan base-package="org.springframework.samples.petclinic.web"/>
須要注意到的是這段示例中使用到了base-package屬性。組件掃描的默認匹配規則會遞歸偵測該包(多個包能夠以逗號分隔的list方式提供)內的全部類的全部Spring構造型註解。正由於如此,PetClinic應用程序範例中的各種控制器的實現都採用了@Controller 註解(Spring的內置構造型之一)。請看下面這個例子:
@Controller
public class ClinicController {
private final Clinic clinic;
@Autowired
public ClinicController(Clinic clinic) {
this.clinic = clinic;
}
自動偵測組件在Spring容器中註冊,就像它們在XML中被定義同樣。如上所示,那些對象能夠輪流利用註解驅動的自動裝配。
組件掃描的匹配規則能夠經過過濾器(filter)來自定義,以根據類型、AspectJ表達式、或針對命名模式的正則表達式來決定包含或不包含哪些組件。默認的構造型也能夠被禁用。好比這裏有一個配置的例子,這個配置會忽略默認的構造型,但會自動偵測名字以Stub打頭或者包含@Mock 註解的全部類:
<context:component-scan base-package="example" use-default-filters="false">
<context:include-filter type="aspectj" expression="example..Stub*"/>
<context:include-filter type="annotation" expression="example.Mock"/>
</context:component-scan>
類型匹配的限制性也能夠用排他的過濾器控制。例如,除了@Repository註解外其餘都依賴於默認過濾器,那麼就須要加入一個排他過濾器(exclude-filter)。
<context:component-scan base-package="example">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
很明顯,有不少方法能夠擴展組件掃描來註冊自定義的類型。構造型註解是最簡單的選擇,因此構造型概念自己也是可擴展的。像先前提到的,@Component是泛型模型,@Repository、@Service ,和@Controller 註解都從該構造型邏輯擴展而得。正由於如此,@Component可被用來做爲元註解(也就是說,在另外的註解上聲明的註解),全部具備@Component元註解的自定義註解都會被默認掃描匹配規則自動偵測到。一個例子就有但願讓你領會到其實它根本沒有聽起來那麼難。
讓咱們回想一下在講@PostConstruct和@PreDestroy生命週期註解的時候的假想的後臺任務。也許一個應用程序有不少不少這樣的後臺任務,這些任務實例須要XML bean定義以便在Spring context裏註冊並使它們本身的生命週期方法在正確時候被調用。利用組件掃描就再也不須要這些顯式的XML bean定義。若是這些後臺任務都實現一個相同的接口或者都沿用一樣的命名慣例,那麼能夠用include-filters。然而,更簡單的方法是爲這些任務對象建立一個註解並提供@Component元註解。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface BackgroundTask {
String value() default "";
}
而後在全部後臺任務的類定義中提供自定義構造型註解。
@BackgroundTask
public class FilePoller {
@PostConstruct
public void startPolling() {
}
@PreDestroy
public void stopPolling() {
}
}
泛型@Component註解能夠像例子中提供的那樣簡單使用,自定義註解技術則提供了一個使用更具涵義的、領域特定的名字的機會。這些領域特定註解提供更深刻的機會,好比使用AspectJ切點表達式來識別全部後臺任務,以便增長advice來監控這些任務的活動性。
默認的,組件被偵測到的時候,Spring會自動生成一個沒有修飾符的類名做爲bean名字。上一個例子中,生成的bean名字會是filePoller。可是,任何加註了Spring構造型註解(@Component、@Repository、@Service 或 @Controller )或是加註了其餘的以@Component做爲元註解的註解(好比上面例子中的@BackgroundTask )的類,構造型註解的value屬性能夠被顯式指定,實例將該值做爲它的bean名字註冊到context中。接下來的例子裏,實例名應該是petClinic而不是默認生成的名字simpleJdbcClinic。
@Service("petClinic")
public class SimpleJdbcClinic {
}
一樣的,在下面修正版的FilePoller例子裏,生成的bean名字應該是poller而不是filePoller。
@BackgroundTask("poller")
public class FilePoller {
}
雖然全部Spring管理對象都被默認地看成單例實例來處理,但有些時候仍是有必要爲某個對象指明一個備用的範圍(scope)。舉個例子來講,在web層,一個Spring管理對象可能捆綁到request或session的範圍。對於2.0版本,Spring的scope機制更具延展性,這樣一來,自定義scope能夠被註冊到應用程序上下文(application context)。在XML配置中,僅僅是簡單地包含進scope屬性及該scope的名字就能夠了。
<bean id="shoppingCart" class="example.ShoppingCart" scope="session">
</bean>
Spring2.5中,爲被掃描的組件提供@Scope註解能夠起到一樣的做用。
@Component
@Scope("session")
public class ShoppingCart {
}
這裏要指出的最後一點是使用組件掃描時qualifier註解應用是多麼的簡單。在上一節,下面這個對象曾被做爲使用自定義qualifier註解進行自動裝配的例子:
@VetSpecialty("dentistry")
private Clinic dentistryClinic;
一樣的例子接着展示了在XML內使用‘qualifier’元素爲依賴提供指定目標bean定義。在使用組件掃描時,XML元數據不是必須的。但自定義修飾符也許在目標類定義中被做爲類型層註解而引入。另外一個將被掃描的@Repository實例做爲依賴的例子以下:
@Repository
@VetSpecialty("dentistry")
public class DentistryClinic implements Clinic {
}
最終,由於前面的例子展示了自定義註解及其屬性的例子,相等同的非XML表示依賴目標的方法以下:
@Repository
@SpecializedClinic(species="dog", breed="poodle")
public class PoodleClinic implements Clinic {
}
Spring2.5在不少方面都提供了頗有意義的新功能。本文主要關注於怎樣經過掌控Java註解的力量將配置簡化。就如在JSR-250中定義的那樣,Spring支持公共註解(Common Annotations),同時爲自動裝配過程的更細粒度的控制提供了額外註解。Spring2.5也擴展了從Spring2.0的@Repository就開始的構造型(stereotype)註解,而且全部這些構造型註解均可以和新的組件掃描功能結合使用。Spring2.5仍然全面支持基於XML的配置,同時它又引進了一個新的context命名空間對常見配置場景提供更精要的文法。實際上,支持XML和基於註解配置的無縫結合最終產生一個更爲平衡的全面的方法。基本構架的複雜配置能夠在模塊XML文件中定義,而應用程序棧日益增多地更高層配置能夠更多的從基於註解的技術中獲益——前提是都在同一個Spring2.5應用程序context內。
本文轉自:http://www.cnblogs.com/rubys/archive/2009/02/04/1384139.html