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 阅读(528) 评论(0)  编辑  收藏 所属分类: study logger


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


网站导航: