动态代理

来源:互联网 发布:人工智能的现状论文 编辑:程序博客网 时间:2024/05/29 14:29

动态代理,简单说就是不用在设计实现的时候就指定某一个代理类来代理哪一个被代理的对象,可以把这种指定延迟到程序运行时有JVM来实现。它的结构图如下:

这里写图片描述

其中:
InvocationHandler:即为java.reflect.InvocationHandler接口;
AbstractSubject:抽象主题类;
RealSubject:真实主题类,即被代理的类;
DynamicProxy:动态代理类,需要实现InvocationHandler接口。
为了让DynamicProxy类能够在运行时才实现RealSubject类已经实现的一系列接口并执行接口中的方法操作,需让DynamicProxy类实现JDK自带的Java.lang.reflect.InvocationHandler接口,因为该接口中的invoke()方法能够让DynamicProxy实例在运行时调用被代理类的“对外服务”,即调用被代理类需要对外实现的所有接口中的方法,也就是完成对真实方法的调用。

代码实例如下:

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;//抽象主题类interface AbstractSubject{    public abstract void request();}//被代理的类class RealSubject implements AbstractSubject{    public void request(){        System.out.println("被代理类的请求");    }}//动态代理类class DynamicProxy implements InvocationHandler{    Object obj=null;//被代理类的实例    //将被代理类的实例传进动态代理类的构造函数中    public DynamicProxy(Object obj){        this.obj=obj;    }    //覆盖了InvocationHandler中的invoke()方法    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{        //在该方法之前,可以进行特殊代码切入的扩展点,可增强其功能;        Object result=method.invoke(this.obj, args);        return result;        //在该方法之后,可以进行特殊代码切入的扩展点,可增强其功能;    }}public class Client{    public static void main(String[] args){        // 定义一个被代理类的实例        AbstractSubject realSubject=new RealSubject();        //获取被代理类的类加载器,使得JVM能够加载并找到被代理类的内部结构,以及已经实现的interface        ClassLoader loader=realSubject.getClass().getClassLoader();        //获取被代理类已经实现的所有接口        Class<?> [] interfaces=realSubject.getClass().getInterfaces();        //用被代理类的实例创建动态代理类的实例,用于真正调用处理程序        InvocationHandler handler=new DynamicProxy(realSubject);        //获取代理类的实例,newProxyInstance()方法中的参数:loader是被代理类的类加载器;interfaces是被代理类已经实现的所有接口;handle是动态代理类实例        AbstractSubject proxy=(AbstractSubject) Proxy.newProxyInstance(loader, interfaces, handler);        proxy.request();        System.out.println(proxy.getClass().getName());                     }}//运行结果为://被代理类的请求//$Proxy0

动态代理模式可以使我们在不改变原来已有的代码结构的情况下,即不用修改源码的情况下,对原来的“真实方法”进行扩展,增强其功能,在方法执行前后增加任何想要的功能,因为在InvocationHandler的invoke方法中,可以直接获取正在调用方法所对应的Method对象,具体的应用,如可以做事物控制,添加调用日志等。并且可以达到控制被代理对象的行为。

一般创建一个动态代理对象分为4个步骤:
(1)通过实现InvocationHandler接口创建自己的调用处理器,`InvocationHandler handler=new DynamicProxy(…);
(2)通过Proxy类指定ClassLoad对象和一组interface,创建动态代理类

Class clazz=Proxy.getProxyClass(classLoader,new Class[]{...});

(3)通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口的类型:

Constructor constructor=clazz.getConstructor(new Class[]{InvocationHandler.class}); 

(4)通过构造函数创建代理类实例,此时需要将调用处理器对象作为参数传入:

Interface Proxy=(Interface)constructor.newInstance(new Object[](handler));

但是一般会进行简化,将(2)-(4)三个步骤进行封装,用到了Proxy类中的newProxyInstance()方法,正如上述程序中所实现的。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝物流把货弄丢了怎么办 刚买的卡没激活怎么办 腾讯王卡40g用完怎么办 手机欠费不知道电话号码怎么办 手机欠费了不用了怎么办 闲鱼恶意差评怎么办 淘宝买家账户体检中心违规怎么办 淘宝卖家账户体检中心违规怎么办 淘宝好评被删除评价怎么办 淘宝没收到货确认收货了怎么办 美团评论被删怎么办 拼多多恶意差评怎么办 淘宝评论被删了怎么办 淘宝买东西错怪店家了怎么办 淘宝骗删除差评怎么办 淘宝买家号虚假交易违规怎么办 淘宝商家一直不发货怎么办 淘宝商家不发货也不退款怎么办 淘宝买家恶意差评怎么办 淘宝评价完了忘截图了怎么办 12306app登录不上怎么办 淘宝换绑支付宝失败怎么办 淘宝和手机不兼容怎么办 换号之后微信怎么办 手机不兼容的应用程序怎么办 微信版本低登录不了怎么办 软件与系统不兼容怎么办 软件与手机系统不兼容怎么办 qq和手机不兼容怎么办 来个软件不兼容怎么办 安卓8.0不兼容app怎么办 两条内存不兼容怎么办 王者荣耀软件不兼容怎么办 冒险岛不兼容win7怎么办 百度网盘手机号换了怎么办 破解版游戏闪退怎么办 安卓手机软件不兼容怎么办 安卓8.0软件闪退怎么办 游戏与手机系统不兼容怎么办 耳机和手机不兼容怎么办 软件和手机不兼容怎么办