西沙璞玉
          愛不容易
          posts - 0,comments - 4,trackbacks - 0

          注釋語法越來越多的被業界所使用,并且注釋配置相對于 XML 配置具有很多的優勢:它可以充分利用 Java 的反射機制獲取類結構信息,這些信息可以有效減少配置的工作。注釋和 Java 代碼位于一個文件中,而 XML 配置采用獨立的配置文件,大多數配置信息在程序開發完成后都不會調整,如果配置信息和 Java 代碼放在一起,有助于增強程序的內聚性。而采用獨立的 XML 配置文件,程序員在編寫一個功能時,往往需要在程序文件和配置文件中不停切換,這種思維上的不連貫會降低開發效率。因此在很多情況下,注釋配置比 XML 配置更受歡迎,注釋配置有進一步流行的趨勢。Spring 2.5 的一大增強就是引入了很多注釋類,現在您已經可以使用注釋配置完成大部分 XML 配置的功能。

           

          首先,我們已經通過 傳統的spring +hibernate方式構架成功了一個應用的后臺體系。

          這個體系里面 有這樣幾個重要的配置文件。

          1. hibernate.cfg.xml
            里面通過 配置 mapping來指向每張數據表單生成配置文件.xxxx.hbm.xml文件
          2. applicaitonContex.xml
            里面通過定義一個一個bean 來配置 各個需要用到的 DAO 和 Service。
            1. <?xml version="1.0" encoding="UTF-8"?>
            2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
            3. <beans >
            4.     <bean id="sessionFactory"
            5.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            6.         <property name="configLocation"
            7.             value="classpath:hibernate.cfg.xml">
            8.         </property>
            9.     </bean>
            10.     
            11.     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            12.         <property name="sessionFactory"> 
            13.             <ref local="sessionFactory"/>
            14.         </property> 
            15.     </bean>
            16.  
            17.     <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
            18.         <!--  事務攔截器bean需要依賴注入一個事務管理器 -->
            19.         <property name="transactionManager">
            20.             <ref local="transactionManager"/>
            21.         </property>
            22.         <property name="transactionAttributes">
            23.             <!--  下面定義事務傳播屬性-->
            24.             <props>
            25.                 <prop key="insert*">PROPAGATION_REQUIRED</prop>
            26.                 <prop key="update*">PROPAGATION_REQUIRED</prop>
            27.                 <prop key="save*">PROPAGATION_REQUIRED</prop>
            28.                 <prop key="add*">PROPAGATION_REQUIRED</prop>
            29.                 <prop key="update*">PROPAGATION_REQUIRED</prop>
            30.                 <prop key="remove*">PROPAGATION_REQUIRED</prop>
            31.                 <prop key="delete*">PROPAGATION_REQUIRED</prop>
            32.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            33.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
            34.                 <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
            35.                 <prop key="change*">PROPAGATION_REQUIRED</prop>
            36.                 <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            37.             </props>
            38.         </property>
            39.     </bean>
            40.     
            41.     
            42. <!-- 定義自動代理BeanNameAutoProxyCreator -->
            43. <bean id="beanNameAutoProxyCreator"
            44. class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            45. <!--  指定對滿足哪些bean name的bean自動生成業務代理 -->
            46. <property name="beanNames">
            47.       <list>
            48.         <value>*Service</value>
            49.       </list>
            50.        </property>
            51. <!--  下面定義BeanNameAutoProxyCreator所需的事務攔截器-->
            52. <property name="interceptorNames">
            53. <list>
            54. <!-- 此處可增加其他新的Interceptor -->
            55. <value>transactionInterceptor</value>
            56. </list>
            57. </property>
            58.         </bean>            
            59.     <bean id="McCityInfoDAO"
            60.         class="com.firemax.manatee.hibernate.McCityInfoDAO">
            61.         <property name="sessionFactory">
            62.             <ref bean="sessionFactory" />
            63.         </property>
            64.     </bean>
            65.     <bean id="McMaterialInfoDAO"
            66.         class="com.firemax.manatee.hibernate.McMaterialInfoDAO">
            67.         <property name="sessionFactory">
            68.             <ref bean="sessionFactory" />
            69.         </property>
            70.     </bean>
            71. </beans>
            72.  
            73.  

          hibernate.cfg.xml要配置這么多 xxxxx.hbm.xml文件。每次數據結構發生變化的時候。要重新去改寫pojo和dao以及這些xxxxx.hbm.xml
          那么好。我們現在就用 注解的力量 去把這部分工作簡化。

          • 首先我們需要 
          1. hibernate3.2 以上版本的jar
          2. jdk 5 以上的環境
          3. spring2 
          • 然后我們修改pojo的java類。加上注解。使起通過注解來取代原先要xxxx.hbm.xml里面配置的指向的數據庫表單結構的信息。
          1. package com.alcor.web.hibernate;
          2.  
          3. import java.util.HashSet;
          4. import java.util.Set;
          5. import javax.persistence.CascadeType;
          6. import javax.persistence.Column;
          7. import javax.persistence.Entity;
          8. import javax.persistence.FetchType;
          9. import javax.persistence.Id;
          10. import javax.persistence.JoinColumn;
          11. import javax.persistence.ManyToOne;
          12. import javax.persistence.OneToMany;
          13. import javax.persistence.Table;
          14.  
          15. /**
          16.  * AlcorTCitys entity. @author MyEclipse Persistence Tools
          17.  */
          18. @Entity
          19. @Table(name = "alcor_t_citys", catalog = "alcorweb")
          20. public class AlcorTCitys implements java.io.Serializable {
          21.  
          22.     // Fields
          23.  
          24.     private String cityCode;
          25.     private AlcorTProvinces alcorTProvinces;
          26.     private String cityName;
          27.     private Set<AlcotTDistrict> alcotTDistricts = new HashSet<AlcotTDistrict>(0);
          28.  
          29.     // Constructors
          30.  
          31.     /** default constructor */
          32.     public AlcorTCitys() {
          33.     }
          34.  
          35.     /** minimal constructor */
          36.     public AlcorTCitys(String cityCode, AlcorTProvinces alcorTProvinces,
          37.             String cityName) {
          38.         this.cityCode = cityCode;
          39.         this.alcorTProvinces = alcorTProvinces;
          40.         this.cityName = cityName;
          41.     }
          42.  
          43.     /** full constructor */
          44.     public AlcorTCitys(String cityCode, AlcorTProvinces alcorTProvinces,
          45.             String cityName, Set<AlcotTDistrict> alcotTDistricts) {
          46.         this.cityCode = cityCode;
          47.         this.alcorTProvinces = alcorTProvinces;
          48.         this.cityName = cityName;
          49.         this.alcotTDistricts = alcotTDistricts;
          50.     }
          51.  
          52.     // Property accessors
          53.     @Id
          54.     @Column(name = "city_code", unique = true, nullable = false, length = 32)
          55.     public String getCityCode() {
          56.         return this.cityCode;
          57.     }
          58.  
          59.     public void setCityCode(String cityCode) {
          60.         this.cityCode = cityCode;
          61.     }
          62.  
          63.     @ManyToOne(fetch = FetchType.EAGER)
          64.     @JoinColumn(name = "province_code", nullable = false)
          65.     public AlcorTProvinces getAlcorTProvinces() {
          66.         return this.alcorTProvinces;
          67.     }
          68.  
          69.     public void setAlcorTProvinces(AlcorTProvinces alcorTProvinces) {
          70.         this.alcorTProvinces = alcorTProvinces;
          71.     }
          72.  
          73.     @Column(name = "city_name", nullable = false, length = 64)
          74.     public String getCityName() {
          75.         return this.cityName;
          76.     }
          77.  
          78.     public void setCityName(String cityName) {
          79.         this.cityName = cityName;
          80.     }
          81.  
          82.     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "alcorTCitys")
          83.     public Set<AlcotTDistrict> getAlcotTDistricts() {
          84.         return this.alcotTDistricts;
          85.     }
          86.  
          87.     public void setAlcotTDistricts(Set<AlcotTDistrict> alcotTDistricts) {
          88.         this.alcotTDistricts = alcotTDistricts;
          89.     }
          90.  
          91. }

           

          • 修改hibernate.cfg.xml中的定義方式,把原來的maping source=“xxxxx.hbm.xml”修改成

          <mapping class="com.alcor.web.hibernate.AlcorTCitys" />

          這樣我們就可以把原來的 xxxxx.hbm.xml全部刪除了。

          經過這個步驟。如果你原有的servcice層的功能能夠正常使用。恭喜你。邁出了成功的第一步

          ===============================================================================================

          通過上面一步驟。我們簡化了hibernate中擾人的 xxxxx.hbm.xml文件。那么是否可以再進行簡化呢?

          那么,我們在這一步驟的目的,就是把整個 hibernate.cfg.xml都給簡化了。

           

          依然是利用注解注入的方式。通過jpa 我們可以把 hibernate.cfg.xml中那些 mapping classes再次簡化與無形。

           

          1. 在applicationContext.xml中進行如下配置
            1. <?xml version="1.0" encoding="UTF-8"?>
            2. <beans xmlns="http://www.springframework.org/schema/beans"
            3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
            5.     xmlns:tx="http://www.springframework.org/schema/tx">
            6.  
            7.  
            8.     <bean id="entityManagerFactory"
            9.         class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
            10.         <property name="persistenceUnitName" value="testerPU" />
            11.     </bean>
            12.     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            13.         <property name="entityManagerFactory" ref="entityManagerFactory" />
            14.     </bean>
            15.  
            16.     <tx:annotation-driven transaction-manager="transactionManager" />
            17.  
            18.     <bean id="transactionInterceptor"
            19.         class="org.springframework.transaction.interceptor.TransactionInterceptor">
            20.         <!-- 事務攔截器bean需要依賴注入一個事務管理器 -->
            21.         <property name="transactionManager">
            22.             <ref local="transactionManager" />
            23.         </property>
            24.         <property name="transactionAttributes">
            25.             <!-- 下面定義事務(指service里面的方法)傳播屬性 -->
            26.             <props>
            27.                 <prop key="insert*">PROPAGATION_REQUIRED</prop>
            28.                 <prop key="update*">PROPAGATION_REQUIRED</prop>
            29.                 <prop key="save*">PROPAGATION_REQUIRED</prop>
            30.                 <prop key="add*">PROPAGATION_REQUIRED</prop>
            31.                 <prop key="update*">PROPAGATION_REQUIRED</prop>
            32.                 <prop key="remove*">PROPAGATION_REQUIRED</prop>
            33.                 <prop key="delete*">PROPAGATION_REQUIRED</prop>
            34.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly
            35.                 </prop>
            36.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly
            37.                 </prop>
            38.                 <prop key="load*">PROPAGATION_REQUIRED,readOnly
            39.                 </prop>
            40.                 <prop key="change*">PROPAGATION_REQUIRED</prop>
            41.                 <prop key="count*">PROPAGATION_REQUIRED</prop>
            42.                 <prop key="*">PROPAGATION_REQUIRED</prop>
            43.             </props>
            44.         </property>
            45.     </bean>
            46.     <!-- 定義自動代理BeanNameAutoProxyCreator -->
            47.     <bean id="beanNameAutoProxyCreator"
            48.         class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            49.         <!-- 指定對滿足哪些bean name的bean自動生成業務代理 -->
            50.         <property name="beanNames">
            51.             <list>
            52.                 <value>*Service</value>
            53.             </list>
            54.         </property>
            55.         <!-- 下面定義BeanNameAutoProxyCreator所需的事務攔截器  -->
            56.         <property name="interceptorNames">
            57.             <list>
            58.                 <!-- 此處可增加其他新的Interceptor -->
            59.                 <value>transactionInterceptor</value>
            60.             </list>
            61.         </property>
            62.     </bean>
            63.  
            64.  
            65.  
            66.  
            67.  
            68.     <bean id="AlcorTCountriesDAO" class="com.firemax.test.hibernate.AlcorTCountriesDAO">
            69.         <property name="entityManagerFactory" ref="entityManagerFactory" />
            70.     </bean>
            71.     <bean id="AlcorTProvincesDAO" class="com.firemax.test.hibernate.AlcorTProvincesDAO">
            72.         <property name="entityManagerFactory" ref="entityManagerFactory" />
            73.     </bean>
            74.     <bean id="AlcotTDistrictDAO" class="com.firemax.test.hibernate.AlcotTDistrictDAO">
            75.         <property name="entityManagerFactory" ref="entityManagerFactory" />
            76.     </bean>
            77.     <bean id="AlcorTCitysDAO" class="com.firemax.test.hibernate.AlcorTCitysDAO">
            78.         <property name="entityManagerFactory" ref="entityManagerFactory" />
            79.     </bean>
            80.  
            81.     <bean id="CountryService" class="com.firemax.test.service.CountryService">
            82.         <property name="alcorTCountriesDAO" ref="AlcorTCountriesDAO" />
            83.         <property name="alcorTProvincesDAO" ref="AlcorTProvincesDAO" />
            84.         <property name="alcorTCitysDAO" ref="AlcorTCitysDAO" />
            85.         <property name="alcotTDistrictDAO" ref="AlcotTDistrictDAO" />
            86.     </bean>
            87.  
            88. </beans>

           

           

          注意紅色部分。這部分和(一)里面提到的那個applicationContext.xml中使用的bean是不同的。這里面已經用到了spring 的jpa部分。

          其中 <property name="persistenceUnitName" value="testerPU" />  是指向了一個 jpa的PU(Persistent Units)

           

          那么這個 是在哪里定義的呢?

          這里的定義是在你的 classes(src)目錄下META-INF下的persistence.xml文件中來定義

          persistence.xml文件內容如下:

           

            1. <?xml version="1.0" encoding="UTF-8"?>
            2. <persistence xmlns="http://java.sun.com/xml/ns/persistence"
            3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            4.     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
            5.     http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
            6.     version="1.0">
            7.  
            8.     <persistence-unit name="testerPU"
            9.         transaction-type="RESOURCE_LOCAL">
            10.         <provider>org.hibernate.ejb.HibernatePersistence</provider>
            11.         <class>com.firemax.test.hibernate.AlcorTCountries</class>
            12.         <class>com.firemax.test.hibernate.AlcorTProvinces</class>
            13.         <class>com.firemax.test.hibernate.AlcotTDistrict</class>
            14.         <class>com.firemax.test.hibernate.AlcorTCitys</class>
            15.         <properties>
            16.             <property name="hibernate.connection.driver_class"
            17.                 value="com.mysql.jdbc.Driver" />
            18.             <property name="hibernate.connection.url"
            19.                 value="jdbc:mysql://localhost:3306/alcorweb?useUnicode=true&characterEncoding=utf-8" />
            20.             <property name="hibernate.connection.username"
            21.                 value="alcorweb" />
            22.             <property name="hibernate.connection.password"
            23.                 value="alcorweb" />
            24.             <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
            25.             <property name="hibernate.c3p0.max_size" value="100"/>
            26.             <property name="hibernate.c3p0.min_size"  value="20"/>
            27.             <property name="hibernate.c3p0.timeout"   value="120"/>
            28.             <property name="hibernate.c3p0.max_statements" value="0"/>
            29.             <property name="hibernate.c3p0.idle_test_period"  value="120"/>
            30.             <property name="hibernate.c3p0.acquire_increment" value="5  "/>
            31.  
            32.             <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
            33.             <property name="hibernate.cache.use_query_cache" value="false"/>
            34.             <property name="hibernate.show_sql" value="false"/>
            35.             <property name="hibernate.useUnicode" value="true"/>
            36.             <property name="hibernate.characterEncoding" value="utf8"/>
            37.         </properties>
            38.     </persistence-unit>
            39. </persistence>

           

          仔細觀察他的代碼,我們發現其實和hibernate.cfg.xml和相似。都有指向pojo的定義 和 database連接的定義。先別著急。我們這次的優化,就先完成這個目標。主要是引入的spring的jpa框架。

          后面將介紹更進一步的優化。來展示jpa 和 注釋注入的能力。

          1. ===========================================================================
          2. 通過 (一)(二)的介紹。我們已經做了初步的簡化程序。

          但是在我們編寫spring 框架的代碼時候。一直遵循是這樣一個規則:所有在spring中注入的bean 都建議定義成私有的域變量。并且要配套寫上 get 和 set方法。雖然 可以通過eclipse等工具來自動生成。但是還是會引起程序閱讀性上的不便。那么既然注解這么強大。是否可以也把他精簡掉呢?

           

          當然可以。這個標簽就是@Autowired 

           

          Spring 2.5 引入了 @Autowired 注釋,它可以對類成員變量、方法及構造函數進行標注,完成自動裝配的工作。

           

          要實現我們要精簡程序的目的。需要這樣來處理:

           

          o    在applicationContext.xml中加入:

          2. <!-- 該 BeanPostProcessor 將自動對標注 @Autowired 的 Bean 進行注入 -->   

          3.     <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

           

          o    修改在原來注入spirng容器中的bean的方法。在域變量上加上標簽@Autowired,并且去掉 相應的get 和set方法

          1. /*國家,省份,城市,城區信息維護服務

          2.  * Created on 2008-9-26

          3.  *

          4.  * 徐澤宇 roamer

          5.  */

          6. package com.firemax.test.service;

          7.  

          8. import java.util.ArrayList;

          9. import java.util.Iterator;

          10. import java.util.List;

          11.  

          12. import org.apache.commons.logging.Log;

          13. import org.apache.commons.logging.LogFactory;

          14. import org.dom4j.Document;

          15. import org.dom4j.DocumentHelper;

          16. import org.dom4j.Element;

          17. import org.springframework.beans.factory.annotation.Autowired;

          18.  

          19. import com.firemax.test.hibernate.AlcorTCitys;

          20. import com.firemax.test.hibernate.AlcorTCitysDAO;

          21. import com.firemax.test.hibernate.AlcorTCountries;

          22. import com.firemax.test.hibernate.AlcorTCountriesDAO;

          23. import com.firemax.test.hibernate.AlcorTProvinces;

          24. import com.firemax.test.hibernate.AlcorTProvincesDAO;

          25. import com.firemax.test.hibernate.AlcotTDistrict;

          26. import com.firemax.test.hibernate.AlcotTDistrictDAO;

          27.  

          28.  

          29. public class CountryService {

          30.     private static Log logger = LogFactory.getLog(CountryService.class);

          31.     @Autowired

          32.     private AlcorTCountriesDAO  alcorTCountriesDAO;

          33.     @Autowired

          34.     private AlcorTProvincesDAO  alcorTProvincesDAO;

          35.     @Autowired

          36.     private AlcorTCitysDAO          alcorTCitysDAO;

          37.     @Autowired

          38.     private AlcotTDistrictDAO       alcotTDistrictDAO;

          39.     

          40.     public CountryService(){

          41.         

          42.     }

          43.     

          44.     /**修改一個國家信息

          45.      * @param alcorTCountries

          46.      * @throws Exception

          47.      */

          48.     public void updateCountry(AlcorTCountries alcorTCountries ) throws Exception{

          49.         this.alcorTCountriesDAO.update(alcorTCountries);

          50.     }

          51.     

          52.     ....

          53.     //這里去掉了哪些DAO 變量的get 和set 方法。

          54.  

          55.  

          56.     

          57.  

          58. }

          59.  

          60.  

           

          o    在applicatonContext.xml中 把原來 引用的<porpery >標簽也去掉。

          1. <bean id="CountryService" class="com.firemax.test.service.CountryService">

          2.         <property name="alcorTCountriesDAO" ref="AlcorTCountriesDAO" />

          3.         <property name="alcorTProvincesDAO" ref="AlcorTProvincesDAO" />

          4.         <property name="alcorTCitysDAO" ref="AlcorTCitysDAO" />

          5.         <property name="alcotTDistrictDAO" ref="AlcotTDistrictDAO" />

          6.  </bean>

          修改成

          7. <bean id="CountryService" class="com.firemax.test.service.CountryService">

          8.         

          9. </bean>

          當然,我們也可以在構造函數上使用@Auwowired 注解 。如果構造函數有兩個入參,分別是 bean1 bean2@Autowired 將分別尋找和它們類型匹配的 Bean,將它們作為 CountryService (Bean1 bean1 ,Bean2 bean2) 的入參來創建 CountryService  Bean

          在運行一下你的業務程序。如果沒有錯誤。恭喜你。這個步驟我們又完成了。

                ======================================================================

                 在(三)里面。我們引入了 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>這個bean 來處理@Autowired注解。

          其實在spring 里面還有其他三個BeanPostProcessor 。總共有四個,分別是:

          AutowiredAnnotationBeanPostProcessor

          CommonAnnotationBeanPostProcessor

          PersistenceAnnotationBeanPostProcessor

          equiredAnnotationBeanPostProcessor 

           

          但是直接在 Spring 配置文件中定義這些 Bean 顯得比較笨拙。Spring 為我們提供了一種方便的注冊這些 BeanPostProcessor 的方式,這就是 <context:annotation-config/>

           

          Spring 2.1 添加了一個新的 context 的 Schema 命名空間,該命名空間對注釋驅動、屬性文件引入、加載期織入等功能提供了便捷的配置。我們知道注釋本身是不會做任何事情的,它僅提供元數據信息。要使元數據信息真正起作用,必須讓負責處理這些元數據的處理器工作起來。

           

          這段代碼就是 啟用了這個命名空間后的applicationContext.xml文件

          0. <?xml version="1.0" encoding="UTF-8"?>

          1. <beans xmlns="http://www.springframework.org/schema/beans"

          2.     xmlns:context="http://www.springframework.org/schema/context"

          3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          4.     xmlns:tx="http://www.springframework.org/schema/tx"

          5.     xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

          6.                                             http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-2.5.xsd

          7.                                             http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"

          8.     >

          9.  

          10.  

          11.     <bean id="entityManagerFactory"

          12.         class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">

          13.         <property name="persistenceUnitName" value="testerPU" />

          14.     </bean>

          15.     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

          16.         <property name="entityManagerFactory" ref="entityManagerFactory" />

          17.     </bean>

          18.  

          19.     <tx:annotation-driven transaction-manager="transactionManager" />

          20.  

          21.     <bean id="transactionInterceptor"

          22.         class="org.springframework.transaction.interceptor.TransactionInterceptor">

          23.         <!-- 事務攔截器bean需要依賴注入一個事務管理器 -->

          24.         <property name="transactionManager">

          25.             <ref local="transactionManager" />

          26.         </property>

          27.         <property name="transactionAttributes">

          28.             <!-- 下面定義事務(指service里面的方法)傳播屬性 -->

          29.             <props>

          30.                 <prop key="insert*">PROPAGATION_REQUIRED</prop>

          31.                 <prop key="update*">PROPAGATION_REQUIRED</prop>

          32.                 <prop key="save*">PROPAGATION_REQUIRED</prop>

          33.                 <prop key="add*">PROPAGATION_REQUIRED</prop>

          34.                 <prop key="update*">PROPAGATION_REQUIRED</prop>

          35.                 <prop key="remove*">PROPAGATION_REQUIRED</prop>

          36.                 <prop key="delete*">PROPAGATION_REQUIRED</prop>

          37.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly

          38.                 </prop>

          39.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly

          40.                 </prop>

          41.                 <prop key="load*">PROPAGATION_REQUIRED,readOnly

          42.                 </prop>

          43.                 <prop key="change*">PROPAGATION_REQUIRED</prop>

          44.                 <prop key="count*">PROPAGATION_REQUIRED</prop>

          45.                 <prop key="*">PROPAGATION_REQUIRED</prop>

          46.             </props>

          47.         </property>

          48.     </bean>

          49.     

          50.     <!-- 該 BeanPostProcessor 將自動對標注 @Autowired 的 Bean 進行注入 -->

          51.     <!--  這個Processor 已經被 <context:annotation-config/> 所簡化   

          52.     <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

          53.     -->

          54.     <context:annotation-config/>

          55.     

          56.     

          57.     <!-- 定義自動代理BeanNameAutoProxyCreator -->

          58.     <bean id="beanNameAutoProxyCreator"

          59.         class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

          60.         <!-- 指定對滿足哪些bean name的bean自動生成業務代理 -->

          61.         <property name="beanNames">

          62.             <list>

          63.                 <value>*Service</value>

          64.             </list>

          65.         </property>

          66.         <!-- 下面定義BeanNameAutoProxyCreator所需的事務攔截器  -->

          67.         <property name="interceptorNames">

          68.             <list>

          69.                 <!-- 此處可增加其他新的Interceptor -->

          70.                 <value>transactionInterceptor</value>

          71.             </list>

          72.         </property>

          73.     </bean>

          74.  

          75.  

          76.  

          77.  

          78.  

          79.     <bean id="AlcorTCountriesDAO" class="com.firemax.test.hibernate.AlcorTCountriesDAO">

          80.         <property name="entityManagerFactory" ref="entityManagerFactory" />

          81.     </bean>

          82.     <bean id="AlcorTProvincesDAO" class="com.firemax.test.hibernate.AlcorTProvincesDAO">

          83.         <property name="entityManagerFactory" ref="entityManagerFactory" />

          84.     </bean>

          85.     <bean id="AlcotTDistrictDAO" class="com.firemax.test.hibernate.AlcotTDistrictDAO">

          86.         <property name="entityManagerFactory" ref="entityManagerFactory" />

          87.     </bean>

          88.     <bean id="AlcorTCitysDAO" class="com.firemax.test.hibernate.AlcorTCitysDAO">

          89.         <property name="entityManagerFactory" ref="entityManagerFactory" />

          90.     </bean>

          91.  

          92.     <bean id="CountryService" class="com.firemax.test.service.CountryService"/>

          93.  

          94.  

          95. </beans>

           

          注意2段標紅的內容,就是這次更新的配置內容。在配置文件中使用 context 命名空間之前,必須在 <beans> 元素中聲明 context 命名空間。


          ===========================================================================================

                雖然我們可以通過 @Autowired 在 Bean 類中使用自動注入功能,但是 Bean 還是在 applicatonContext.xml 文件中通過 <bean> 進行定義 —— 在前面的例子中,我們還是在配置文件中定義 Bean,通過 @Autowired為 Bean 的成員變量、方法形參或構造函數形參提供自動注入的功能。

          那么能不是也可以通過注解定義 Bean,從 XML 配置文件中完全移除 Bean 定義的配置呢?

          答案是肯定的,我們通過 Spring 2.5 提供的 @Component 注釋就可以達到這個目標了。

          修改Bean的java類的代碼如下,在類名前面加上 @Component注解

          0. package com.firemax.test.service;

          1.  

          2. import java.util.ArrayList;

          3. import java.util.Iterator;

          4. import java.util.List;

          5.  

          6. import org.apache.commons.logging.Log;

          7. import org.apache.commons.logging.LogFactory;

          8. import org.dom4j.Document;

          9. import org.dom4j.DocumentHelper;

          10. import org.dom4j.Element;

          11. import org.springframework.beans.factory.annotation.Autowired;

          12. import org.springframework.stereotype.Component;

          13.  

          14.  

          15. import com.firemax.test.hibernate.AlcorTCitys;

          16. import com.firemax.test.hibernate.AlcorTCitysDAO;

          17. import com.firemax.test.hibernate.AlcorTCountries;

          18. import com.firemax.test.hibernate.AlcorTCountriesDAO;

          19. import com.firemax.test.hibernate.AlcorTProvinces;

          20. import com.firemax.test.hibernate.AlcorTProvincesDAO;

          21. import com.firemax.test.hibernate.AlcotTDistrict;

          22. import com.firemax.test.hibernate.AlcotTDistrictDAO;

          23.  

          24. @Component

          25. public class CountryService {

          26.     private static Log logger = LogFactory.getLog(CountryService.class);

          27.     @Autowired

          28.     private AlcorTCountriesDAO  alcorTCountriesDAO;

          29.     @Autowired

          30.     private AlcorTProvincesDAO  alcorTProvincesDAO;

          31.     @Autowired

          32.     private AlcorTCitysDAO          alcorTCitysDAO;

          33.     @Autowired

          34.     private AlcotTDistrictDAO       alcotTDistrictDAO;

          35.     

          36.     public CountryService(){

          37.         

          38.     }

          39.      //這里是業務邏輯的方法

          40.      。。。。。

          41. }

          然后,我們修改配置文件applicatonContext.xml中,啟用自動注入的功能,而放棄原來的<bean>方式的配置

          42. <?xml version="1.0" encoding="UTF-8"?>

          43. <beans xmlns="http://www.springframework.org/schema/beans"

          44.     xmlns:context="http://www.springframework.org/schema/context"

          45.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          46.     xmlns:tx="http://www.springframework.org/schema/tx"

          47.     xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

          48.                                             http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-2.5.xsd

          49.                                             http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"

          50.     default-autowire="autodetect">

          51.     <bean id="entityManagerFactory"

          52.         class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">

          53.         <property name="persistenceUnitName" value="testerPU" />

          54.     </bean>

          55.     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

          56.         <property name="entityManagerFactory" ref="entityManagerFactory" />

          57.     </bean>

          58.     <tx:annotation-driven transaction-manager="transactionManager" />

          59.     <bean id="transactionInterceptor"

          60.         class="org.springframework.transaction.interceptor.TransactionInterceptor">

          61.         <!-- 事務攔截器bean需要依賴注入一個事務管理器 -->

          62.         <property name="transactionManager">

          63.             <ref local="transactionManager" />

          64.         </property>

          65.         <property name="transactionAttributes">

          66.             <!-- 下面定義事務(指service里面的方法)傳播屬性 -->

          67.             <props>

          68.                 <prop key="insert*">PROPAGATION_REQUIRED</prop>

          69.                 <prop key="update*">PROPAGATION_REQUIRED</prop>

          70.                 <prop key="save*">PROPAGATION_REQUIRED</prop>

          71.                 <prop key="add*">PROPAGATION_REQUIRED</prop>

          72.                 <prop key="update*">PROPAGATION_REQUIRED</prop>

          73.                 <prop key="remove*">PROPAGATION_REQUIRED</prop>

          74.                 <prop key="delete*">PROPAGATION_REQUIRED</prop>

          75.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly

          76.                 </prop>

          77.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly

          78.                 </prop>

          79.                 <prop key="load*">PROPAGATION_REQUIRED,readOnly

          80.                 </prop>

          81.                 <prop key="change*">PROPAGATION_REQUIRED</prop>

          82.                 <prop key="count*">PROPAGATION_REQUIRED</prop>

          83.                 <prop key="*">PROPAGATION_REQUIRED</prop>

          84.             </props>

          85.         </property>

          86.     </bean>

          87.     

          88.     <!-- 該 BeanPostProcessor 將自動對標注 @Autowired 的 Bean 進行注入 -->

          89.     <!--  這個Processor 已經被 <context:annotation-config/> 所簡化   

          90.     <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

          91.     -->

          92.      <!-- <context:component-scan/> 配置項不但啟用了對類包進行掃描以實施注釋驅動 Bean 定義的功能,同時還啟用了注釋驅動自動注入的功能(即還隱式地在內部注冊了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor),因此當使用 <context:component-scan/> 后,就可以將 <context:annotation-config/> 移除了。 -->

          93.     <context:component-scan base-package ="com.firemax"/>  

          94.     

          95.     

          96.     <!-- 定義自動代理BeanNameAutoProxyCreator -->

          97.     <bean id="beanNameAutoProxyCreator"

          98.         class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

          99.         <!-- 指定對滿足哪些bean name的bean自動生成業務代理 -->

          100.           <property name="beanNames">

          101.               <list>

          102.                   <value>*Service</value>

          103.               </list>

          104.           </property>

          105.           <!-- 下面定義BeanNameAutoProxyCreator所需的事務攔截器  -->

          106.           <property name="interceptorNames">

          107.               <list>

          108.                   <!-- 此處可增加其他新的Interceptor -->

          109.                   <value>transactionInterceptor</value>

          110.               </list>

          111.           </property>

          112.       </bean>

          113.       <!-- 

          114.       <bean id="AlcorTCountriesDAO" class="com.firemax.test.hibernate.AlcorTCountriesDAO">

          115.           <property name="entityManagerFactory" ref="entityManagerFactory" />

          116.       </bean>

          117.       <bean id="AlcorTProvincesDAO" class="com.firemax.test.hibernate.AlcorTProvincesDAO">

          118.           <property name="entityManagerFactory" ref="entityManagerFactory" />

          119.       </bean>

          120.       <bean id="AlcotTDistrictDAO" class="com.firemax.test.hibernate.AlcotTDistrictDAO">

          121.           <property name="entityManagerFactory" ref="entityManagerFactory" />

          122.       </bean>

          123.       <bean id="AlcorTCitysDAO" class="com.firemax.test.hibernate.AlcorTCitysDAO">

          124.           <property name="entityManagerFactory" ref="entityManagerFactory" />

          125.       </bean>

          126.       

          127.        <bean id="CountryService" class="com.firemax.test.service.CountryService"/>

          128.       -->

          129.   </beans>

          新的applicaitonContext.xml 配置文件中藍色的部分就是原來的<bean>的注入方式,現在已經給屏蔽了。不需要再寫。而紅色部分就是使用了<context:component-scan base-package ="com.firemax"/> ,讓spirng自動搜索,然后注入。

           

          注意:

          o    這里注入的bean 的名稱是按照類的名稱,把第一個字母改成小寫來命名的。比如例子中的CountryService的bean的名稱就是countryService.

          o    我們也可以通過@Component("countryService") 這種方式來顯示的定義一個bean的注入名稱。但是在大多數情況下沒有必要。

           

          <context:component-scan/> base-package 屬性指定了需要掃描的類包,類包及其遞歸子包中所有的類都會被處理。

          <context:component-scan/> 還允許定義過濾器將基包下的某些類納入或排除。Spring 支持以下 4 種類型的過濾方式,通過下表說明:


           掃描過濾方式

          過濾器類型

          說明

          注釋

          假如 com.firemax.test.SomeAnnotation 是一個注釋類,我們可以將使用該注釋的類過濾出來。

          類名指定

          通過全限定類名進行過濾,如您可以指定將 com.firemax.test.IncludeService納入掃描,而將 com.firemax.test.NotIncludeService 排除在外。

          正則表達式

          通過正則表達式定義過濾的類,如下所示: com/.firemax/.test/.Default.*

          AspectJ 表達式

          通過 AspectJ 表達式定義過濾的類,如下所示: com. firemax.test..*Service+

          下面是一個簡單的例子:


          默認情況下通過 @Component 定義的 Bean 都是 singleton 的,如果需要使用其它作用范圍的 Bean,可以通過 @Scope 注釋來達到目標,如以下代碼所示:


           通過 @Scope 指定 Bean 的作用范圍


           

          這樣,當從 Spring 容器中獲取 boss Bean 時,每次返回的都是新的實例了。

           

          Spring2.5中引入了更多的典型化注解,@Repository @Service@Controler@Component的細化。分別表示持久層,服務層,控制層。建議使用這個注解來取代@Component

           

          附上一個java Applicaiton的簡單測試程序

          132.   /*

          133.    * Created on 2008-9-28

          134.    *

          135.    * 徐澤宇 roamer

          136.    */

          137.   package com.firemax.test.tester;

          138.    

          139.   import java.util.Iterator;

          140.    

          141.   import org.springframework.context.ApplicationContext;

          142.   import org.springframework.context.support.FileSystemXmlApplicationContext;

          143.    

          144.   import com.firemax.test.hibernate.AlcorTCitys;

          145.   import com.firemax.test.hibernate.AlcorTCitysDAO;

          146.   import com.firemax.test.hibernate.AlcorTCountries;

          147.   import com.firemax.test.hibernate.AlcorTProvinces;

          148.   import com.firemax.test.hibernate.AlcotTDistrict;

          149.   import com.firemax.test.hibernate.AlcotTDistrictDAO;

          150.   import com.firemax.test.service.CountryService;

          151.    

          152.    

          153.    

          154.   public class Tester {

          155.    

          156.       /**

          157.        * @param args

          158.        */

          159.       public static void main(String[] args) throws Exception{

          160.           // TODO Auto-generated method stub

          161.           ApplicationContext ctx =     new FileSystemXmlApplicationContext("/WebContent/WEB-INF/classes/applicationContext*.xml");

          162.           String[] beans = ctx.getBeanDefinitionNames();

          163.           for (int i = 0 ; i < beans.length;i++)

          164.           {

          165.               System.out.println(beans[i]);

          166.           }

          167.           CountryService countryService= (CountryService)ctx.getBean("countryService");

          168.         

          169.           AlcorTCountries  alcorTCountries= countryService.getCountriesInfo("CN");

          170.           System.out.println(alcorTCountries.getCountry());

          171.           System.out.println("開始調用子類");

          172.           System.out.println(alcorTCountries.getAlcorTProvinceses().size());

          173.           Iterator<AlcorTProvinces> it = alcorTCountries.getAlcorTProvinceses().iterator();

          174.           while (it.hasNext()){

          175.               AlcorTProvinces  alcorTProvinces= (AlcorTProvinces)it.next();

          176.               System.out.println(alcorTProvinces.getProvinceName());

          177.           }

          178.           AlcotTDistrict alcotTDistrict= new AlcotTDistrict();

          179.           alcotTDistrict.setDistrictCode("22");

          180.           alcotTDistrict.setDistrictName("浦東");

          181.           AlcorTCitys alcorTCitys =countryService.getCityInfo("021");

          182.           alcotTDistrict.setAlcorTCitys(alcorTCitys);

          183.           countryService.saveProvinces(alcotTDistrict);

          184.           

          185.       }

          186.   }

          187.    

          188.    

          在所有的JPOPO中,我們可以使用@Entity 這個注解來注入 JOPO。這樣我們在 Persistent.xml中就不需要在 定義哪些POJO的類了。

          感謝 JPA 感謝Spring ,終于不要頻繁的去定義和修改這些Bean

           

          posted on 2012-01-05 13:45 @趙 閱讀(1718) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          哥哥最近不是很忙
          主站蜘蛛池模板: 永登县| 河东区| 石林| 轮台县| 杭州市| 韶关市| 和田市| 梁平县| 石林| 洪洞县| 云梦县| 子长县| 东乌| 喀喇| 抚宁县| 九江县| 福建省| 巴南区| 那坡县| 兖州市| 石棉县| 阳谷县| 新密市| 阜宁县| 冀州市| 澄江县| 秭归县| 五寨县| 延长县| 牡丹江市| 乌拉特前旗| 奇台县| 霍邱县| 班玛县| 仙游县| 长垣县| 仪陇县| 肃北| 大安市| 长乐市| 柳江县|