简单拦截器(spring aop)

1.applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans"
xmlns:http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance"
xmlns:http://www.springframework.org/schema/p">http://www.springframework.org/schema/p"
xmlns:http://www.springframework.org/schema/aop">http://www.springframework.org/schema/aop"
xmlns:http://www.springframework.org/schema/tx">http://www.springframework.org/schema/tx"
xsi:schemaLhttp://www.springframework.org/schema/beans">http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!--第一种配置数据源
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/beian"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
-->
<!-- 第二种方式配置数据源 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 将数据库源导入到会话工厂的class类中去 -->
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<!-- 配置hibernate方言(mysql/orcle/sqlserver)-->
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
<property name="mappingResources">
<list>
<!-- 导入hibernate 中实体JavaBean 对应的配置文件 -->
<value>com/edong/beian/model/Log.hbm.xml</value>
</list>
</property>
</bean>
<!-- 创建事务管理器 -->
<!-- jdbc,ibtas 方式
<bean id="jdbcTransaction"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
-->
<!-- hibernate 方式 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--配置了事务拦截器-->
<bean id="interceptorTrans" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!--根据需要进行事务切换-->
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<!--PROPAGATION_REQUIRED:
表示在当前运行的方法中:
如果没有事务环境,则添加:conn.setCommitAuto(false),且事务类型为:wr;
如果有事务环境,则把该事务类型改为:wr
-->
<!-- ServiceException 前面的符号的含义:
+ 表示在当前运行的方法中,如果抛出该类型的异常,则强制提交事务,commmit();
_ 表示在当前运行的方法中,如果抛出该类型的异常,则回退事务,以前提交的数据rollback();
-->
<!-- 为以h开头的方法进行添加事务处理为以h开头的方法进行添加事务处理 -->
<prop key="p*">
PROPAGATION_REQUIRED,-RuntimeException
</prop>
</props>
</property>
</bean>
<!-- 配置DAO-->
<bean id="logDAO" class="com.edong.beian.dao.LogDAO"/>
<!-- 配置需要被代理的目标类 -->
<bean id="logService" abstract="false"
lazy-init="default" autowire="default" dependency-check="default"
class="com.edong.beian.service.LogService">
<!--在LogService 中注入LogDAO-->
<property name="logDAO" ref="logDAO"/>
</bean>
<!--配置事务代理类-->
<bean id="transactionProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<!--要对目标类DeptDAO进行自动事务处理,当调用该目标类中的方法??会给自动维护它的事务的统一性质-->
<value>logService</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>interceptorTrans</value>
</list>
</property>
<property name="optimize" value="true"/>
</bean>
<!-- 前置增强 -->
<bean id="before" class="com.edong.beian.cglib.LogMethodBeforeAdvice"/>
<!-- 后置增强 -->
<bean id="after" class="com.edong.beian.cglib.LogAfterReturningAdvice"/>
<!-- 前后增强 -->
<bean id="around" class="com.edong.beian.cglib.LogMethodInterceptor"/>
<!-- 异常增强-->
<bean id="throw" class="com.edong.beian.cglib.ThrowExceptionAdvice"/>
<!-- 返回代理对象 -->
<bean id="proxy1" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--指定目标类-->
<property name="target" ref="logService"/>
<property name="proxyTargetClass" value="true"/>
<!-- 前提: 不管用hibernate的HibernateTransactionManager事务管理类
还是用 jdbc,ibatis的DataSourceTransactionManager事务管理类来进行事务管理
1. 如果目标类实现了一个接口
1) 当 optimize=true 为cglib产生的事务代理对象
2) 当 optimize=false 或 默认时 则以为jdk产生动态代理对象
2.如果目标类不实现任何接口
1) 当 optimize=true 为cglib产生的事务代理对象
2) 当 optimize=false 或默认时 则以为jdk产生动态代理对象,但是会报异常
(原因是:由jdk产生的代理时目标类必须实现一个接口,而cglib既能代理接口也能代理类)
注意:
传入 Session 注入SessionFactory 要分清
1.如果以spring内置代理(包括事务代理)时, getHibernateTemplate()
方式获取的SessionFactory 永远为空.(原因她由spring内部通过new 创
建一全新的HibernateTemplate 实列, 并不是通过获取配置文件中注入的
SessionFactory)
2.如果在配置文件中配置自动管理目标类的事务机制时,该机制只能管理通过
getHibernateTemplate()获取对象中的事务和它的统一性. 不能管理
传入的Session 的事务和它的统一性.传入的Session的事务必须手动
开启和提交.
-->
<!--添加增强类-->
<property name="interceptorNames">
<list>
<value>before</value>
<value>after</value>
<value>around</value>
<value>throw</value>
</list>
</property>
</bean>
</beans>

2. cglib:实现前增强,后增强,前后增强,异常增强 (四个单独的类)
前增强
import com.edong.ws.security.Login;
import java.lang.reflect.Method;
import java.util.Date;
import org.springframework.aop.MethodBeforeAdvice;
public class LogMethodBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] aobj, Object obj)
throws Throwable {
String date = (new Date()).toString();
Login login=null;
if(aobj.length>0){
if(aobj[0] instanceof Login){
login =(Login)aobj[0];
System.out.println("信息:[" + date + "]用户 " +login.getUsername() + " 正在尝试登录陆系统...");
}
}
}
后增强...
import com.edong.ws.security.Login;
import java.lang.reflect.Method;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.aop.AfterReturningAdvice;
public class LogAfterReturningAdvice implements AfterReturningAdvice {
public void afterReturning(Object obj, Method method, Object[] aobj,
Object obj1) throws Throwable {
String date = (new Date()).toString();
/ /防止其他方法进入:logService.getCount();方法中就没参数...所以不存在访问数组元素...就会报错..
if(aobj.length>0){
if(aobj[0] instanceof Login){
Login login=(Login)aobj[0];
System.out.println("信息:["+date+"]用户 "+login.getUsername()+" 成功登录系统.");
}
}
}
前后增强
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class LogMethodInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
Object result = null;
Object[] args = methodInvocation.getArguments();//获取传入目标方法的参数列表
int length =args.length;
for (int i = 0; i <length; i++) {
if (args instanceof Session){//判断参数类型是否是 Session
Transaction trans=((Session)(args)).beginTransaction();
try {
trans.begin();
result = methodInvocation.proceed();//调用代理目标类的具体方法
trans.commit();
} catch (Exception e) {
trans.rollback();
e.printStackTrace();
}
}
}
return result;
}
}

异常增强 :导包
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class ThrowExceptionAdvice implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target,Exception ex)throws Throwable {
System.out.println("用户登录过程中发生异常: "+target.getClass().getSimpleName());
}
}


测试类:导包
import com.edong.beian.service.LogService;
import com.edong.ws.security.Login;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
public static void main(String[] args){
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");//xml文件 放在src目录下
LogService logService = (LogService) ac.getBean("proxy1");
Login login=new Login();
login.setUsername("thh");
login.setPassword("aaa");
logService.clientLogin(login);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值