下面我们来深度解析AOP的底层原理,并且带有源码示例。
- JDK动态代理实现AOP:JDK动态代理基于接口,要求目标对象实现一个接口。它使用Java的反射机制在运行时动态创建代理对象。JDK动态代理主要涉及以下几个类和接口:
- InvocationHandler(接口):定义了一个invoke方法,它是实际代理逻辑的入口。
- Proxy(类):提供了创建代理对象的静态方法,它会生成一个代理类的字节码,并通过反射机制创建代理对象。
下面是一个使用JDK动态代理实现AOP的示例代码:
// 定义一个接口 public interface UserService { void save(); } // 实现接口的目标对象 public class UserServiceImpl implements UserService { @Override public void save() { System.out.println("保存用户信息"); } } // 自定义InvocationHandler public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开始事务"); Object result = method.invoke(target, args); System.out.println("提交事务"); return result; } } // 使用JDK动态代理 public class Main { public static void main(String[] args) { UserService userService = new UserServiceImpl(); MyInvocationHandler invocationHandler = new MyInvocationHandler(userService); UserService proxy = (UserService) Proxy.newProxyInstance( userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), invocationHandler); proxy.save(); } }
在上面的示例中,我们定义了一个UserService接口和一个UserServiceImpl类作为目标对象,然后通过自定义MyInvocationHandler类来实现代理逻辑。在invoke方法中,我们可以添加额外的横切逻辑,比如开始事务和提交事务。
- CGLIB动态代理实现AOP:CGLIB(Code Generation Library)是一个基于字节码生成的库,可以代理没有实现接口的类。CGLIB动态代理通过继承的方式来创建代理对象,并重写目标对象的方法。CGLIB动态代理主要涉及以下几个类:
- MethodInterceptor(接口):定义了一个intercept方法,它是实际代理逻辑的入口。
- Enhancer(类):提供了创建代理对象的静态方法,它会生成一个代理类的字节码,并通过字节码增强技术创建代理对象。
下面是一个使用CGLIB动态代理实现AOP的示例代码:
// 目标对象 public class UserService { public void save() { System.out.println("保存用户信息"); } } // 自定义MethodInterceptor public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("开始事务"); Object result = proxy.invokeSuper(obj, args); System.out.println("提交事务"); return result; } } // 使用CGLIB动态代理 public class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserService.class); enhancer.setCallback(new MyMethodInterceptor()); UserService proxy = (UserService) enhancer.create(); proxy.save(); } }
在上面的示例中,我们创建了一个UserService类作为目标对象,然后通过自定义MyMethodInterceptor类来实现代理逻辑。在intercept方法中,我们可以添加额外的横切逻辑,比如开始事务和提交事务。
总结:JDK动态代理和CGLIB动态代理是两种常见的实现AOP的方式。选择使用哪种方式应根据具体需求和场景来决定。如果目标对象实现了接口,可以使用JDK动态代理;如果目标对象没有实现接口,可以使用CGLIB动态代理。