JDK动态代理和CGLIB动态代理基本使用

一、什么是代理

代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

代理模式UML图:

image.png

二、静态代理与动态代理的区别

静态代理中的代理类是需要用户自己写的,这样代理类在程序运行前就已经存在了。
动态代理中的代理类是在程序运行中自动生成的。

三、静态代理

// 接口
public interface Fruit {
   void eat();
}

// 实现类
public class Apple implements Fruit {
   public void eat() {
       System.out.println("吃苹果");
   }
}

// 代理类
public class AppleProxy implements Fruit {
   private Apple apple;
   public AppleProxy (Apple apple) {
       this.apple = apple;
   }

   public void eat() {
       System.out.println("吃前先洗手");
       apple.eat();
       System.out.println("吃后也洗手");
   }

   public static void main(String[] args) {
       AppleProxy appleProxy = new AppleProxy(new Apple());
       appleProxy.eat();
   }
}
输出
 
吃前先洗手
吃苹果
吃后也洗手

四、JDK动态代理

// 实现类
public class Apple implements Fruit {
    @Override
    public void eat() {
        System.out.println("吃苹果");
    }
}
 
// 代理类
public class AppleProxy implements InvocationHandler {
    public Object object;
 
    public Object newProxy(Object object) {
        this.object = object;
        return Proxy.newInstance(object.getClass().getClassLoader(),     
                                 object.getClass().getInterfaces(), 
                                 this);
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        System.out.println("执行方法之前");
        result = method.invoke(object, args);
        System.out.println("执行方法之后");
        return result;
    }
 
   
}
// 客户端
public class Client {
    public static void main(String[] args) {
        AppleProxy appleProxy = new AppleProxy();
        Fruit fruitProxy = (Fruit) appleProxy.newProxy(new Apple());
        fruitProxy.eat();
    }
}
输出
执行方法之前
吃苹果
执行方法之后

JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用CGLIB动态代理了

五、CGLIB动态代理

// 接口
public interface Fruit {
    void eat();
}
 
// 实现类
public class Apple implements Fruit {
 
    public void eat() {
        System.out.println("吃苹果");
    }
}
 
// 代理类
public class AppleProxy implements MethodInterceptor {
    private Object object;
 
    public Object getInstance(Object object) {
        this.object = object;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.object.getClass());
        //回调方法
        enhancer.setCallback(this);
        //创建代理对象
        return enhancer.create();
    }
 
    public Object intercept(Object object, Method method, 
                            Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("执行方法之前");
        methodProxy.invokeSuper(object, args);
        System.out.println("执行方法之后");
        return null;
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        AppleProxy appleProxy = new AppleProxy();
        Apple apple = (Apple) appleProxy.getInstance(new Apple());
        apple.eat();
    }
}
输出
执行方法之前
吃苹果
执行方法之后
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容