企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
在 Spring 中 AOP 可以使用 JDK 动态代理或 CGLIB 动态代理来实现,如果目标对象是接口,则默认采用 JDK 动态代理,否则使用 CGLIB 代理。 ```java // 基于接口实现的代理为JDK动态代理 public interface UserService{...} public class UserServiceImpl implements UserService{...} // 基于类实现的代理为CGLIB动态代理 public abstract class UserService{ ... } public UserServiceImpl extends UserService{...} ``` [TOC] # 1. JDK动态代理实现 案例源码:https://gitee.com/flymini/codes03/tree/master/learn-springaop01 **** **1. 创建一个接口** ```java public interface UserService { void printUsername(); } ``` **2. 实现接口** ```java public class UserServiceImpl implements UserService { @Override public void printUsername() { System.out.println("[printUsername]"); } } ``` **3. 创建代理对象** ```java public class JDKDynamicProxyHandler implements InvocationHandler { private Object obj; public JDKDynamicProxyHandler(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() + "方法之前执行."); //执行目标方法 Object res = method.invoke(obj, args); System.out.println(method.getName() + "方法之后执行."); System.out.println("\n被代理对象:" + obj); return res; } } ``` **4. 测试** ```java public class UserTest { /** * 写法一 */ @Test public void textProxy1() { Class[] interfaces = {UserService.class}; UserServiceImpl userServiceImpl = new UserServiceImpl(); //通过代理创建UserService接口的一个对象 UserService userService = (UserService) Proxy.newProxyInstance(UserTest.class.getClassLoader(), interfaces, new JDKDynamicProxyHandler(userServiceImpl)); userService.printUsername(); } /** * 写法二 */ @Test public void testProxy2() { Class[] interfaces = {UserService.class}; UserServiceImpl userServiceImpl = new UserServiceImpl(); UserService userService = (UserService) Proxy.newProxyInstance(UserTest.class.getClassLoader() , interfaces, (proxy, method, args) -> { System.out.println(method.getName() + "方法之前执行."); //执行目标方法 Object res = method.invoke(userServiceImpl, args); System.out.println(method.getName() + "方法之后执行."); System.out.println("\n被代理对象:" + userServiceImpl); return res; }); userService.printUsername(); } } ``` ``` /**** 控制台输出的顺序如下 ****/ printUsername方法之前执行. [printUsername] printUsername方法之后执行. 被代理对象:learn.springaop01.service.impl.UserServiceImpl@d7b1517 ``` <br/> 结论:通过代理可以选择在执行目标方法之前或之后做我们想要的逻辑处理,相当于在目标方法的前面或后面插了一脚,实现了切面编程思想。