Aop 执行方式 用到一个 责任链设计模式和递归调用 具体通过一个demo来说明
1:定义执行器接口
public interface MethodInvocation {
//执行方法
void process() throws InvocationTargetException, IllegalAccessException;
}
2:实现该接口 做具体操作
public class DefaultMethodInvocation implements MethodInvocation {
//list 中装入 相关切入点执行类
private List<MethodInterceptor> list;
private Object target;//目标对象
private Method method;//目标方法
private Object args[];//目标参数
public DefaultMethodInvocation(List<MethodInterceptor> list, Object target, Method method, Object[] args) {
this.list = list;
this.target = target;
this.method = method;
this.args = args;
}
// 切入点方法执行到那一步的指针
private int index;
//执行方法 递归方法
public void process() throws InvocationTargetException, IllegalAccessException {
//在后置方法之前执行 目标方法
if (index == list.size()) {
//调用目标方法
method.invoke(target, args);
return;
}
//通过递归调用 获取 切入点 类
MethodInterceptor methodInterceptor = list.get(index++);
//执行 切入点方法
methodInterceptor.invoke(this);
}
}
3:定义需要执行切入的拦截器接口
public interface MethodInterceptor {
//aop 切入点方法调用
void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException;
}
4:各个拦截器实现该接口
public class BeforeMethodInterceptor implements MethodInterceptor {
@Override
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
System.out.println("前置拦截器");
//通过执行器 执行递归方法
methodInvocation.process();
}
}
public class AfterMethodInterceptor implements MethodInterceptor {
@Override
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
//通过执行器 执行递归方法
methodInvocation.process();
System.out.println("后置拦截器");
}
}
public class AroundMethodInterceptor implements MethodInterceptor {
@Override
public void invoke(MethodInvocation methodInvocation) throws InvocationTargetException, IllegalAccessException {
System.out.println("环绕通知在目标方法之前执行");
//通过执行器 执行递归方法
methodInvocation.process();
System.out.println("环绕通知在目标方法之后执行");
}
}
5:测试
public class Test001 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//放入需要执行的切入类
List<MethodInterceptor> list = new ArrayList<>();
list.add(new BeforeMethodInterceptor());
list.add(new AfterMethodInterceptor());
list.add(new AroundMethodInterceptor());
//需要被切入的目标类
UserService userService = new UserService();
//需要被切入的方法
Method login = userService.getClass().getMethod("login");
//获取执行器 传入 执行切入的类 以及目标类 方法 参数
DefaultMethodInvocation methodExecution = new DefaultMethodInvocation(list, userService, login, null);
//执行器 进行执行方法
methodExecution.process();
}
}
6:总结
总的来的就是执行器定义一个公共方法 ,通过各个执行切入类中 递归调用方法 来选择 该哪个执行切入的类进行调用 从而实现 前置 后置 环绕 方法的执行。