@Repository、@Service、@Controller 和 @Component

@Repository、@Service、@Controller 和 @Component 將類標識爲Bean框架

Spring 自 2.0 版本開始,陸續引入了一些註解用於簡化 Spring 的開發。@Repository註解便屬於最早引入的一批,它用於將數據訪問層 (DAO 層 ) 的類標識爲 Spring Bean。具體只需將該註解標註在 DAO類上便可。同時,爲了讓 Spring 可以掃描類路徑中的類並識別出 @Repository 註解,須要在 XML 配置文件中啓用Bean 的自動掃描功能,這能夠經過<context:component-scan/>實現。以下所示:spa

 // 首先使用 @Repository 將 DAO 類聲明爲 Bean 
 package bookstore.dao; 
 @Repository 
 public class UserDaoImpl implements UserDao{ …… } 

 // 其次,在 XML 配置文件中啓動 Spring 的自動掃描功能
 <beans … > 
    ……
 <context:component-scan base-package=」bookstore.dao」 /> 
……
 </beans> 

如此,咱們就再也不須要在 XML 中顯式使用 <bean/> 進行Bean 的配置。Spring 在容器初始化時將自動掃描 base-package 指定的包及其子包下的全部 class文件,全部標註了 @Repository 的類都將被註冊爲 Spring Bean。prototype

爲何 @Repository 只能標註在 DAO 類上呢?這是由於該註解的做用不僅是將類識別爲Bean,同時它還能將所標註的類中拋出的數據訪問異常封裝爲 Spring 的數據訪問異常類型。 Spring自己提供了一個豐富的而且是與具體的數據訪問技術無關的數據訪問異常結構,用於封裝不一樣的持久層框架拋出的異常,使得異常獨立於底層的框架。component

Spring 2.5 在 @Repository的基礎上增長了功能相似的額外三個註解:@Component、@Service、@Constroller,它們分別用於軟件系統的不一樣層次:對象

  • @Component 是一個泛化的概念,僅僅表示一個組件 (Bean) ,能夠做用在任何層次。
  • @Service 一般做用在業務層,可是目前該功能與 @Component 相同。
  • @Constroller 一般做用在控制層,可是目前該功能與 @Component 相同。

經過在類上使用 @Repository、@Component、@Service 和 @Constroller 註解,Spring會自動建立相應的 BeanDefinition 對象,並註冊到 ApplicationContext 中。這些類就成了 Spring受管組件。這三個註解除了做用於不一樣軟件層次的類,其使用方式與 @Repository 是徹底相同的。接口

另外,除了上面的四個註解外,用戶能夠建立自定義的註解,而後在註解上標註 @Component,那麼,該自定義註解便具備了與所@Component 相同的功能。不過這個功能並不經常使用。ci

當一個 Bean 被自動檢測到時,會根據那個掃描器的 BeanNameGenerator 策略生成它的 bean名稱。默認狀況下,對於包含 name 屬性的 @Component、@Repository、 @Service 和@Controller,會把 name 取值做爲 Bean 的名字。若是這個註解不包含 name值或是其餘被自定義過濾器發現的組件,默認 Bean 名稱會是小寫開頭的非限定類名。若是你不想使用默認 bean命名策略,能夠提供一個自定義的命名策略。首先實現 BeanNameGenerator接口,確認包含了一個默認的無參數構造方法。而後在配置掃描器時提供一個全限定類名,以下所示:作用域

 <beans ...> 
 <context:component-scan 
    base-package="a.b" name-generator="a.SimpleNameGenerator"/> 
 </beans> 

與經過 XML 配置的 Spring Bean 同樣,經過上述註解標識的Bean,其默認做用域是"singleton",爲了配合這四個註解,在標註 Bean 的同時可以指定 Bean 的做用域,Spring2.5 引入了 @Scope 註解。使用該註解時只需提供做用域的名稱就好了,以下所示:開發

 @Scope("prototype") 
 @Repository 
 public class Demo { … } 

若是你想提供一個自定義的做用域解析策略而不使用基於註解的方法,只需實現 ScopeMetadataResolver接口,確認包含一個默認的沒有參數的構造方法。而後在配置掃描器時提供全限定類名:get

 <context:component-scan base-package="a.b"
 scope-resolver="footmark.SimpleScopeResolver" /> 
相關文章
相關標籤/搜索