AOP的动态代理技术
JDK代理
接口Target: public interface Target { void targetMethod(); } |
接口实现类TargetImpl: public class TargetImpl implements Target { @Override public void targetMethod() { System.out.println("我是目标方法..."); } } |
增强的切面Aspect: public class Aspect { public void PreEnhance(){ System.out.println("我是前置增强..."); } public void PostEnhance(){ System.out.println("我是后置增强..."); } } |
JDKProxy获取代理类: public class JDKProxy implements InvocationHandler { //定义切面 Aspect aspect=new Aspect(); //定义一个目标类的实现接口 private Target target; public Object createJDKProxy(Target target){ //target进行绑定 this.target=target; //获取target实现类的类加载器 ClassLoader classLoader = target.getClass().getClassLoader(); //获取target实现类的接口 Class<?>[] interfaces = target.getClass().getInterfaces(); //创建jdk代理,this代表当前的invocationHandler对象 Target proxyTarget = (Target) Proxy.newProxyInstance(classLoader, interfaces, this); return proxyTarget; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用aspect前置增强 aspect.PreEnhance(); //待增强的方法,target为目标类的实现接口 Object invoke = method.invoke(target, args); //调用aspect后置增强 aspect.PostEnhance(); return invoke; } } |
创建JDKTest测试类: public class JDKTest { public static void main(String[] args) { JDKProxy jdkProxy = new JDKProxy(); Target target=new TargetImpl(); Target targetProxy = (Target) jdkProxy.createJDKProxy(target); targetProxy.targetMethod(); } } |
Cglib动态代理
导入Cglib依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.3.22</version> </dependency> |
增强的切面Advice public class Advice { public void before(){ System.out.println("我是一个前置增强..."); } public void after(){ System.out.println("我是一个后置增强"); } } |
需要增强的类 public class TargetCglib { public void save(){ System.out.println("我是cglib切面..."); } } |
CglibProxy代理创建类 public class CglibProxy implements MethodInterceptor { //实例化Advice static Advice advice=new Advice(); //定义需要增强的类 TargetCglib targetCglib; public Object createCglibProxy(TargetCglib targetCglib){ //传入的targetCglib与类中的进行绑定 this.targetCglib=targetCglib; //创建增强器 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(TargetCglib.class); enhancer.setCallback(this); //enhancer调用create创建cglib目标代理对象并返回 return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //前置增强 advice.PreEnhance(); //待增强的目标 Object invoke = method.invoke(targetCglib, objects); //后置增强 advice.PostEnhance(); return invoke; } } |
测试Cglib代理类 public class CglibTest { public static void main(String[] args) { CglibProxy cglibProxy = new CglibProxy(); TargetCglib targetCglib = new TargetCglib(); TargetCglib cglibTarget = (TargetCglib) cglibProxy.createCglibProxy(targetCglib); cglibTarget.cglibMethod(); } } |
总结与对比
重要区别:jdk代理必须含有接口,cglib可以不用有接口,也可以有
jdk代理:基于接口的动态代理技术,jdk自带,反射机制
cglib代理:基于父类的动态代理技术,第三方jar包,fastClass机制