zoukankan      html  css  js  c++  java
  • [注解的力量]Spring 2.5 JPA hibernate 使用方法的点滴整理(五):使用@Component 来简化bean的配置

    出处:http://blog.csdn.net/remote_roamer/archive/2008/10/01/3008016.aspx


    虽然我们可以通过 @Autowired 在 Bean 类中使用自动注入功能,但是 Bean 还是在 applicatonContext.xml 文件中通过 <bean> 进行定义 —— 在前面的例子中,我们还是在配置文件中定义 Bean,通过 @Autowired为 Bean 的成员变量、方法形参或构造函数形参提供自动注入的功能。
    那么能不是也可以通过注解定义 Bean,从 XML 配置文件中完全移除 Bean 定义的配置呢?
    答案是肯定的,我们通过 Spring 2.5 提供的 @Component 注释就可以达到这个目标了。
    修改Bean的java类的代码如下,在类名前面加上 @Component注解
    package com.firemax.test.service;

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;


    import com.firemax.test.hibernate.AlcorTCitys;
    import com.firemax.test.hibernate.AlcorTCitysDAO;
    import com.firemax.test.hibernate.AlcorTCountries;
    import com.firemax.test.hibernate.AlcorTCountriesDAO;
    import com.firemax.test.hibernate.AlcorTProvinces;
    import com.firemax.test.hibernate.AlcorTProvincesDAO;
    import com.firemax.test.hibernate.AlcotTDistrict;
    import com.firemax.test.hibernate.AlcotTDistrictDAO;

    @Component
    public class CountryService {
        private static Log logger = LogFactory.getLog(CountryService.class);
        @Autowired
        private AlcorTCountriesDAO  alcorTCountriesDAO;
        @Autowired
        private AlcorTProvincesDAO  alcorTProvincesDAO;
        @Autowired
        private AlcorTCitysDAO          alcorTCitysDAO;
        @Autowired
        private AlcotTDistrictDAO       alcotTDistrictDAO;
       
        public CountryService(){
           
        }
         //这里是业务逻辑的方法
         。。。。。
    }
    然后,我们修改配置文件applicatonContext.xml中,启用自动注入的功能,而放弃原来的<bean>方式的配置
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                                                http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-2.5.xsd
                                                http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
        default-autowire="autodetect">
        <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
            <property name="persistenceUnitName" value="testerPU" />
        </bean>
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean>
        <tx:annotation-driven transaction-manager="transactionManager" />
        <bean id="transactionInterceptor"
            class="org.springframework.transaction.interceptor.TransactionInterceptor">
            <!-- 事务拦截器bean需要依赖注入一个事务管理器 -->
            <property name="transactionManager">
                <ref local="transactionManager" />
            </property>
            <property name="transactionAttributes">
                <!-- 下面定义事务(指service里面的方法)传播属性 -->
                <props>
                    <prop key="insert*">PROPAGATION_REQUIRED</prop>
                    <prop key="update*">PROPAGATION_REQUIRED</prop>
                    <prop key="save*">PROPAGATION_REQUIRED</prop>
                    <prop key="add*">PROPAGATION_REQUIRED</prop>
                    <prop key="update*">PROPAGATION_REQUIRED</prop>
                    <prop key="remove*">PROPAGATION_REQUIRED</prop>
                    <prop key="delete*">PROPAGATION_REQUIRED</prop>
                    <prop key="get*">PROPAGATION_REQUIRED,readOnly
                    </prop>
                    <prop key="find*">PROPAGATION_REQUIRED,readOnly
                    </prop>
                    <prop key="load*">PROPAGATION_REQUIRED,readOnly
                    </prop>
                    <prop key="change*">PROPAGATION_REQUIRED</prop>
                    <prop key="count*">PROPAGATION_REQUIRED</prop>
                    <prop key="*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>
       
        <!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->
        <!--  这个Processor 已经被 <context:annotation-config/> 所简化  
        <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
        -->
         <!-- <context:component-scan/> 配置项不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor),因此当使用 <context:component-scan/> 后,就可以将 <context:annotation-config/> 移除了。 -->
        <context:component-scan base-package ="com.firemax"/> 
       
       
        <!-- 定义自动代理BeanNameAutoProxyCreator -->
        <bean id="beanNameAutoProxyCreator"
            class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
            <!-- 指定对满足哪些bean name的bean自动生成业务代理 -->
            <property name="beanNames">
                <list>
                    <value>*Service</value>
                </list>
            </property>
            <!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器  -->
            <property name="interceptorNames">
                <list>
                    <!-- 此处可增加其他新的Interceptor -->
                    <value>transactionInterceptor</value>
                </list>
            </property>
        </bean>
        <!--
        <bean id="AlcorTCountriesDAO" class="com.firemax.test.hibernate.AlcorTCountriesDAO">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean>
        <bean id="AlcorTProvincesDAO" class="com.firemax.test.hibernate.AlcorTProvincesDAO">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean>
        <bean id="AlcotTDistrictDAO" class="com.firemax.test.hibernate.AlcotTDistrictDAO">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean>
        <bean id="AlcorTCitysDAO" class="com.firemax.test.hibernate.AlcorTCitysDAO">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean>
       
         <bean id="CountryService" class="com.firemax.test.service.CountryService"/>
        -->
    </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+

    下面是一个简单的例子:

    <context:component-scan base-package="com.firemax">    <context:include-filter type="regex"         expression="com\.firemax\.test\.service\..*"/>    <context:exclude-filter type="aspectj"         expression="com.firemax.test.util..*"/></context:component-scan>

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


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


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


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


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


    /*
     * Created on 2008-9-28
     *
     * 徐泽宇 roamer
     */
    package com.firemax.test.tester;

    import java.util.Iterator;

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

    import com.firemax.test.hibernate.AlcorTCitys;
    import com.firemax.test.hibernate.AlcorTCitysDAO;
    import com.firemax.test.hibernate.AlcorTCountries;
    import com.firemax.test.hibernate.AlcorTProvinces;
    import com.firemax.test.hibernate.AlcotTDistrict;
    import com.firemax.test.hibernate.AlcotTDistrictDAO;
    import com.firemax.test.service.CountryService;

    public class Tester {

        /**
         * @param args
         */
        public static void main(String[] args) throws Exception{
            // TODO Auto-generated method stub
            ApplicationContext ctx =     new FileSystemXmlApplicationContext("/WebContent/WEB-INF/classes/applicationContext*.xml");
            String[] beans = ctx.getBeanDefinitionNames();
            for (int i = 0 ; i < beans.length;i++)
            {
                System.out.println(beans[i]);
            }
            CountryService countryService= (CountryService)ctx.getBean("countryService");
         
            AlcorTCountries  alcorTCountries= countryService.getCountriesInfo("CN");
            System.out.println(alcorTCountries.getCountry());
            System.out.println("开始调用子类");
            System.out.println(alcorTCountries.getAlcorTProvinceses().size());
            Iterator<AlcorTProvinces> it = alcorTCountries.getAlcorTProvinceses().iterator();
            while (it.hasNext()){
                AlcorTProvinces  alcorTProvinces= (AlcorTProvinces)it.next();
                System.out.println(alcorTProvinces.getProvinceName());
            }
            AlcotTDistrict alcotTDistrict= new AlcotTDistrict();
            alcotTDistrict.setDistrictCode("22");
            alcotTDistrict.setDistrictName("浦东");
            AlcorTCitys alcorTCitys =countryService.getCityInfo("021");
            alcotTDistrict.setAlcorTCitys(alcorTCitys);
            countryService.saveProvinces(alcotTDistrict);
           
        }
    }


    在所有的JPOPO中,我们可以使用@Entity 这个注解来注入 JOPO。这样我们在 Persistent.xml中就不需要在 定义哪些POJO的类了。


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

    本文来自CSDN博客,转载请标明出处

  • 相关阅读:
    net5:动态修改内存中的站点地图节点
    手动创建DataTable并绑定gridview
    文件转换成二进制流及二进制流转换成文件
    XML 增、删、改和查的实例【转】
    免费CSS鼠标样式代码大全
    C#连接数据库SQL(2005)
    关于hibernate4.3版本之后org.hibernate.service.ServiceRegistryBuilder被弃用
    史上最全的Maven Pom文件标签详解
    Readme.MD 例子
    GitHub中README.md文件的编辑和使用
  • 原文地址:https://www.cnblogs.com/huqingyu/p/1658086.html
Copyright © 2011-2022 走看看