简单拦截器(spring aop)

xiaoxiao2026-05-19  15

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); } } 相关资源:mybatis 拦截器 + spring aop切面 + spring事务+ 反射工具类
转载请注明原文地址: https://www.6miu.com/read-5049043.html

最新回复(0)