🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 1. AOP原理 1. 将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决,如常用的日志、事务管理、权限管理等。 2. 采用代理机制组装成起来运行,在不改变原程序的基础上对代码进行增强处理,添加新的功能。 在 Spring 中 AOP 代理使用 JDK 动态代理或 CGLIB 动态代理来实现,如果目标对象是接口,则默认采用JDK 动态代理,否则使用 CGLIB 代理。 (1)JDK动态代理 ```java // 基于接口实现的代理为JDK动态代理 public interface UserDao {...} public class UserDaoImpl implements UserDao {...} ``` (2)CGLIB动态代理 ```java // 基于类实现的代理为CGLIB动态代理 public class People{ ... } public Persion extends People{...} ``` <br/> # 2. JDK动态代理演示 案例代码:https://gitee.com/flymini/codes01/tree/master/spring_/com-learn-spring05 **** 步骤如下: **1. 创建接口** ```java public interface UserDao { public int add(int a,int b); } ``` **2. 实现接口** ```java public class UserDaoImpl implements UserDao { @Override public int add(int a, int b) { return a + b; } } ``` **3. 创建代理对象** ```java public class JdkDynamicProxy implements InvocationHandler { private Object obj; public JdkDynamicProxy(Object obj) { this.obj = obj; } /** * 增强逻辑:在invoke方法中,你可以决定在被代理对象的目标方法执行之前或之后自由决定做你想要的处理。 * * @param proxy 需要被代理的对象 * @param method 当前被代理对象正在被调用的方法 * @param args 被代理对象方法的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //方法之前 System.out.println("方法之前执行:" + method.getName() + ",传递的参数:" + Arrays.toString(args)); //被增强的方法执行 Object res = method.invoke(obj, args); //方法之后 System.out.println("方法之后执行:" + obj); return res; } } ``` **4. 测试** ```java public class JdkDynamicProxyTest { /** * 写法一 */ @Test public void proxyTest1() { Class[] interfaces = {UserDao.class}; UserDaoImpl userDaoImpl = new UserDaoImpl(); //使用代理创建UserDao接口的一个对象 UserDao userDao = (UserDao) Proxy.newProxyInstance(JdkDynamicProxyTest.class.getClassLoader(), interfaces, new JdkDynamicProxy(userDaoImpl)); int result = userDao.add(1, 2); System.out.println("输出结果:" + result); } /** * 写法二 */ @Test public void proxyTest2() { Class[] interfaces = {UserDao.class}; UserDaoImpl userDaoImpl = new UserDaoImpl(); UserDao userDao = (UserDao) Proxy.newProxyInstance(JdkDynamicProxyTest.class.getClassLoader(), interfaces, (proxy, method, args) -> { //方法之前 System.out.println("方法之前执行:" + method.getName() + ",传递的参数:" + Arrays.toString(args)); //被增强的方法执行 Object res = method.invoke(userDaoImpl, args); //方法之后 System.out.println("方法之后执行:" + userDaoImpl); return res; }); int result = userDao.add(1, 2); System.out.println("输出结果:" + result); } } ``` 结果如下: ``` 方法之前执行:add,传递的参数:[1, 2] 方法之后执行:com.learn.spring05.dao.impl.UserDaoImpl@4f8e5cde 输出结果:3 ``` 执行的顺序应该如下: ``` 遇到语句 int result = userDao.add(1, 2); 但还没有执行 --> 执行 invoke 方法 --> 执行 System.out.println("方法之前执行:" + method.getName() + ",传递的参数:" + Arrays.toString(args)); --> 这个时候才执行 userDao.add方法:Object res = method.invoke(obj, args); --> 执行System.out.println("方法之后执行:" + obj); ``` 结论:通过代理可以选择在执行目标方法之前或之后做我们想要的逻辑处理,相当于在目标函数的前面或后面插了一脚,实现了切面编程思想。