动态代理类

动态代理类,第1张

静态代理 

 为了解决缺点 使用动态代理

jdk动态代理 使用接口

cglib  使用类

javasisit 字节码

 

 

 

动态代理类 (以下简称为代理类 )是一个实现在类创建时在运行时指定的接口列表的类,具有如下所述的行为。 代理接口是由代理类实现的接口。 代理实例是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序对象,它实现了接口InvocationHandler 。 通过其代理接口之一的代理实例上的方法调用将被分派到实例调用处理程序的invoke方法,传递代理实例, java.lang.reflect.Method被调用方法的java.lang.reflect.Method对象以及包含参数的类型Object Object的数组。 调用处理程序适当地处理编码方法调用,并且返回的结果将作为方法在代理实例上调用的结果返回。

代理类具有以下属性:

  • 代理类是公共的,最终的,而不是抽象的,如果所有代理接口都是公共的。
  • 如果任何代理接口是非公开的,代理类是非公开的,最终的,而不是抽象的 。
  • 代理类的不合格名称未指定。 然而,以字符串"$Proxy"开头的类名空间应该保留给代理类。
  • 一个代理类扩展了java.lang.reflect.Proxy 。
  • 代理类完全按照相同的顺序实现其创建时指定的接口。
  • 如果一个代理类实现一个非公共接口,那么它将被定义在与该接口相同的包中。 否则,代理类的包也是未指定的。 请注意,程序包密封不会阻止在运行时在特定程序包中成功定义代理类,并且类也不会由同一类加载器定义,并且与特定签名者具有相同的包。
  • 由于代理类实现了在其创建时指定的所有接口, getInterfaces在其对象上调用getInterfaces将返回一个包含相同列表接口的数组(按其创建时指定的顺序),在其对象上调用getMethods将返回一个数组的方法对象,其中包括这些接口中的所有方法,并调用getMethod将在代理接口中找到可以预期的方法。
  • Proxy.isProxyClass方法将返回true,如果它通过代理类 - 由Proxy.getProxyClass返回的类或由Proxy.newProxyInstance返回的对象的类 - 否则为false。
  • 所述java.security.ProtectionDomain代理类的是相同由引导类装载程序装载系统类,如java.lang.Object ,因为是由受信任的系统代码生成代理类的代码。 此保护域通常将被授予java.security.AllPermission 。
  • 每个代理类有一个公共构造一个参数,该接口的实现InvocationHandler ,设置调用处理程序的代理实例。 而不必使用反射API来访问公共构造函数,也可以通过调用Proxy.newProxyInstance方法来创建代理实例,该方法将调用Proxy.getProxyClass的 *** 作与调用处理程序一起调用构造函数。
 接口
package com.kuang.demo03;

public interface Rent {
    public void rent();
}
实现类

 

package com.kuang.demo03;

public class Host implements Rent {

    public void rent() {
        System.out.println("房东要出租房子!");
    }
}
 代理类
package com.kuang.demo03;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//等会我们会有这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
/*

    Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
            new Class[] { Foo.class },
            handler);


    //被代理的接口
*/
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //生成得到代理类
    public  Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }

    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //动态代理的本质,就是使用反射机制实现!
        seeHouse();
        Object result = method.invoke(rent, args);
        fare();
        return result;
    }

    public void seeHouse(){
        System.out.println("中介带着看房子");
    }
    public void fare(){
        System.out.println("中介收费房价一半");
    }

}
测试类
package com.kuang.demo03;

public class Client {
    public static void main(String[] args) {
        //真实角色
        Host host = new Host();

        //代理角色 : 现在没有
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //通过调用程序处理角色来处理我们要调用的接口对象!
        pih.setRent(host);

        Rent proxy = (Rent)pih.getProxy();
        proxy.rent();
    }
}
结构图和最终效果

 官方源码

public class Proxy
extends Object
implements Serializable

Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。

为某个接口创建代理Foo :

  InvocationHandler handler = new MyInvocationHandler(...);
     Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
     Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
                     newInstance(handler); 

或更简单地:

  Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler); 
方法摘要
所有方法 静态方法 具体的方法
Modifier and TypeMethod and Description
static InvocationHandlergetInvocationHandler(Object proxy)

返回指定代理实例的调用处理程序。

static 类getProxyClass(ClassLoader loader, 类... interfaces)

给出类加载器和接口数组的代理类的 java.lang.Class对象。

static booleanisProxyClass(类 cl)

如果且仅当使用 getProxyClass方法或 newProxyInstance方法将指定的类动态生成为代理类时,则返回true。

static ObjectnewProxyInstance(ClassLoader loader, 类[] interfaces, InvocationHandler h)

返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/738126.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存