<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 【第十二章】零配置 之 12.3 注解實現Bean定義 ——跟我學spring3 ## 12.3? 注解實現Bean定義 ### 12.3.1? 概述 前邊介紹的Bean定義全是基于XML方式定義配置元數據,且在【12.2注解實現Bean依賴注入】一節中介紹了通過注解來減少配置數量,但并沒有完全消除在XML配置文件中的Bean定義,因此有沒有方式完全消除XML配置Bean定義呢? Spring提供通過掃描類路徑中的特殊注解類來自動注冊Bean定義。同注解驅動事務一樣需要開啟自動掃描并注冊Bean定義支持,使用方式如下(resources/chapter12/ componentDefinitionWithAnnotation.xml): ``` <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <aop:aspectj-autoproxy /> <context:component-scan base-package="cn.javass.spring.chapter12"/> </beans> ``` 使用&lt;context:component-scan&gt;標簽來表示需要要自動注冊Bean定義,而通過base-package屬性指定掃描的類路徑位置。 &lt;context:component-scan&gt;標簽將自動開啟“**注解實現Bean依賴注入**”支持。 此處我們還通過&lt;aop:aspectj-autoproxy/&gt;用于開啟Spring對@AspectJ風格切面的支持。 Spring基于注解實現Bean定義支持如下三種注解: * **Spring自帶的@Component注解及擴展@Repository、@Service、@Controller**,如圖12-1所示; * **JSR-250 1.1版本中中定義的@ManagedBean注解**,是Java EE 6標準規范之一,不包括在JDK中,需要在應用服務器環境使用(如Jboss),如圖12-2所示; * **JSR-330的@Named注解**,如圖12-3所示。 ![](https://box.kancloud.cn/2016-02-22_56caf9fb566e4.jpg) 圖12-1 Spring自帶的@Component注解及擴展 ![](https://box.kancloud.cn/2016-05-13_5735472466929.JPG) 圖12-2 JSR-250中定義的@ManagedBean注解及自定義擴展 ![](https://box.kancloud.cn/2016-05-13_573547247aaa3.JPG) 圖12-3 JSR-330的@Named注解及自定義擴展 圖12-2和圖12-3中的自定義擴展部分是為了配合Spring自帶的模式注解擴展自定義的,并不包含在Java EE 6規范中,在Java EE 6中相應的服務層、DAO層功能由EJB來完成。 在Java EE中有些注解運行放置在多個地方,如@Named允許放置在類型、字段、方法參數上等,因此一般情況下放置在類型上表示定義,放置在參數、方法等上邊一般代表使用(如依賴注入等等)。 ### 12.3.2? Spring自帶的@Component注解及擴展 **一、@Component:定義Spring管理Bean,**使用方式如下: ``` @Component("標識符") POJO類 ``` 在類上使用@Component注解,表示該類定義為Spring管理Bean,使用默認value(可選)屬性表示Bean標識符。 1、定義測試Bean類: ``` package cn.javass.spring.chapter12; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; @Component("component") public class TestCompoment { @Autowired private ApplicationContext ctx; public ApplicationContext getCtx() { return ctx; } } ``` 2、Spring配置文件使用chapter12/ componentDefinitionWithAnnotation.xml即可且無需修改; 3、定義測試類和測試方法: ``` package cn.javass.spring.chapter12; //省略import public class ComponentDefinitionWithAnnotationTest { private static String configLocation = "classpath:chapter12/componentDefinitionWithAnnotation.xml"; private static ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocation); @Test public void testComponent() { TestCompoment component = ctx.getBean("component", TestCompoment.class); Assert.assertNotNull(component.getCtx()); } } ``` 測試成功說明被@Component注解的POJO類將自動被Spring識別并注冊到Spring容器中,且自動支持自動裝配。 **@AspectJ風格的切面可以通過@Compenent注解標識其為Spring管理Bean,而@Aspect注解不能被Spring自動識別并注冊為Bean,必須通過@Component注解來完成,示例如下:** ``` package cn.javass.spring.chapter12.aop; //省略import @Component @Aspect public class TestAspect { @Pointcut(value="execution(* *(..))") private void pointcut() {} @Before(value="pointcut()") public void before() { System.out.println("=======before"); } } ``` **通過@Component將切面定義為Spring管理Bean。** **二、@Repository:@Component擴展,被@Repository注解的POJO類表示DAO層實現,從而見到該注解就想到DAO層實現,使用方式和@Component相同;** 1、定義測試Bean類: ``` package cn.javass.spring.chapter12.dao.hibernate; import org.springframework.stereotype.Repository; @Repository("testHibernateDao") public class TestHibernateDaoImpl { } ``` 2、Spring配置文件使用chapter12/ componentDefinitionWithAnnotation.xml即可且無需修改; 3、定義測試方法: ``` @Test public void testDao() { TestHibernateDaoImpl dao = ctx.getBean("testHibernateDao", TestHibernateDaoImpl.class); Assert.assertNotNull(dao); } ``` 測試成功說明被@Repository注解的POJO類將自動被Spring識別并注冊到Spring容器中,且自動支持自動裝配,并且被@Repository注解的類表示DAO層實現。 **三、@Service:@Component擴展,被@Service注解的POJO類表示Service層實現,從而見到該注解就想到Service層實現,使用方式和@Component相同;** 1、定義測試Bean類: ``` package cn.javass.spring.chapter12.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import cn.javass.spring.chapter12.dao.hibernate.TestHibernateDaoImpl; @Service("testService") public class TestServiceImpl { @Autowired @Qualifier("testHibernateDao") private TestHibernateDaoImpl dao; public TestHibernateDaoImpl getDao() { return dao; } } ``` 2、Spring配置文件使用chapter12/ componentDefinitionWithAnnotation.xml即可且無需修改; 3、定義測試方法: ``` @Test public void testService() { TestServiceImpl service = ctx.getBean("testService", TestServiceImpl.class); Assert.assertNotNull(service.getDao()); } ``` 測試成功說明被@Service注解的POJO類將自動被Spring識別并注冊到Spring容器中,且自動支持自動裝配,并且被@Service注解的類表示Service層實現。 **四、@Controller:@Component擴展,被@Controller注解的類表示Web層實現,從而見到該注解就想到Web層實現,使用方式和@Component相同;** 1、定義測試Bean類: ``` package cn.javass.spring.chapter12.action; //省略import @Controller public class TestAction { @Autowired private TestServiceImpl testService; public void list() { //調用業務邏輯層方法 } } ``` 2、Spring配置文件使用chapter12/ componentDefinitionWithAnnotation.xml即可且無需修改; 3、定義測試方法: ``` @Test public void testWeb() { TestAction action = ctx.getBean("testAction", TestAction.class); Assert.assertNotNull(action); } ``` 測試成功說明被@Controller注解的類將自動被Spring識別并注冊到Spring容器中,且自動支持自動裝配,并且被@Controller注解的類表示Web層實現。 大家是否注意到@Controller中并沒有定義Bean的標識符,那么默認Bean的名字將是以小寫開頭的類名(不包括包名),即如“TestAction”類的Bean標識符為“testAction”。 **六、自定義擴展:Spring內置了三種通用的擴展注解@Repository、@Service、@Controller?,大多數情況下沒必要定義自己的擴展,在此我們演示下如何擴展@Component注解來滿足某些特殊規約的需要;** 在此我們可能需要一個緩存層用于定義緩存Bean,因此我們需要自定義一個@Cache的注解來表示緩存類。 1、擴展@Component: ``` package cn.javass.spring.chapter12.stereotype; //省略import @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Cache{ String value() default ""; } ``` 擴展十分簡單,只需要在擴展的注解上注解@Component即可,**@Repository、**@Service、@Controller也是通過該方式實現的,沒什么特別之處 2、定義測試Bean類: ``` package cn.javass.spring.chapter12.cache; @Cache("cache") public class TestCache { } ``` 2、Spring配置文件使用chapter12/ componentDefinitionWithAnnotation.xml即可且無需修改; 3、定義測試方法: ``` @Test public void testCache() { TestCache cache = ctx.getBean("cache", TestCache.class); Assert.assertNotNull(cache); } ``` 測試成功說明自定義的@Cache注解也能很好的工作,而且實現了我們的目的,使用@Cache來表示被注解的類是Cache層Bean。 ### 12.3.3? JSR-250中定義的@ManagedBean注解 @javax.annotation.ManagedBean需要在實現Java EE 6規范的應用服務器上使用,雖然Spring3實現了,但@javax.annotation.ManagedBean只有在Java EE 6環境中才有定義,因此測試前需要我們定義ManagedBean類。 1、定義javax.annotation.ManagedBean注解類: ``` package javax.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ManagedBean { String value() default ""; } ``` 其和@Component完全相同,唯一不同的就是名字和創建者(一個是Spring,一個是Java EE規范)。 2、定義測試Bean類: ``` package cn.javass.spring.chapter12; import javax.annotation.Resource; import org.springframework.context.ApplicationContext; @javax.annotation.ManagedBean("managedBean") public class TestManagedBean { @Resource private ApplicationContext ctx; public ApplicationContext getCtx() { return ctx; } } ``` 2、Spring配置文件使用chapter12/ componentDefinitionWithAnnotation.xml即可且無需修改; 3、定義測試方法: ``` @Test public void testManagedBean() { TestManagedBean testManagedBean = ctx.getBean("managedBean", TestManagedBean.class); Assert.assertNotNull(testManagedBean.getCtx()); } ``` 測試成功說明被@ManagedBean注解類也能正常工作。 自定義擴展就不介紹了,大家可以參考@Component來完成如圖12-2所示的自定義擴展部分。 ### 12.3.4? JSR-330的@Named注解 @Named不僅可以用于依賴注入來指定注入的Bean的標識符,還可以用于定義Bean。即注解在類型上表示定義Bean,注解在非類型上(如字段)表示指定依賴注入的Bean標識符。 1、定義測試Bean類: ``` package cn.javass.spring.chapter12; //省略import @Named("namedBean") public class TestNamedBean { @Inject private ApplicationContext ctx; public ApplicationContext getCtx() { return ctx; } } ``` 2、Spring配置文件使用chapter12/ componentDefinitionWithAnnotation.xml即可且無需修改; 3、定義測試方法: ``` @Test public void testNamedBean() { TestNamedBean testNamedBean = ctx.getBean("namedBean", TestNamedBean.class); Assert.assertNotNull(testNamedBean.getCtx()); } ``` 測試成功說明被@Named注解類也能正常工作。 自定義擴展就不介紹了,大家可以參考@Component來完成如圖12-3所示的自定義擴展部分。 ### 12.3.5? 細粒度控制Bean定義掃描 在XML配置中完全消除了Bean定義,而是只有一個&lt;context:component-scan&gt;標簽來支持注解Bean定義掃描。 前邊的示例完全采用默認掃描設置,如果我們有幾個組件不想被掃描并自動注冊、我們想更改默認的Bean標識符生成策略該如何做呢?接下來讓我們看一下如何細粒度的控制Bean定義掃描,具體定義如下: ``` <context:component-scan base-package="" resource-pattern="**/*.class" name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator" use-default-filters="true" annotation-config="true"> <context:include-filter type="aspectj" expression=""/> <context:exclude-filter type="regex" expression=""/> </context:component-scan> ``` * **base-package:**表示掃描注解類的開始位置,即將在指定的包中掃描,其他包中的注解類將不被掃描,默認將掃描所有類路徑; * **resource-pattern:**表示掃描注解類的后綴匹配模式,即“base-package+resource-pattern”將組成匹配模式用于匹配類路徑中的組件,默認后綴為“**/*.class”,即指定包下的所有以.class結尾的類文件; * **name-generator:默認情況下的Bean標識符生成策略,默認是**AnnotationBeanNameGenerator,其將生成以小寫開頭的類名(不包括包名);可以自定義自己的標識符生成策略; * **use-default-filters:**默認為true表示過濾@Component、@ManagedBean、@Named注解的類,如果改為false默認將不過濾這些默認的注解來定義Bean,即這些注解類不能被過濾到,即不能通過這些注解進行Bean定義; * **annotation-config:**表示是否自動支持注解實現Bean依賴注入,默認支持,如果設置為false,將關閉支持注解的依賴注入,需要通過&lt;context:annotation-config/&gt;開啟。 默認情況下將自動過濾@Component、@ManagedBean、@Named注解的類并將其注冊為Spring管理Bean,可以通過在&lt;context:component-scan&gt;標簽中指定自定義過濾器將過濾到匹配條件的類注冊為Spring管理Bean,具體定義方式如下: ``` <context:include-filter type="aspectj" expression=""/> <context:exclude-filter type="regex" expression=""/> ``` * **&lt;context:include-filter&gt;:**表示過濾到的類將被注冊為Spring管理Bean; * **&lt;context:exclude-filter&gt;:**表示過濾到的類將不被注冊為Spring管理Bean,它比&lt;context:include-filter&gt;具有更高優先級; * **type:**表示過濾器類型,目前支持注解類型、類類型、正則表達式、aspectj表達式過濾器,當然也可以自定義自己的過濾器,實現org.springframework.core.type.filter.TypeFilter即可; * **expression:**表示過濾器表達式。 一般情況下沒必要進行自定義過濾,如果需要請參考如下示例: 1、cn.javass.spring.chapter12.TestBean14自動注冊為Spring管理Bean: ``` <context:include-filter type="assignable" expression="cn.javass.spring.chapter12.TestBean14"/> ``` 2、把所有注解為org.aspectj.lang.annotation.Aspect自動注冊為Spring管理Bean: ``` <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> ``` 3、將把匹配到正則表達式“cn\.javass\.spring\.chapter12\.TestBean2*”排除,不注冊為Spring管理Bean: ``` <context:exclude-filter type="regex" expression="cn\.javass\.spring\.chapter12\.TestBean2*"/> ``` 4、將把匹配到aspectj表達式“cn.javass.spring.chapter12.TestBean3*”排除,不注冊為Spring管理Bean: ``` <context:exclude-filter type="aspectj" expression="cn.javass.spring.chapter12.TestBean3*"/> ``` 具體使用就要看項目需要了,如果以上都不滿足需要請考慮使用自定義過濾器。 ### 12.3.6? 提供更多的配置元數據 **1、@Lazy:**定義Bean將延遲初始化,使用方式如下: ``` @Component("component") @Lazy(true) public class TestCompoment { …… } ``` 使用@Lazy注解指定Bean需要延遲初始化。 2、**@DependsOn:**定義Bean初始化及銷毀時的順序,使用方式如下: ``` @Component("component") @DependsOn({"managedBean"}) public class TestCompoment { …… } ``` **3、@Scope**:定義Bean作用域,默認單例,使用方式如下: ``` @Component("component") @Scope("singleton") public class TestCompoment { …… } ``` **4、@Qualifier:**指定限定描述符,對應于基于XML配置中的&lt;qualifier&gt;標簽,使用方式如下: ``` @Component("component") @Qualifier("component") public class TestCompoment { …… } ``` 可以使用復雜的擴展,如@Mysql等等。 **5、@Primary:**自動裝配時當出現多個Bean候選者時,被注解為@Primary的Bean將作為首選者,否則將拋出異常,使用方式如下: ``` @Component("component") @Primary public class TestCompoment { …… } ``` 原創內容,轉載請注明私塾在線【http://sishuok.com/forum/blogPost/list/2547.html】
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看