用简单的代码模拟了Spring Aop的方法调用流程
主要难点在于责任链模式的执行流程,不太好跟踪代码步骤
其次,各种方法拦截器的执行方式
1 import java.lang.reflect.Method; 2 3 /** 4 * aop执行模型 5 * @author sunxueqiang 6 */ 7 public class AopInvokeModel { 8 /** 9 * 方法拦截器 10 */ 11 interface MethodInterceptor { 12 Object invoke(MethodInvocation mi) throws Throwable; 13 } 14 15 //前置拦截器:调用下一个拦截器前执行拦截逻辑 16 static MethodInterceptor before = (mi)->{ 17 System.out.println("1:----before------"); 18 return mi.proceed(); 19 }; 20 21 //环绕拦截器:调用下个拦截器前后执行环绕逻辑 22 static MethodInterceptor around = (mi)->{ 23 System.out.println("2:----around before------"); 24 Object result = mi.proceed(); 25 System.out.println("4:----around after------"); 26 return result; 27 }; 28 29 //后置拦截器:finally中执行拦截逻辑 30 static MethodInterceptor after = (mi)->{ 31 try { 32 return mi.proceed(); 33 } finally { 34 System.out.println("5:----after------"); 35 } 36 }; 37 38 //返回拦截器:如果能正常返回执行结果,随后执行拦截逻辑 39 static MethodInterceptor afterReturning = (mi)->{ 40 Object result = mi.proceed(); 41 System.out.println("6:----after returning------"); 42 return result; 43 }; 44 45 //异常拦截器:catch中执行拦截逻辑 46 static MethodInterceptor afterThrowing = (mi)->{ 47 try { 48 return mi.proceed(); 49 } catch (Exception e) { 50 System.out.println("----after throwing------"); 51 throw e; 52 } 53 }; 54 55 /** 56 * 方法执行 57 */ 58 static class MethodInvocation{ 59 //方法拦截器链 60 private MethodInterceptor[] methodInterceptors; 61 //目标对象 62 private Object target; 63 //方法 64 private Method method; 65 //拦截器链执行位置 66 private int index = 0; 67 68 public MethodInvocation(Object target,Method method,MethodInterceptor[] methodInterceptors) { 69 super(); 70 this.target = target; 71 this.method = method; 72 this.methodInterceptors = methodInterceptors; 73 } 74 75 /** 76 * 责任链模式 77 * 执行链中的下一个拦截器 78 */ 79 public Object proceed() throws Throwable { 80 if(methodInterceptors.length == index) { 81 return method.invoke(target); 82 } 83 MethodInterceptor methodInterceptor = methodInterceptors[index ++]; 84 return methodInterceptor.invoke(this); 85 } 86 } 87 88 //测试方法 89 public String testMethod() { 90 System.out.println("5:----testMethod----------"); 91 if(true) { 92 //throw new RuntimeException("--- exception ---"); 93 } 94 return "result"; 95 } 96 97 public static void main(String[] args) throws Throwable { 98 AopInvokeModel aopInvokeModel = new AopInvokeModel(); 99 Method method = aopInvokeModel.getClass().getMethod("testMethod"); 100 MethodInterceptor[] methodInterceptors = new MethodInterceptor[] { 101 afterReturning, afterThrowing, before, after, around, 102 };//定义拦截器链 103 MethodInvocation mi = new MethodInvocation(aopInvokeModel, method, methodInterceptors); 104 Object result = mi.proceed(); 105 System.out.println(result); 106 } 107 108 }
执行结果:
1:----before------
2:----around before------
5:----testMethod----------
4:----around after------
5:----after------
6:----after returning------
result