如果我們不使用xml設定檔來配置Bean執行個體,那麼我們只能指望Spring會自動搜尋某些路徑下的Java類,並將這些Java類註冊成Bean執行個體。
Spring要求程式員顯式指定搜尋哪些路徑下的Java類,Spring將會把合適的Java類全部註冊成Spring Bean。現在的問題是:Spring怎麼知道應該把哪些Java類當成Bean類處理呢?這就需要使用Annotation了,Spring通過使用一些特殊的Annotation來標註Bean類。Spring提供了如下幾個Annotation來標註Spring Bean。
| Annotation名稱 |
說明 |
| @Component |
標註一個普通的Spring Bean類。 |
| @Controller |
標註一個控制器組件類。 |
| @Service |
標註一個商務邏輯組件類。 |
| @Repository |
標註一個DAO組件類。 |
如果我們需要定義一個普通的Spring Bean,則直接使用@Component標註即可。但如果用@Repository、@Service或@Controller來標註這些Bean類,這些Bean類將被作為特殊的JavaEE組件對待,也許能更好地被工具處理,或與切面進行關聯。
在Spring的未來版本中,@Controller、@Service和@Repository也許還能攜帶更多語義,因此如果需要在JavaEE應用中使用這些標註時,盡量考慮使用@Controller、@Service和@Repository來代替通用的@Component標註。
指定了某些類可作為Spring Bean類使用後,最後還需要讓Spring搜尋指定路徑,此時需要在Spring設定檔中匯入context Scheme,並指定一個簡單的搜尋路徑。
注意現在使用Annotation,工程除了spring.jar 和 commons-logging.jar,還需要添加一個common-annotations.jar,其路徑為spring開發包下的lib--->j2ee--->common-annotations.jar
Axe.java :
public interface Axe {public String chop();}
SteelAxe.java :
@Componentpublic class SteelAxe implements Axe {@Overridepublic String chop() {return "鋼斧砍柴真快";}}
StoneAxe.java :
@Componentpublic class StoneAxe implements Axe {@Overridepublic String chop() {return "石斧砍柴真慢";}}
Person.java :
public interface Person {public void useAxe();}
Chinese.java :
@Componentpublic class Chinese implements Person {private Axe axe;public void setAxe(Axe axe) {this.axe = axe;}@Overridepublic void useAxe() {System.out.println(axe.chop());}}
bean.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" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:component-scan base-package="com.bean"/> </beans>
Test.java :
public class Test {public static void main(String[] args) {ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");System.out.println(Arrays.toString(ctx.getBeanDefinitionNames()));}}
運行Test.java,控制台輸出:
[
steelAxe, stoneAxe, chinese,
org.springframework.context.annotation.internalCommonAnnotationProcessor,
org.springframework.context.annotation.internalAutowiredAnnotationProcessor,
org.springframework.context.annotation.internalRequiredAnnotationProcessor
]
每個使用了@Component標註的Java類都將作為Spring的Bean類。
從上面程式的運行結果來看,Spring容器中三個Bean執行個體的名稱分別為chinese、steelAxe和stoneAxe,之所以叫這些名稱,是因為在這種基於Annotation的方式下,Spring採用約定的方式來為這些Bean執行個體指定名稱,這些Bean執行個體的名稱預設是Bean類的首字母小寫,其他部分不變。
當然,Spring也允許在使用@Component標註時指定Bean執行個體的名稱:
@Component("axe")public class SteelAxe implements Axe{ //codes here}
上面程式中指定該Bean執行個體的名稱為axe。
在預設情況下,Spring會自動搜尋所有以@Component、@Controller、@Service和@Repository標註的Java類,並將它們當成Spring Bean來處理。
除此之外,我們還可通過為<component-scan.../>元素添加<include-filter.../>或<exclude-filter.../>子項目來指定Spring Bean類,只要位於指定路徑下的Java類滿足這種規則,即使這些java類沒有使用任何Annotation標註,Spring一樣會將它們當成Bean類來處理。
<include-filter.../>元素用於指定滿足該規則的Java類會被當成Bean類處理。<exclude-filter.../>元素用於指定滿足該規則的Java類不會被當成Bean類處理。使用這兩個元素時都要求指定如下兩個屬性:
① type:指定過濾器類型。
② expression:指定過濾器所需要的運算式。
Spring內建支援如下4種過濾器:
① annotation:Annotation過濾器,該過濾器需要指定一個Annotation名,如lee.AnnotationTest
② assignable:類名過濾器,該過濾器直接指定一個Java類。
③ regex:Regex過濾器,該過濾器指定一個Regex,匹配該Regex的Java類將滿足該過濾規則,如org\.example\.Default.*。
④ aspectj:AspectJ過濾器,如org.example..*Service+。
例如下面的設定檔指定所有以Chinese結尾的類,以Axe結尾的類都將被當成Spring Bean處理。
<context:component-scan base-package="org.crazyit.app.service"> <context:include-filter type="regex" expression=".*Chinese"/> <context:include-filter type="regex" expression=".*Axe"/> </context:component-scan>