Spring AOP 四大通知
Spring 3.X 以前
1.前置通知,实现 MethodBeforeAdvice 接口,重写
public void before(Method method, Object[] args, Object target) throws Throwable方法
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class TestMethodBeforeAdvice implements MethodBeforeAdvice {
/** arg0 方法
* arg1 参数
* arg2 操作对象
* */
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("前置通知:----》方法:"+arg0.getName()+"传入参数"+arg1+"操作象"+arg2);
}
}
2.后置通知,实现 AfterReturningAdvice 接口,重写
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable 方法
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class TestAfterReturningAdvice implements AfterReturningAdvice{
/**
* arg0:return 的返回值
* arg1:执行的方法对象
* arg2:方法执行中传递过来的参数
* arg3:执行方法的对象
*/
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("后置通知:----》方法:"+arg1.getName()+"返回值:"+arg0+"执行方对象:"+arg3);
}
}
3.环绕通知, 实现 MethodInterceptor 接口,重写
public Object invoke(MethodInvocation invocation) throws Throwable 方法
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class TestMethodinterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod() ; //方法
Object[] objs = invocation.getArguments() ; //参数
Object obj = invocation.getThis() ; //操作对象
System.out.println("环绕通知:-----》 开始: 方法:"+method.getName()+"传入的参数:"+objs+" 操作对象:"+obj);
Object result = invocation.proceed() ; //放行
System.out.println("环绕通知:-----》 结束: 返回值:"+result);
return result ;
}
}
4.异常通知,实现 ThrowsAdvice 接口,重写
public void afterThrowing(Method m, Object args, Object target,Throwable e) 方法
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class TestThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Method m, Object args, Object target, Throwable e) {
System.out.println("异常通知:方法"+m.getName()+"发生异常,"+e.getMessage());
System.exit(0);
}
}
注意:查看ThrowsAdvice源码会发现这个接口里面没有定义方法,但是这个方法必须这么写,
Spring 3.X 以后版本
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class TestAdvice {
public void before(JoinPoint joinPoint){ //前置通知
System.out.println("操作者"+joinPoint.getTarget()+"参数 "+joinPoint.getArgs()[0]);
System.out.println("*********************前置通知*********************");
}
//后置通知:当方法执行完会触发,出错则不执行
public void afterReturning(JoinPoint joinPoint,Object obj){
System.out.println("后置通知");
System.out.println("返回结果:"+obj);
}
//最终通知
public void after(JoinPoint joinPoint){
System.out.println("最终通知");
System.out.println("调用的方法"+joinPoint.getSignature());
}
//异常通知
public void throwAdvice(Exception exception){
System.out.println("--------异常通知--------");
System.out.println("异常消息"+exception.getMessage());
}
//环绕通知
public Object around(ProceedingJoinPoint proceedingJoinPoint){
System.out.println("环绕通知开始");
try {
Object obj = proceedingJoinPoint.proceed() ;
System.out.println("环绕通知结束");
return obj ;
} catch (Throwable e) {
e.printStackTrace();
}
return null ;
}
}
配置信息
<!--Spring3.X以前-->
<!--后置通知-->
<bean id="afterAdvice" class="com.spring.advice.TestAfterReturningAdvice"/>
<!--前置通知-->
<bean id="beforeAdvice" class="com.spring.advice.TestMethodBeforeAdvice"/>
<!--环绕通知-->
<bean id="interceptorAdvice" class="com.spring.advice.TestMethodinterceptor"/>
<!--异常通知-->
<bean id="throwsAdvice" class="com.spring.advice.TestThrowsAdvice"/>
<!--Spring3.X以后整合-->
<bean id="advice" class="com.spring.advice.TestAdvice"/>
<!-- AOP设置 -->
<aop:config>
<aop:pointcut expression="execution(* com.spring.service.*.*(..))" id="mycut"/>
<aop:advisor advice-ref="afterAdvice" pointcut-ref="mycut"/>
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="mycut"/>
<aop:advisor advice-ref="interceptorAdvice" pointcut-ref="mycut"/>
<aop:advisor advice-ref="throwsAdvice" pointcut-ref="mycut"/>
<!-- 新版本 -->
<aop:aspect ref="advice">
<aop:before method="before" pointcut-ref="mycut"/>
<aop:after-returning method="afterReturning" returning="obj" pointcut-ref="mycut"/>
<aop:after method="after" pointcut-ref="mycut"/>
<aop:after-throwing method="throwAdvice" throwing="exception" pointcut-ref="mycut"/>
<aop:around method="around" pointcut-ref="mycut"/>
</aop:aspect>
</aop:config>
两种方法:
Spring3.X版本以前写法思路更清晰,新版本,虽然把4个通知整合在了一起,但是,如果业务复杂的话,通知较多建议分开写,
两种方法区别不是很大,具体还得开需求
expression的value值
任意公共方法的执行:
execution(public * *(..))
任何一个以“set”开始的方法的执行:
execution(* set*(..))
AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))
定义在service包或者子包里的任意方法的执行:
execution(* com.xyz.service..*.*(..))
若要转载,请标明此处