您的位置:首页 > 编程语言 > Java开发

spring 拦截器(ProxyFactoryBean,BeanNameAutoProxyCreator)

2015-08-28 20:07 866 查看
比较下spring 拦截器,一般有两种,第一种是使用 ProxyFactoryBean, 第二种是使用BeanNameAutoProxyCreator。先介绍这两种拦截器的简单使用例子,再比较分析优缺点.


   使用 ProxyFactoryBean
作拦截器三部曲

   1.先定义业务接口以及实现类(无需实现或扩展任何接口或继承类)

//业务接口
public interface SayHello
{
public void sayHell();

}

//业务接口实现类之一

public class SayChineseHelloImpl implements SayHello
{

/* (non-Javadoc)
* @see test.SayHello#sayHell()
*/
public void sayHell()
{
PrintUtil.print("你好!");
}

}

//业务实现接口类之二

public class SayEnglishHello implements SayHello
{

/* (non-Javadoc)
* @see test.SayHello#sayHell()
*/
public void sayHell()
{
PrintUtil.print("hello !");
}

}



2.定义拦截器(需实现MethodInterceptor
接口)

//定义日志拦截器
public class LogInterCeptor implementsMethodInterceptor
{

/* (non-Javadoc)
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
public Object invoke(MethodInvocation invocation) throwsThrowable
{
doBusiness(invocation);
return  invocation.proceed();
}
private Object doBusiness(MethodInvocation invocation){

System.out.print("I'm do nothing except  record log.....");
return null;
}

}



  3.spring.xml 配置

<bean id="sayChineseHello"class="test.SayChineseHelloImpl"/>
<bean id="sayEnglishHello"class="test.SayEnglishHello"/>
<bean id="logInterceptor"class="interceptor.LogInterCeptor"/>

<bean id="sayHelloProxy"class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<!--需要拦截的接口的类全名-->
<value>test.SayHello</value>
</property>

<property name="interceptorNames">
<list>
<!--由拦截器和业务类组成的列表,业务类必须放在最后,而且只能拦截一个业务类-->
<value>logInterceptor</value>
<value>sayEnglishHello</value>
</list>
</property>
</bean>
 
   好了,至此,一切就绪,开始使用:

public class InterceptorTest
{
private ApplicationContext context=null;
@Before
public void init(){
context=newClassPathXmlApplicationContext("spring.xml");

}
@Test
public void testInterceptor(){

System.out.println("sayEnglishHello whitout  proxy!");
SayHello sayEnglishHello=(SayHello)  context.getBean("sayEnglishHello");
sayEnglishHello.sayHell();
System.out.println("sayChineseHello whitout  proxy!");
SayHello sayChineseHello=(SayHello)  context.getBean("sayChineseHello");
sayChineseHello.sayHell();

System.out.println("sayEnglishHello whit  proxy!");

SayHello sayHelloProxy=(SayHello)  context.getBean("sayHelloProxy");
sayHelloProxy.sayHell();

}
}
 
   输出结果

sayEnglishHello whitout  proxy!
hello!
sayChineseHello whitout  proxy!
你好!
sayEnglishHello whit  proxy!
I'm nothing except  record log.....
hello!
BeanNameAutoProxyCreator
跟上面差不多,只是配置不同而已:

<bean id="sayChineseHello"class="test.SayChineseHelloImpl"/>
<bean id="sayEnglishHello"class="test.SayEnglishHello"/>
<bean id="logInterceptor"class="interceptor.LogInterCeptor"/>

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"id="test_proxy">
<property name="beanNames">
<list>
<!--需要拦截的业务类ID列表-->
<value>sayEnglishHello</value>
<value>sayChineseHello</value>
</list>
</property>
<property name="interceptorNames">
<list>
<!--拦截器列表-->
<value>logInterceptor</value>

</list>
</property>
</bean>
public class InterceptorTest
{
private ApplicationContext context=null;
@Before
public void init(){
context=new ClassPathXmlApplicationContext("spring.xml");

}
@Test
public void testInterceptor(){

System.out.println("sayEnglishHello whit  BeanNameAutoProxyCreator!");
SayHello sayEnglishHello=(SayHello)  context.getBean("sayEnglishHello");
sayEnglishHello.sayHell();
System.out.println("sayChineseHello whit  BeanNameAutoProxyCreator!");
SayHello sayChineseHello=(SayHello)  context.getBean("sayChineseHello");
sayChineseHello.sayHell();
}
}


?然后测试? 
 查看测试结果

sayEnglishHello whit  BeanNameAutoProxyCreator!
I'm nothing except  record log.....
hello!
sayChineseHello whit  BeanNameAutoProxyCreator!
I'm nothing except  record log.....
你好!


     总结下:两种拦截器都需要经过三个步骤:实现业务类,实现拦截器,配置业务类也拦截器关系。如果需要代理的bean很多,使用ProxyFactoryBean 无疑会对spring配置文件的编写带来繁重的工作,因为ProxyFactoryBean 不支持代理列表。BeanNameAutoProxyCreator考虑到这点,既支持多个拦截器,又支持多个代理bean,略胜一筹,哈哈

事务管理配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/myuser</value>
</property>
<property name="username">
<value>lighter</value>
</property>
<property name="password">
<value>12345</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>org/mmc/dao/domain/User.hbm.xml</value>
</list>
</property>
</bean>
<!-- 配置Hibernate的事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<!-- 定义事务拦截器bean -->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<!-- 定义BeanNameAutoProxyCreator-->
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<!-- 所有名字以DAO,Service结尾的bean,将由该"bean后处理器"为其创建事务代理;实际上应该在业务层进行事务管理,这里只是举一个简单例子 -->
<value>*DAO,*Service</value>
</property>
<!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
<property name="interceptorNames">
<list>
<!-- 可以增加其他的拦截器 -->
<value>transactionInterceptor</value>
</list>
</property>
</bean>

<!-- 举下面这一个例子:这时候,这一个bean已经有了事务管理,可以增加类似的bean -->
<bean id="searchUserDAO" class="org.mmc.dao.impl.SearchUserDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>

ref:http://my.oschina.net/qicheng/blog/168085
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: