StevenBot-Saltsam

眼睛能装下世界,为何却装不下眼泪? 一只风筝一辈子只为一根线冒险。 那不是一场游戏,为何总有一根线牵着心怀,隐隐作疼? 那不是一段邂逅,为何飘在桥上的影子,总缠进梦乡? 那不是一个梦境,为何你的温柔私语,总是不经意的响起?

导航

<2011年11月>
日一二三四五六
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

统计

常用链接

留言簿

随笔分类

随笔档案

文章分类

文章档案

datas link

OSChinal Sources codes Library

搜索

最新评论

阅读排行榜

评论排行榜

Spring 学习

1.spring属性的注入配置

  1. 1.      属性的注入配置

Bean文件的配置,即为bean的各属性赋值

 

<bean id="sone" class="edu.yzu.entity.Student" init-method="initialMethod" parent="sbean" >

<!—- init-method指定了该bean类初始化后用来验证属性是否合法,该方法会在属性设置结束后调用 ,

Parent是指本bean中的一些属性如果没有初始化则会以sbean中的相同属性名的对应值来初始化--!>

       <property name="id" value="10002" />

       <property name="name" value="Rose" />

       <property name="sex" value="boy" />

       <property name="age" value="23" />

       <property name="birthday" value="1980-10-24" />

       <property name="emails">

           <list>

              <value>123@qq.com</value>

              <value>456@sina.com</value>

              <value>789@163.com</value>

           </list>

       </property>

       <property name="phones">

//list或者数组类型的属性注入

           <list>

              <value>13657164847</value>

              <value>15901083941</value>

              <value>13797502137</value>

           </list>

       </property>

       <property name="scores">

//为map指定 key value属性指定一般类型,key-ref  value-ref指定的是bean引用

           <map>

              <entry key="math" value="97" />

              <entry key="chinese" value="96" />

              <entry key="englist" value="92" />

           </map>

       </property>

 

       <property name="classmates">

//set类型的属性注入

           <set>

              <ref local="sone" />

<!-- 表时此值并非String int 等原始类型,local指明这个值是本配置文件的一个bean -à

              <ref local="myself" />

           </set>

       </property>

    </bean>

  1. 非自动类型转换

对bean属性的注入过程中,如果一些类型不能注入,则可以类型转换,自定义转换该类型的转换器,如上面的birthday属性是日期性的,spring 不能自动注入该类型,则自定义转换器如下:

public class myDateEditor extends PropertyEditorSupport {

    @Override

    public void setAsText(String text) throws IllegalArgumentException {

       try {

           SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd");

           Date date = format.parse(text);

           setValue(date);

       } catch (ParseException e) {

           e.printStackTrace();

           new IllegalAccessException(e.getMessage());

       }

    }

}

 

 

 

 

 

 

配置文件如下 :只要这样配置后spring 遇到java.util.Date类型后会自动调用上面的转换器,注入bean属性

 

    <bean id="myeditor"

       class="org.springframework.beans.factory.config.CustomEditorConfigurer">

       <property name="customEditors">

           <map>

              <entry key="java.util.Date">

                  <bean id="dateEditor" class="edu.yzu.editor.myDateEditor" />

              </entry>

           </map>

       </property>

    </bean>

2.spring非自动类型转换

对bean属性的注入过程中,如果一些类型不能注入,则可以类型转换,自定义转换该类型的转换器,如上面的birthday属性是日期性的,spring 不能自动注入该类型,则自定义转换器如下:

public class myDateEditor extends PropertyEditorSupport {

    @Override

    public void setAsText(String text) throws IllegalArgumentException {

       try {

           SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd");

           Date date = format.parse(text);

           setValue(date);

       } catch (ParseException e) {

           e.printStackTrace();

           new IllegalAccessException(e.getMessage());

       }

    }

}

 

3.spring中面向切面的使用

  1. BeanPostProcessor接口的使用

 

BeanPostProcessor接口用在bean生成后将放入ApplicationContext前进行一些必要的处理,它有两个方法,分别在调用bean配置的init-method前后执行(如果配置了的话),本接口的实现类常常结合动态代理生成bean的代理类型:

class MyProxyClass {

    private Object target;

 

    public MyProxyClass(Object target) {

       this.target = target;

    }

 

    public Object getNewProxy() {

       return Proxy.newProxyInstance(target.getClass().getClassLoader(),

              target.getClass().getInterfaces(), new InvocationHandler() {

 

                  public Object invoke(Object proxy, Method method,

                         Object[] args) throws Throwable {

                     System.out.println("you can do something here!!");

                     Object obj = method.invoke(target, args);

                     System.out.println("you can do something here!!");

                     return obj;

                  }

              });

    }

}

 

接口使用如下,接口使用如下,一般只要在postProcessAfterInitialization里面配置后即可(事实上这在实际开发中很少使用,一般会使用spring提供的组件,但其底层是使用这些的)

public class MyBeanPostProcessor implements BeanPostProcessor {

 

    public Object postProcessAfterInitialization(Object bean, String id)

           throws BeansException {

      

//参数Object 为生成的bean id 为该bean在配置文件中的id,这里我们一该用动态代理来生成一个代理对象返回

       return new  MyProxyClass(bean).getNewProxy();

    }

 

    public Object postProcessBeforeInitialization(Object bean, String id)

           throws BeansException {

              return bean;

    }

 

}

 

配置如下:

    <bean id="myprocessor" class="edu.yzu.filter.MyBeanPostProcessor" />

如上配置后spring 会自动为每个生成的bean生成相应的代理,如上代理的的效果为在调用每个方法找对应此bean的id,,,我们可以使用动态代理来生成

 

  1. 对bean中方法的方法的拦截(既自定义的Advice)共有四种,分别为四个接口,继承此四个接口后分别实现对应的方法:

MethodBeforeAdvice(在方法调用之前)

    public void before(Method method, Object[] args, Object target)

           throws Throwable {

//要在方法调用之前执行的操作

    }

MethodInterceptor (在方法调用之前之后都可以用此接口中的一个方法得到)

    AfterReturningAdvice(在方法返回以后)

    public void afterReturning(Object returnValue, Method method, Object[] args,

           Object targer) throws Throwable {

       //在方法调用之后 要执行的操作

    }

    ThrowsAdvice(在方法抛出异常以后会拦截)

public void afterThrowing(Exception e) {

       Session session=HibernateSessionFactory.getSessionFactory().getCurrentSession();

       session.getTransaction().rollback();

    }

注意:ThrowsAdvice接口中没有任何方法,但是使用此接口必须给出的方法签名为:afterThrowing,它可以重载多次,当相应的异常发生后调用对应的处理方法

使用:在配置文件中配置自定义的Advice,比如我有一个 TranstionManager类,它用来控制事务,实现了MethodInterceptor,如下!

public class TranstionManager implements MethodInterceptor {

    public Object invoke(MethodInvocation invocation) throws Throwable {

       Session session = HibernateSessionFactory.getSessionFactory()

              .getCurrentSession();

       Transaction trans = session.getTransaction();

       trans.begin();

       Object obj = invocation.proceed();

       trans.commit();

       return obj;

    }

}

文件的配置如下:

    <bean id="transtionmanager" class="edu.yzu.filter.TranstionManager"/>

另外有一个bean即为拦截的目标对象,为其生成代理对象,该bean的配置如下:

<bean id="userDao" class="edu.yzu.dao.impl.UserDaoImpl"/>

   

    <bean id="userBiz" class="edu.yzu.biz.impl.UserBizImpl">

    <property name="userDao">

    <ref local="userDao"/>//将userDao注入到到UserBizImpl中

    </property>

    </bean>

下面为userBiz生成代理对象的bean使用时用ApplicationContext对象实例applicationContext调用代理对象的方法为:applicationContext.getBean(“userBizImpl”);

<bean id="userBizImpl" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target">

    <ref local="userBiz"/>//指定给哪个目标对象建立代理

    </property>

    <property name="interceptorNames">

    <list>

    <value>transtionmanager</value>

//使用的Advice, 可以配置多个

    </list>

    </property>

    <property name="interfaces">

    <list>

    <value>edu.yzu.biz.UserBiz</value>

//指定要代理目标对象的哪个的接口

    </list>

    </property>

    </bean>

(上面是为实现接口的类生成代理) 缺点:一旦为一个bean指定代理,则bean中的所有方法都会被代理,不能指定为特定的方法指定代理,没有体现面向切面的特点!优点,依然可以拿到代理前的bean对象。如果没有实现任何接口,则不必要加name=”interfaces” 的项,但要加<property name="proxyTargetClass">

       <value>true</value>

       </property>表示这个bean没有实现任何接口,spring为它生成它的子类(cglib实现)

 

  1. 切面=切入点+切入内容。既为:aspect=pointcut+advice  spring 中切面用advisor表示,可以在配置文件中配置。切入的内容即为我们自定义的类型,它实现四个接口的的任何一个。切入点即为要切入内容的目标类型的方法:由此可知切面的配置也要配置这两项!

l         为一个bean配置一个advisor ,一个advisor里面只能有一个advice,但是可以给此advisor指定几个切入点,方法如下:

     <bean id="myadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

    <property name="advice">

    <ref local="transtionmanager"/>

    </property>

    <property name="mappedNames">

    <list>

    <value>addProduct</value>

    <value>deleteProductById</value>

    <value>getAllProducts</value>

    <value>getProduct</value>

    <value>getProducts</value>

    <value>updateProduct</value>

    </list>

    </property>

</bean>

这个Advisor只指定的advice为transtionmanager 为切入的内容,切入点为list只的几个方法名,既所代理的bean中,只有方法名相同的才能被切入。这正是面向切面的思想所在,advisor用法如下:

<bean id="productBizImpl" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="target">

    <ref local="productBiz"/>

    </property>

    <property name="interceptorNames">

    <list>

    <value>myadvisor</value>

    <value>exceptionadvice</value>//这个是没有包装的advice,配置如下:

//<bean id="exceptionadvice" class="edu.yzu.filter.ExceptionFilter"/>

    </list>

    </property>

    <property name="interfaces">

    <list>

    <value>edu.yzu.biz.ProductBiz</value>

    </list>

    </property>

</bean>

这样做的好处体现了面向切面的思想,既给指定的切入点切入想要执行的内容。

 

下面是为多个bean指定多个advisor的方法,似乎也是最为常用的。

 

l         第一种:为多个bean同时指定多个advisor

Advisor配置不变,如下

     <bean id="myadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

    <property name="advice">

    <ref local="transtionmanager"/>

    </property>

    <property name="mappedNames">

    <list>

    <value>addProduct</value>

    <value>deleteProductById</value>

    <value>getAllProducts</value>

    <value>getProduct</value>

    <value>getProducts</value>

    <value>updateProduct</value>

    </list>

    </property>

</bean>

 

指定代理的目标对象的配置如下,既为哪些目标bean生成代理

    <bean id="autoProxy"

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

       <property name="interceptorNames">

           <list>

              <value>myadvisor</value>

              <value>exceptionadvisor</value>

//自定义的advisor

           </list>

       </property>

       <property name="beanNames">

           <list>

              <value>userBiz</value>

              <value>productBiz</value>

//生成代理的目标对象

           </list>

       </property>

    </bean>

优点:可以同时为多个bean指定多个advisor。不足,因为是自动的为指定的bean生成代理,所以不能再得到原来的bean,只能拿到代理后的bean对象

 

l         第二种:为多个bean同时指定多个advisor

完整配置如下:

    <bean id="userBiz" class="edu.yzu.biz.impl.UserBizImpl">

       <property name="userDao">

           <bean id="userDao" class="edu.yzu.dao.impl.UserDaoImpl" />

       </property>

    </bean>

    <bean id="productBiz" class="edu.yzu.biz.impl.ProductBizImpl">

       <property name="productDao">

           <bean id="productDao" class="edu.yzu.dao.impl.ProductDaoImpl" />

       </property>

</bean>

 

<bean id="myadvisor"

       class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

       <property name="advice">

           <bean id="transtionmanager" class="edu.yzu.filter.TranstionManager" />

       </property>

       <property name="mappedNames">

           <list>

              <value>addProduct</value>

              <value>deleteProductById</value>

              <value>getAllProducts</value>

              <value>getProduct</value>

              <value>getProducts</value>

              <value>updateProduct</value>

           </list>

       </property>

    </bean>

 

    <bean id="exceptionadvice"

       class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

       <property name="advice">

           <bean id="exadvice" class="edu.yzu.filter.ExceptionFilter" />

       </property>

       <property name="mappedNames">

           <list>

              <value>addProduct</value>

              <value>deleteProductById</value>

              <value>getAllProducts</value>

              <value>getProduct</value>

              <value>getProducts</value>

              <value>updateProduct</value>

           </list>

       </property>

</bean>

 

<bean id="defaultautoproxy"

    class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

优点,可以同时多个bean指定多个,advisor,缺点:可控性差。会为整个配置文件的所有的非advisor的bean都指定所有的advisor。注意事项,不必要的bean不要放在一个配置文件中,或者放在另外一个bean的内部,但是这样的bean对外界不可见,即不可用ApplicationContext的对象通过getBean得到!(实际用得不多)

6.spring中事务管理

声明式的事务管理(Declarative transaction management): 
<bean id="dataSource"

       class="org.apache.commons.dbcp.BasicDataSource">

       <property name="driverClassName">

           <value>oracle.jdbc.OracleDriver</value>

       </property>

       <property name="url">

           <value>jdbc:oracle:thin:@localhost:1521:XE</value>

       </property>

       <property name="username">

           <value>rose</value>

       </property>

       <property name="password">

           <value>aier</value>

       </property>

    </bean>

 

    <bean id="sessionFactory"

       class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

       <property name="dataSource">

           <ref bean="dataSource" />

       </property>

       <property name="hibernateProperties">

           <props>

              <prop key="hibernate.dialect">

                  org.hibernate.dialect.Oracle9Dialect

              </prop>

              <prop key="hibernate.show_sql">true</prop>

              <prop key="hibernate.format_sql">true</prop>

              <prop key="hibernate.jdbc.batch_size">15</prop>

           </props>

       </property>

       <property name="mappingResources">

           <list>

              <value>com/kettas/shops/entity/Entity.hbm.xml</value>

           </list>

       </property>

    </bean>

 

    <bean id="hibernatetemplate"

       class="org.springframework.orm.hibernate3.HibernateTemplate">

       <property name="sessionFactory">

           <ref bean="sessionFactory" />

       </property>

    </bean>

 

    <!--

       dao的bean

       +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    -->

    <bean id="userDao" class="edu.yzu.shops.dao.impl.UserDaoImpl">

       <property name="hibernateTemplate">

           <ref local="hibernatetemplate" />

       </property>

    </bean>

 

    <!--

       biz的配置

       +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    -->

    <bean id="userBiz" class="edu.yzu.shops.biz.impl.UserBizImpl">

       <property name="userDao">

           <ref local="userDao" />

       </property>

    </bean>

 

    <!--

       事物控制

       +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    -->

    <bean id="transactionManager"

       class="org.springframework.orm.hibernate3.HibernateTransactionManager">

       <property name="sessionFactory">

           <ref bean="sessionFactory" />

       </property>

    </bean>

 

    <bean id="transactionInterceptor"

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

       <property name="transactionManager">

           <ref bean="transactionManager" />

       </property>

       <property name="transactionAttributes">

           <props>

              <prop key="add*">PROPAGATION_REQUIRED,-Exception</prop>

              <prop key="update*">

                  PROPAGATION_REQUIRED,-Exception

              </prop>

              <prop key="delete*">

                  PROPAGATION_REQUIRED,-Exception

              </prop>

           </props>

       </property>

    </bean>

 

    <!-- 有两种方式可以给一个bean加上事务控制,一种为自动创建。

       另一种是指明创建 .第一种为:-->

    <bean id="autoProxy"

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

       <property name="beanNames">

           <list>

              <value>userBiz</value>

              <value>productBiz</value>

              <value>orderBiz</value>

              <value>orderItemBiz</value>

              <value>categoryBiz</value>

           </list>

       </property>

       <property name="interceptorNames">

           <list>

              <value>transactionInterceptor</value>

           </list>

       </property>

    </bean>

<!-- 第二种方法为下面,显然表比较少时用第二种可以,但是当表比较多时显然第一种更合适。 -->

    <bean id="userBizProxy"

       class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

       <property name="target">

           <ref bean="userBiz" />

       </property>

       <property name="transactionManager">

           <ref bean="transactionManager" />

       </property>

       <!-- 下面的设置表时要代理的不是类本身,而是其实现的接口 -->

       <property name="proxyTargetClass">

           <value>false</value>

       </property>

       <property name="proxyInterfaces">

           <list>

              <value>edu.yzu.biz.UserBiz</value>

           </list>

       </property>

       <property name="transactionAttributes">

           <props>

              <prop key="add*">PROPAGATION_REQUIRED,-Exception</prop>

              <prop key="update*">

                  PROPAGATION_REQUIRED,-Exception

              </prop>

              <prop key="delete*">

                  PROPAGATION_REQUIRED,-Exception

              </prop>

           </props>

       </property>

    </bean>

 

 

 

 

    <!--

       +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        -->

1. 

2. 

3. 

4. 

5. 

6. 

7. <bean

  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

  <!-- 配置事务管理器 -->

  <property>

   <ref bean="transactionManager" />

  </property>

  <!-- 此属性指定目标类本身是否是代理的对象,如果目标类没有实现任何类,就设为true代表自己 -->

  <property>

   <value>false</value>

  </property>

  <property>

   <value> com.test.service.userManageService</value>

  </property>

  <!-- 目标bean -->

  <property>

   <ref bean="userManageService"/>

  </property>

  <!-- 配置事务属性 -->

<property>

   <props>

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

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

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

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

<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>

 

 

利用继承的思想简化配置,适合相对比较多的模块时使用。

 <bean id="transactionBase"  

  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"  

  lazy-init="true" abstract="true">   

  <!-- 配置事务管理器 -->   

  <property name="transactionManager">   

   <ref bean="transactionManager" />   

  </property>   

  <!-- 配置事务属性 -->   

  <property name="transactionAttributes">   

   <props>   

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

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

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

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

<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>   

</props>   

</property>

</bean>   

8.<bean

  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

  lazy-init="true" abstract="true">

  <!-- 配置事务管理器 -->

  <property>

   <ref bean="transactionManager" />

  </property>

  <!-- 配置事务属性 -->

  <property>

   <props>

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

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

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

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

<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

</props>

</property>

</bean>


而具体的模块可以简单的这样配置。只要指明它的parent(父类)就可以了。父类一般把abstract="true",因为在容器加载的时候不需要初始化,等到用的时候再有它的子类调用的时候,再去初始化。

Java代码

<bean id="userManageServiceProxy" parent="transactionBase" >   

  <property name="target">   

  <ref bean="userBiz"/>   

  </property>   

</bean>  <bean parent="transactionBase" >

  <property>

  <ref bean="userManageService"/>

  </property>

</bean>

8.DWR与spring的整合简单使用

  1. 文件的配置。在web.xml中配置dwr的拦截器,为一个Servlet,配置如下:

       <servlet>

       <servlet-name>dwrServlet</servlet-name>

       <servlet-class>

           org.directwebremoting.servlet.DwrServlet

       </servlet-class>

       <init-param>

           <param-name>debug</param-name>

           <param-value>true</param-value>

       </init-param>

    </servlet>

    <servlet-mapping>

       <servlet-name>dwrServlet</servlet-name>

       <url-pattern>/dwr/*</url-pattern>

    </servlet-mapping>

  1. 在dwr.xml文件中的配置

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

<!DOCTYPE dwr PUBLIC

    "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"

    "http://getahead.org/dwr/dwr20.dtd">

<dwr>

    <allow>

       <create javascript="JTestBean" creator="new">

           <param name="class" value="edu.yzu.dwr.TestBean"/>

       </create>

       <convert  converter="bean" match="edu.yzu.dwr.Student"/> 

           <!--

         <convert converter="bean" match="edu.yzu.dwr.Teacher"/>     

         若是在方法签名或者返回类型中用到了自定义类型,则要加上这一句,即给自定义类型一个转换器,在客户端会自动被转换为js对象   -->

    </allow>

<!—下面也有必要配置一下,即当所使用的方法签名有用到泛型集合时要指定(往往不配置也没没有什么错误)-- >

    <signatures>

       <![CDATA[

          import java.util.* ;

          import edu.yzu.entity.*.*;

          public List<User> queryAllUsers() ;

       ]]>

    </signatures>

  1. 在所使用的页面引用dwr动态生成的js文件!

<script src="/ajax/dwr/interface/JTestBean.js"></script>

<script src="/ajax/dwr/engine.js"></script> 

如果有必要还可以引用dwr提供的一个util.js的工具包

 

  1. dwr整合spring的配置

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

<!DOCTYPE dwr PUBLIC

    "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"

    "http://getahead.org/dwr/dwr20.dtd">

 

<!-- dwr与spring的整合

create标签的creator值为spring表时dwr在不创建对象,而是使用

spring托管的对象。

它的param标签的name属性为beanName,value属性的值与spring中bean

的id值对应。

 -->

<dwr>

    <allow>

       <create javascript="userBiz" creator="spring">

           <param name="beanName" value="userBiz" />

       </create>

       <convert converter="bean" match="edu.yzu.shops.entity.User" />

    </allow>

</dwr>


posted on 2011-11-16 01:16 Steven_bot 阅读(588) 评论(0)  编辑  收藏 所属分类: study logger


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


网站导航: