在上一篇博文中我们讲了前置增强处理。在这篇文章中我们将结合案例继续讲解其它各种增强处理。
一 后置增强
LoggerAfterReturning类则通过AfterReturningAdvice接口实现后置增强,该接口要求实现afterReturning()方法。Spring会将该方法添加到目标方法正常返回之后执行。afterReturning()方法有4个参数,target表示被代理的目标对象,method表示被代理的目标方法,arguments表示传递给目标方法的参数歹I表,retumValue表示目标方法的返回值。
================LoggerAfter.java==================package com.obtk.advise;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.apache.log4j.Logger;
import org.springframework.aop.AfterReturningAdvice;
public class LoggerAfter implements AfterReturningAdvice {
private static final Logger log=Logger.getLogger(LoggerAfter.class);
public void afterReturning(Object result, Method method, Object[] args,
Object target) throws Throwable {
log.info("调用了"+target+"的方法:"+method.getName()+",方法参数:"
+Arrays.toString(args)+",返回值:"+result);
}
}
要切入的方法
===================public int save(UsersEntity user) {
System.out.println("方法执行开始...");
int result=0;
SqlSession session=null;
try {
session=MybatisUtil.getSession();
result=session.insert("user.save", user);
session.commit();
} catch (Exception e) {
session.rollback();
e.printStackTrace();
}finally{
MybatisUtil.closeSession();
}
System.out.println("方法执行结束...");
return result;
}
配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="dbUserDao" class="com.obtk.dao.DbUserDaoImpl"></bean>
<bean id="userServ" class="com.obtk.service.UserService" p:userDao-ref="dbUserDao">
</bean>
<bean id="afterAdvise" class="com.obtk.advise.LoggerAfter"></bean>
<aop:config>
<aop:pointcut id="myCut" expression="execution(* com.obtk.dao.*.*(..))" />
<aop:advisor advice-ref="afterAdvise" pointcut-ref="myCut"/>
</aop:config>
</beans>
异常抛出增强的特点是在目标方法抛出异常时织人增强处理。
增强处理代码
package com.obtk.advise;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
import org.springframework.aop.ThrowsAdvice;
public class ExceptionAdvise implements ThrowsAdvice {
private static final Logger log=Logger.getLogger(ExceptionAdvise.class);
public void afterThrowing(Method method,Object[] args
,Object target,RuntimeException e){
log.info("调用"+target+"的方法"+method.getName()+"发生了异常==>\n"+e);
}
}
以上代码通过ThrowsAdvice接口实现异常抛出增强。ThrowsAdvice接口中并没有定义任何方法,但是我们在定义异常抛出的增强方法时必须遵守以下方法签名。
void afterThrowing( Method method, Object[] arguments, Object target, Throwable ex)
这里规定了方法名必须是afterThrowing。方法的人参只有最后1个是必需的,前3个人参是可选的,但是前3个参数要么都提供,要么一个也不提供。
切入的方法package com.obtk.dao;
import org.apache.ibatis.session.SqlSession;
import com.obtk.entitys.UsersEntity;
import com.obtk.utils.MybatisUtil;
public class DbUserDaoImpl implements UserDao{
public int save(UsersEntity user) {
System.out.println("方法执行开始...");
int result=0;
SqlSession session=null;
try {
session=MybatisUtil.getSession();
result=session.insert("user.save", user);
session.commit();
} catch (Exception e) {
session.rollback();
//要使异常抛出增强代码生效,需要抛出异常
throw new RuntimeException("我抛出的:"+e);
}finally{
MybatisUtil.closeSession();
}
System.out.println("方法执行结束...");
return result;
}
}
配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="dbUserDao" class="com.obtk.dao.DbUserDaoImpl"></bean>
<bean id="userServ" class="com.obtk.service.UserService" p:userDao-ref="dbUserDao">
</bean>
<bean id="beforeAdvise" class="com.obtk.advise.LoggerBefore"></bean>
<bean id="afterAdvise" class="com.obtk.advise.LoggerAfter"></bean>
<bean id="throwAdvise" class="com.obtk.advise.ExceptionAdvise"></bean>
<aop:config>
<aop:pointcut id="myCut" expression="execution(* com.obtk.dao.*.*(..))" />
<aop:advisor advice-ref="beforeAdvise" pointcut-ref="myCut"/>
<aop:advisor advice-ref="afterAdvise" pointcut-ref="myCut"/>
<aop:advisor advice-ref="throwAdvise" pointcut-ref="myCut"/>
</aop:config>
</beans>
三 环绕增强
环绕增强在目标方法的前后都可以织入增强处理。环绕增强是功能最强大的增强处理,Spring把目标方法的控制权全部交给了它。在环绕增强处理中,可以获取或修改目标方法的参数、返回值,可以对它进行异常处理,甚至可以决定目标方法是否执行。
环绕增强代码package com.obtk.advise;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
public class AroundAdvise implements MethodInterceptor {
private static final Logger log=Logger.getLogger(AroundAdvise.class);
public Object invoke(MethodInvocation arg0) throws Throwable {
Object target=arg0.getThis(); //获取被代理的类的对象
Method method=arg0.getMethod(); //获得要切入的方法
Object[] args=arg0.getArguments(); //获得参数列表
log.info("之前:调用了"+target+"的"+method.getName()+"方法,方法的入参是:" +
Arrays.toString(args));
Object result=null;
try {
result=arg0.proceed(); //执行save方法
log.info("之后:调用了"+target+"的方法:"+method.getName()+",方法参数:"
+Arrays.toString(args)+",返回值:"+result);
} catch (Exception e) {
log.info("发生了异常:调用"+target+"的方法"+method.getName()+"发生了异常==>\n"+e);
}
return result;
}
}
切入的方法
package com.obtk.dao;
import org.apache.ibatis.session.SqlSession;
import com.obtk.entitys.UsersEntity;
import com.obtk.utils.MybatisUtil;
public class DbUserDaoImpl implements UserDao{
public int save(UsersEntity user) {
System.out.println("方法执行开始...");
int result=0;
SqlSession session=null;
try {
session=MybatisUtil.getSession();
result=session.insert("user.save", user);
session.commit();
} catch (Exception e) {
session.rollback();
//要使异常抛出增强代码生效,需要抛出异常
throw new RuntimeException("我抛出的:"+e);
}finally{
MybatisUtil.closeSession();
}
System.out.println("方法执行结束...");
return result;
}
}
配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="dbUserDao" class="com.obtk.dao.DbUserDaoImpl"></bean>
<bean id="userServ" class="com.obtk.service.UserService" p:userDao-ref="dbUserDao">
</bean>
<bean id="aroundAdvise" class="com.obtk.advise.AroundAdvise"></bean>
<aop:config>
<aop:pointcut id="myCut" expression="execution(* com.obtk.dao.*.*(..))" />
<aop:advisor advice-ref="aroundAdvise" pointcut-ref="myCut"/>
</aop:config>
</beans>