自動偵測spring元件
從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_r="example..Stub*"/>
<context:include-filter type="annotation" expression_r="example.Mock"/>
</context:component-scan>
型別匹配的限制性也可以用排他的過濾器控制。例如,除了@Repository註解外其他都依賴於預設過濾器,那麼就需要加入一個排他過濾器(exclude-filter)。
<context:component-scan base-package="example">
<context:exclude-filter type="annotation" expression_r="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 {
...
}
相關文章
- Spring 自動掃描元件Spring元件
- 自動化元件測試元件
- Web應用主動偵測工具SkipfishWeb
- Spring MVC自動化單元測試SpringMVC
- 自動化測試之控制元件點選控制元件
- 電子元件的自動AXI射線檢測元件
- Spring 註解自動裝載和檢測Spring
- App自動化測試:高階控制元件互動技巧APP控制元件
- 自動化測試畫布控制元件找不到控制元件
- Spring Boot 自動配置的原理、核心註解以及利用自動配置實現了自定義 Starter 元件Spring Boot元件
- 自動化測試系列 —— UI自動化測試UI
- Spring AOP 實現《自動自動填充Entity》Spring
- 【Spring註解驅動開發】元件註冊-@ComponentScan-自動掃描元件&指定掃描規則Spring元件
- Spring 容器自動注入.Spring
- Autocomplete自動補全元件-HeyUI元件庫元件UI
- Vue的變化偵測原理Vue
- 自己動手寫Web自動化測試框架(3):操縱Web控制元件Web框架控制元件
- 自己動手寫Web自動化測試框架(4):驗證Web控制元件Web框架控制元件
- Jquery 自動完成控制元件jQuery控制元件
- 【自動化測試入門】自動化測試思維
- Spring AOP 自動建立代理Spring
- Spring自動裝配BeansSpringBean
- 自動裝配【Spring autowire】Spring
- Spring 自動裝配AutoWireSpring
- Spring Boot 自動配置原理Spring Boot
- 測者的測試技術手冊:自動的自動化EvoSuite 自動生成JUnit的測試用例UI
- 利用tox打造自動自動化測試框架框架
- 自動的自動化:EvoSuite 自動生成JUnit的測試用例UI
- 自動化裝置測試與自動化測試的區別
- 頁面滾動偵聽器
- oracle偵聽無法啟動Oracle
- Spring Boot 自動裝配原理Spring Boot
- Spring Boot核心原理-自動配置Spring Boot
- spring框架半自動註解Spring框架
- [spring-rabbit]自動配置原理Spring
- Jenkins自動部署spring bootJenkinsSpring Boot
- Spring IOC容器-自動裝配Spring
- 自動化測試理解