• 注解的力量 Spring 2.5 JPA hibernate 使用方法的点滴整理(五):使用@Component 来简化bean的配置


    虽然我们可以通过 @Autowired 在 Bean 类中使用自动注入功能,但是 Bean 还是在 applicatonContext.xml 文件中通过 <bean> 进行定义 —— 在前面的例子中,我们还是在配置文件中定义 Bean,通过 @Autowired为 Bean 的成员变量、方法形参或构造函数形参提供自动注入的功能。

    那么能不是也可以通过注解定义 Bean,从 XML 配置文件中完全移除 Bean 定义的配置呢?
    答案是肯定的,我们通过 Spring 2.5 提供的 @Component 注释就可以达到这个目标了。
    修改Bean的java类的代码如下,在类名前面加上 @Component注解
    1. package com.firemax.test.service;
    2. import java.util.ArrayList;
    3. import java.util.Iterator;
    4. import java.util.List;
    5. import org.apache.commons.logging.Log;
    6. import org.apache.commons.logging.LogFactory;
    7. import org.dom4j.Document;
    8. import org.dom4j.DocumentHelper;
    9. import org.dom4j.Element;
    10. import org.springframework.beans.factory.annotation.Autowired;
    11. import org.springframework.stereotype.Component;
    12. import com.firemax.test.hibernate.AlcorTCitys;
    13. import com.firemax.test.hibernate.AlcorTCitysDAO;
    14. import com.firemax.test.hibernate.AlcorTCountries;
    15. import com.firemax.test.hibernate.AlcorTCountriesDAO;
    16. import com.firemax.test.hibernate.AlcorTProvinces;
    17. import com.firemax.test.hibernate.AlcorTProvincesDAO;
    18. import com.firemax.test.hibernate.AlcotTDistrict;
    19. import com.firemax.test.hibernate.AlcotTDistrictDAO;
    20. @Component
    21. public class CountryService {
    22.     private static Log logger = LogFactory.getLog(CountryService.class);
    23.     @Autowired
    24.     private AlcorTCountriesDAO  alcorTCountriesDAO;
    25.     @Autowired
    26.     private AlcorTProvincesDAO  alcorTProvincesDAO;
    27.     @Autowired
    28.     private AlcorTCitysDAO          alcorTCitysDAO;
    29.     @Autowired
    30.     private AlcotTDistrictDAO       alcotTDistrictDAO;
    31.     
    32.     public CountryService(){
    33.         
    34.     }
    35.      //这里是业务逻辑的方法
    36.      。。。。。
    37. }
    然后,我们修改配置文件applicatonContext.xml中,启用自动注入的功能,而放弃原来的<bean>方式的配置
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3.     xmlns:context="http://www.springframework.org/schema/context"
    4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    5.     xmlns:tx="http://www.springframework.org/schema/tx"
    6.     xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    7.                                             http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-2.5.xsd
    8.                                             http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
    9.     default-autowire="autodetect">
    10.     <bean id="entityManagerFactory"
    11.         class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    12.         <property name="persistenceUnitName" value="testerPU" />
    13.     </bean>
    14.     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    15.         <property name="entityManagerFactory" ref="entityManagerFactory" />
    16.     </bean>
    17.     <tx:annotation-driven transaction-manager="transactionManager" />
    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.     
    47.     <!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->
    48.     <!--  这个Processor 已经被 <context:annotation-config/> 所简化   
    49.     <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
    50.     -->
    51.      <!-- <context:component-scan/> 配置项不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor),因此当使用 <context:component-scan/> 后,就可以将 <context:annotation-config/> 移除了。 -->
    52.     <context:component-scan base-package ="com.firemax"/>  
    53.     
    54.     
    55.     <!-- 定义自动代理BeanNameAutoProxyCreator -->
    56.     <bean id="beanNameAutoProxyCreator"
    57.         class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    58.         <!-- 指定对满足哪些bean name的bean自动生成业务代理 -->
    59.         <property name="beanNames">
    60.             <list>
    61.                 <value>*Service</value>
    62.             </list>
    63.         </property>
    64.         <!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器  -->
    65.         <property name="interceptorNames">
    66.             <list>
    67.                 <!-- 此处可增加其他新的Interceptor -->
    68.                 <value>transactionInterceptor</value>
    69.             </list>
    70.         </property>
    71.     </bean>
    72.     <!-- 
    73.     <bean id="AlcorTCountriesDAO" class="com.firemax.test.hibernate.AlcorTCountriesDAO">
    74.         <property name="entityManagerFactory" ref="entityManagerFactory" />
    75.     </bean>
    76.     <bean id="AlcorTProvincesDAO" class="com.firemax.test.hibernate.AlcorTProvincesDAO">
    77.         <property name="entityManagerFactory" ref="entityManagerFactory" />
    78.     </bean>
    79.     <bean id="AlcotTDistrictDAO" class="com.firemax.test.hibernate.AlcotTDistrictDAO">
    80.         <property name="entityManagerFactory" ref="entityManagerFactory" />
    81.     </bean>
    82.     <bean id="AlcorTCitysDAO" class="com.firemax.test.hibernate.AlcorTCitysDAO">
    83.         <property name="entityManagerFactory" ref="entityManagerFactory" />
    84.     </bean>
    85.     
    86.      <bean id="CountryService" class="com.firemax.test.service.CountryService"/>
    87.     -->
    88. </beans>
    新的applicaitonContext.xml 配置文件中蓝色的部分就是原来的<bean>的注入方式,现在已经给屏蔽了。不需要再写。而红色部分就是使用了<context:component-scan base-package ="com.firemax"/> ,让spirng自动搜索,然后注入。
     
    注意:
    • 这里注入的bean 的名称是按照类的名称,把第一个字母改成小写来命名的。比如例子中的CountryService的bean的名称就是countryService.
    • 我们也可以通过@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+

    下面是一个简单的例子:

    1. <context:component-scan base-package="com.firemax">
    2.     <context:include-filter type="regex" 
    3.         expression="com/.firemax/.test/.service/..*"/>
    4.     <context:exclude-filter type="aspectj" 
    5.         expression="com.firemax.test.util..*"/>
    6. </context:component-scan>

    默认情况下通过 @Component 定义的 Bean 都是 singleton 的,如果需要使用其它作用范围的 Bean,可以通过 @Scope 注释来达到目标,如以下代码所示:


     通过 @Scope 指定 Bean 的作用范围
    1.                 
    2. package com.firemax.tester.service;
    3. import org.springframework.context.annotation.Scope;
    4. @Scope("prototype")
    5. @Component("countryService")
    6. public class CountryService{
    7.     …
    8. }

    这样,当从 Spring 容器中获取 boss Bean 时,每次返回的都是新的实例了。

    在Spring2.5中引入了更多的典型化注解,@Repository ,@Service,@Controler是@Component的细化。分别表示持久层,服务层,控制层。建议使用这个注解来取代@Component

    附上一个java Applicaiton的简单测试程序

    1. /*
    2.  * Created on 2008-9-28
    3.  *
    4.  * 徐泽宇 roamer
    5.  */
    6. package com.firemax.test.tester;
    7. import java.util.Iterator;
    8. import org.springframework.context.ApplicationContext;
    9. import org.springframework.context.support.FileSystemXmlApplicationContext;
    10. import com.firemax.test.hibernate.AlcorTCitys;
    11. import com.firemax.test.hibernate.AlcorTCitysDAO;
    12. import com.firemax.test.hibernate.AlcorTCountries;
    13. import com.firemax.test.hibernate.AlcorTProvinces;
    14. import com.firemax.test.hibernate.AlcotTDistrict;
    15. import com.firemax.test.hibernate.AlcotTDistrictDAO;
    16. import com.firemax.test.service.CountryService;
    17. public class Tester {
    18.     /**
    19.      * @param args
    20.      */
    21.     public static void main(String[] args) throws Exception{
    22.         // TODO Auto-generated method stub
    23.         ApplicationContext ctx =     new FileSystemXmlApplicationContext("/WebContent/WEB-INF/classes/applicationContext*.xml");
    24.         String[] beans = ctx.getBeanDefinitionNames();
    25.         for (int i = 0 ; i < beans.length;i++)
    26.         {
    27.             System.out.println(beans[i]);
    28.         }
    29.         CountryService countryService= (CountryService)ctx.getBean("countryService");
    30.       
    31.         AlcorTCountries  alcorTCountries= countryService.getCountriesInfo("CN");
    32.         System.out.println(alcorTCountries.getCountry());
    33.         System.out.println("开始调用子类");
    34.         System.out.println(alcorTCountries.getAlcorTProvinceses().size());
    35.         Iterator<AlcorTProvinces> it = alcorTCountries.getAlcorTProvinceses().iterator();
    36.         while (it.hasNext()){
    37.             AlcorTProvinces  alcorTProvinces= (AlcorTProvinces)it.next();
    38.             System.out.println(alcorTProvinces.getProvinceName());
    39.         }
    40.         AlcotTDistrict alcotTDistrict= new AlcotTDistrict();
    41.         alcotTDistrict.setDistrictCode("22");
    42.         alcotTDistrict.setDistrictName("浦东");
    43.         AlcorTCitys alcorTCitys =countryService.getCityInfo("021");
    44.         alcotTDistrict.setAlcorTCitys(alcorTCitys);
    45.         countryService.saveProvinces(alcotTDistrict);
    46.         
    47.     }
    48. }
    在所有的JPOPO中,我们可以使用@Entity 这个注解来注入 JOPO。这样我们在 Persistent.xml中就不需要在 定义哪些POJO的类了。

    感谢 JPA 感谢Spring ,终于不要频繁的去定义和修改这些Bean了

    原文网址:http://blog.csdn.net/remote_roamer/article/details/3008016

  • 相关阅读:
    LeetCode 867. 转置矩阵
    LeetCode 26. 删除排序数组中的重复项
    LeetCode 905. 按奇偶排序数组
    LeetCode 922. 按奇偶排序数组 II
    CentOS 7.4 系统安装 git
    浅谈final修饰的变量
    【笔试题】京东2017秋招笔试真题
    【笔试题】在 Java 中,如何跳出当前的多重嵌套循环?
    【面试题】反转单链表
    Windows 系统采用批处理命令修改 ip 地址
  • 原文地址:https://www.cnblogs.com/winkey4986/p/2355023.html
Copyright © 2020-2023  润新知