Java动态代理

来源:互联网 发布:罗马斗兽场 知乎 编辑:程序博客网 时间:2024/06/06 03:04

装饰器设计模式 解决单继承的问题

代理模式


  • 概念

静态代理需要被代理类,代理类,接口
将被代理类包一层
一个被代理的类和接口
代理类实现该接口并且包含被代理类
代理类在被代理的方法上进行扩展
//接口interface 新娘{    void 洞房();}//被代理类class 马蓉 implements 新娘{   @Override   public void 洞房(){        输出一条信息   }}//代理类class 王宝强 implements 新娘{    private Object obj;//必须是实现了新娘的类    public 王宝强(Object obj){        this.obj = obj;    }    @Override    public void 洞房(){        先拜堂;        obj.洞房();   }}//调用代理者class 客户端{    main(){      马蓉 小马蓉 =  new 马蓉();(生成出一个被代理的类)      王宝强 小王宝强 =  new 王宝强(小马蓉);(将代理者生存出来,此时要将代理者传入)      小王宝强.洞房();    }}


  • 缺点

要代理的类必须实现一个接口
要代理的类中的方法必须要在接口中才能被调用

Java动态代理模式


  • 一个接口InvocationHandler和一个类Proxy

被代理对象,接口,代理对象
实现方法 public Object invoke(Object proxy, Method method, Object[] args);
Object proxy被代理类的接口
method 被代理类的方法
方法的参数
调用被代理类的方法通过代理类来调用
public interface Subject {    void rent();    void hello(String world);}public class RealSubject implements Subject{    @Override    public void rent() {        System.out.println("我是rent方法");        }    @Override    public void hello(String world) {        System.out.println("我是hello方法"+world);       } }public class DynamicProxy implements InvocationHandler{    private Object subject;    public DynamicProxy(Object subject) {        this.subject = subject;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println(subject.getClass().getName());        System.out.println("我正在执行");        method.invoke(subject, args);        System.out.println("我执行完毕");        return null;    }  }public class Client {       public static void main(String[] args) throws Exception {        RealSubject realSubject = new RealSubject();        InvocationHandler dynamicProxy = new DynamicProxy(realSubject);        Subject newProxyInstance = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),                realSubject.getClass().getInterfaces(), dynamicProxy);        newProxyInstance.rent();        newProxyInstance.hello("大家好");    }}


  • 接口可以代理自己

不用实现类就实现方法
public interface Subject {    void rent();    void hello(String world);}public class Real implements InvocationHandler{    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        //在这里对方法进行拦截,和处理        //调用方法        //处理结果或者进行其它操作        System.out.println("haha");        return null;    }}public class Client {    public static void main(String[] args) {        Real real = new Real();        Subject object = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(), new Class<?>[]{Subject.class}, real);        object.rent();    }}


  • 缺陷

接口,被代理者的方法必须添加至接口

Cglib 实现无接口的类的动态代理


  • 入口

代理类实现MethodInterceptor
Enhancer类的setSuperclass(被代理者)
setCallback(代理类)
返回enhancer.create();
调用invoke方法