西沙璞玉
爱不容易
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 @赵 阅读(1712) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
 
哥哥最近不是很忙