SpringAOP之多切⾯运⾏顺序
多切⾯运⾏顺序
当⼀个⽅法的执⾏被多个切⾯共同切的时候,环绕通知只影响当前切⾯的通知顺序,例如创建两个切⾯logUtil,validateUtil两个切⾯共同监视计算器类的加法运算,add(int a,int b);测试中,看切⾯⼯具类的名称⾸字母,默认情况下a-z执⾏顺序,所以这个时候logUtil切⾯通知⽐validateUtil先执⾏通知;
所以顺序是:L的前置通知 -->v的前置通知–>执⾏add⽅法,然后v的后置通知–>V的后置返回–>L的后置通知–>L的后置返回。
但是当logUtil中加⼊了环绕通知,所以环绕通知要⽐logUtil的普通通知先执⾏,环绕通知功能很强⼤,在通过反射执⾏⽅法的前⾯我们可以更改这个⽅法的参数,但是普通通知不能这么做。虽然在logUtil加了环绕通知,但是这个环绕通知只是⽐logUtil的普通通知先执⾏⽆论是进⼊切⾯前还是出切⾯时,他并不影响validateUtil这个切⾯的普通通知的执⾏顺序,所以加了环绕通知执⾏顺序是
环绕前置–> log前置–>va前置–>⽬标⽅法–>va后置–>va返回–>环绕返回通知–>环绕后置–>log后置–>log返回。
图:
这⾥的validate切⾯就是图中的VaAspect;
对啦,可以更改默认的切⾯顺序,要在将要更改的切⾯类上加⼊@order(int value)注解,value默认值很⼤,超级⼤,越⼤执⾏的优先级越低,所以如果把它调成1就是先执⾏这个切⾯的通知。
AOP的应⽤场景:
1. aop可以进⾏⽇志记录;
2. aop可以做权限验证
3. AOP可以做安全检查
4. AOP可以做事务控制
回忆基于注解的AOC配置
将⽬标类和切⾯类都加⼊到IOC容器中。@Component
告诉Spring哪个是切⾯类@Aspect
在切⾯类中使⽤五个通知注解来配置切⾯中的这些⽅法都什么时候在那运⾏
开启注解的aop功能。
不使⽤注解实现AOP配置。spring aop应用场景
1.切⾯类
public class LogUtil {
public void performance(){}
public void logStart(JoinPoint joinPoint)
{
//获取⽅法上的参数列表
Object[] args = Args();
//获取⽅法签名
Signature signature = Signature();
String name = Name();//获取⽅法名
System.out.println("前置通知:"+name+" ⽅法开始执⾏了....参数是:"+ Arrays.asList(args)+""); }
public void logReturn(JoinPoint point,Object result)
{
String name = Signature().getName();
Object[] args = Args();
System.out.println("返回通知: "+name+"⽅法正常执⾏,返回结果是:"+result+"");
}
public void logException(JoinPoint point,Exception e)
{
String name = Signature().getName();
System.out.println("异常通知:"+name+" ⽅法出现了异常,异常是 "+e+"...");
}
public void logEnd(JoinPoint joinPoint)
{
String name = Signature().getName();
System.out.println("后置通知:"+name+"⽅法结束了");
}
//环绕通知
public Object myAround(ProceedingJoinPoint proceedingJoinPoint){
Object proceed = null;
//获取⽅法名
String name = Signature().getName();
//获取执⾏⽅法的参数列表
Object[] args = Args();
try{
System.out.println("环绕前置通知:"+name+"⽅法开始执⾏了,参数是"+Arrays.asList(args)+"");
//等于 method.invoke();通过反射执⾏指定⽅法
proceed = proceedingJoinPoint.proceed();
System.out.println("环绕返回通知:"+name+"⽅法返回结果是"+proceed+";");
}catch(Throwable throwable){
System.out.println("环绕异常通知:异常是"+throwable+"");
throwable.printStackTrace();
}finally{
System.out.println("环绕后置通知:"+name+"⽅法结束了");
}
return proceed;
}
2.被切⼊的类(这⾥是⼀个计算器类)
package main.java.zixue.domain;public class MyCalculator
{
public int add(int a,int b)
{
return a+b;
}
public int sub(int a,int b)
{
return a-b;
}
public int mul(int a,int b)
{
return a*b;
}
public int dev(int a,int b)
{
return a/b;
}
public double add(double a,float b,int c)
{
return a+b+c;
}
}
3.配置⽂件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"
xmlns:aop="/schema/aop"
xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd www./schema/context /schema/context/spring-context.xsd
/schema/aop w /schema/aop/spring-aop.xsd">
<context:component-scan base-package="main.java"></context:component-scan>
<bean id="myCalculator"class="main.java.zixue.domain.MyCalculator"></bean>
<bean id="logUtil"class="main.java.zixue.utils.LogUtil"></bean>
<!--AOP名称空间-->
<aop:config>
<!--制定切⾯的⽅法-->
<aop:pointcut id="performance" expression="execution(public * main.java.zixue.domain.MyCalculator.*(..))"></aop:pointcut>
<!--指定切⾯-->
<aop:aspect ref="logUtil">
<aop:after method="logEnd" pointcut-ref="performance"></aop:after>
<aop:before method="logStart" pointcut-ref="performance"></aop:before>
<aop:after-returning method="logReturn" pointcut-ref="performance" returning="result"></aop:after-returning>
<aop:after-throwing method="logException" pointcut-ref="performance" throwing="e"></aop:after-throwing>
<aop:around method="myAround" pointcut-ref="performance"></aop:around>
</aop:aspect>
</aop:config>
</beans>
4.测试结果
@Test
public void Test02()
{
MyCalculator myCalculator =(MyCalculator) Bean("myCalculator");
myCalculator.add(1,10);
System.out.println("========================");
}
前置通知:add ⽅法开始执⾏了…参数是:[1, 10]
环绕前置通知:add⽅法开始执⾏了,参数是[1, 10]
环绕返回通知:add⽅法返回结果是11;
环绕后置通知:add⽅法结束了
返回通知: add⽅法正常执⾏,返回结果是:11
后置通知:add⽅法结束了
====================**
普通前置通知->环绕通知->环绕返回->环绕后置->普通返回->普通后置
注解和配置⽂件在什么时候使⽤?该如何选择?
注解的优点:配置快速简洁。
配置⽂件的优点:功能丰富,注解有的他都可以实现,注解没有的他也有。
当遇到重要的切⾯时,⽤配置⽂件写,例如权限验证及管理。对于常⽤的普通的切⾯就⽤注解。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。