当前位置:首页 > CN2资讯 > 正文内容

动态代理 (JDK代理)

3天前CN2资讯


1、动态代理用到的类和方法

动态代理涉及到的类是java.lang.reflect.Proxy,主要是用到它的newProxyInstance方法。

public class Proxy implements java.io.Serializable {     /** prefix for all proxy class names */     private final static String proxyClassNamePrefix = "$Proxy";    /**      * Returns an instance of a proxy class for the specified interfaces      * that dispatches method invocations to the specified invocation      * handler.  This method is equivalent to:      * <pre>      *     Proxy.getProxyClass(loader, interfaces).      *         getConstructor(new Class[] { InvocationHandler.class }).      *         newInstance(new Object[] { handler });      * </pre>      *      * <p>{@code Proxy.newProxyInstance} throws      * {@code IllegalArgumentException} for the same reasons that      * {@code Proxy.getProxyClass} does.      *      * @param   loader the class loader to define the proxy class      * @param   interfaces the list of interfaces for the proxy class      *          to implement      * @param   h the invocation handler to dispatch method invocations to      * @return  a proxy instance with the specified invocation handler of a      *          proxy class that is defined by the specified class loader      *          and that implements the specified interfaces      * @throws  IllegalArgumentException if any of the restrictions on the      *          parameters that may be passed to {@code getProxyClass}      *          are violated      * @throws  NullPointerException if the {@code interfaces} array      *          argument or any of its elements are {@code null}, or      *          if the invocation handler, {@code h}, is      *          {@code null}      */     @CallerSensitive     public static Object newProxyInstance(ClassLoader loader,                                           Class<?>[] interfaces,                                           InvocationHandler h)         throws IllegalArgumentException     {         if (h == null) {             throw new NullPointerException();         }         final SecurityManager sm = System.getSecurityManager();         if (sm != null) {             checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);         }         /*          * Look up or generate the designated proxy class.          */         Class<?> cl = getProxyClass0(loader, interfaces);         /*          * Invoke its constructor with the designated invocation handler.          */         try {             final Constructor<?> cons = cl.getConstructor(constructorParams);             final InvocationHandler ih = h;             if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {                 // create proxy instance with doPrivilege as the proxy class may                 // implement non-public interfaces that requires a special permission                 return AccessController.doPrivileged(new PrivilegedAction<Object>() {                     public Object run() {                         return newInstance(cons, ih);                     }                 });             } else {                 return newInstance(cons, ih);             }         } catch (NoSuchMethodException e) {             throw new InternalError(e.toString());         }     } }


2、动态代理涉及到几个概念

动态代理涉及到几个概念:Proxy、proxy class、proxy interface、proxy instance、InvocationHandler、target class、target instance。


示例:明星-->经纪人,经纪人是明星的代理。


target class是我们的原始类型,target instance是target class的实例。


proxy class是代理类,proxy instance是proxy class的实例。


proxy interface是proxy class实现的接口。


proxy instance是target instance的代理类的实例。在使用动态代理时,我们原有的对象是target instance,真正使用的对象是proxy instance。


当调用proxy instance实例上的method时(注意,这些method是定义在proxy interface接口上的),会调用InvocationHandler的invoke方法。在invoke方法内,对原来的target instance的方法进行扩展。


注意:target class必须实现接口。




java.lang.reflect.Proxy类提供了创建proxy classes和proxy instance的方法。java.lang.reflect.Proxy类是所有proxy classes的子类。


【Proxy与proxy class和proxy instance的关系】

Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods. 


【proxy class】

A dynamic proxy class (simply referred to as a proxy class below) is a class that implements a list of interfaces specified at runtime when the class is created, with behavior as described below.


【proxy interface和proxy class的关系】

A proxy interface is such an interface that is implemented by a proxy class.


【proxy instance和proxy class的关系】

A proxy instance is an instance of a proxy class.


【proxy instance和invocation handler的关系】

Each proxy instance has an associated invocation handler object, which implements the interface InvocationHandler.


【proxy interface是proxy class的接口,proxy instance是proxy class的实例。当调用proxy instance的某个proxy interface的method时,会执行InvocationHandler的invoke方法。】

A method invocation on a proxy instance through one of its proxy interfaces will be dispatched to the invoke method of the instance's invocation handler, passing the proxy instance, a java.lang.reflect.Method object identifying the method that was invoked, and an array of type Object containing the arguments. 


3、示例代码

To create a proxy for some interface Foo: 

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

or more simply: 

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


下面是newProxyInstance方法的参数

    public static Object newProxyInstance(ClassLoader loader,                                           Class<?>[] interfaces,                                           InvocationHandler h)


假设我们正在使用一个(实现了某个接口的)实例target

loader: target.getClass().getClassLoader()

interfaces: target.getClass().getInterfaces()


假设我们正在使用一个接口Foo

loader: Foo.class.getClassLoader()

interfaces: new Class[] {Foo.class}


public void test() { final UserDao target = new UserDao(); Class<?>[] interfaces = target.getClass().getInterfaces(); IPlay proxy = (IPlay) Proxy.newProxyInstance( target.getClass().getClassLoader(),  new Class[]{IFly.class},  //target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("hello--begin"); Object result = method.invoke(target, args); System.out.println("hello--end"); return result; } }); proxy.play(); System.out.println("------------------------------"); IFly dao = (IFly)proxy; dao.fly(); System.out.println("------------------------------"); ISwim dao2 = (ISwim)proxy; dao2.swim(); }









    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/23888.html

    分享给朋友:

    “动态代理 (JDK代理)” 的相关文章

    中国电信CN2网络费用解析:高效稳定,助力全球互联

    在全球化快速发展的今天,企业对国际网络的需求日益增长。无论是跨国企业的数据传输、海外分支机构的互联,还是个人用户对高质量国际带宽的需求,中国电信CN2网络凭借其卓越的性能和稳定的连接,成为了用户的首选。随着需求的增加,用户对CN2网络的费用结构也愈发关注。本文将深入解析中国电信CN2网络的费用体系,...

    国内VPS安装Docker的详细步骤与优化技巧

    在决定开始安装Docker之前,首先需要为你的国内VPS做好一些准备工作。准备工作不仅可以帮助我们顺利完成Docker的安装,还能让过程更加高效。 首先,选择一个适合的VPS服务提供商至关重要。目前市场上有很多VPS服务商,例如阿里云、腾讯云、Linode等。在选择时,可以根据自己的需求考虑价格、性...

    国外常用ping工具及其使用方法

    ping工具在国外的应用 什么是ping工具?其基本功能和重要性 ping工具是一种非常实用的网络诊断工具,通过向指定的IP地址发送数据包来检测网络连接的质量。当我们在互联网上进行访问时,ping工具能够帮助我们了解网络延迟、丢包率等关键指标。这些信息对于网站运营者和普通用户来说都是极其重要的,因为...

    水牛VPS:高性能虚拟专用服务器的最佳选择与比较

    水牛城VPS,顾名思义,是在美国纽约州布法罗市托管的虚拟专用服务器。这种服务器因其独特的地理位置和优越的技术配置,吸引了众多用户,特别是需要高性能和灵活性的网站和应用程序。这类服务的定义非常简单,但其特点却非常丰富。通常来说,水牛城VPS提供了良好的网络带宽、灵活的存储选项,以及能够根据用户需求进行...

    如何开启BBR查询并提升TCP网络性能

    BBR(Bottleneck Bandwidth and Round-trip propagation time)是一种由Google开发的TCP拥塞控制算法,我对它的了解让我感到非常兴奋。BBR旨在通过精确的网络条件监测,以提高传输速度和稳定性。传统的拥塞控制算法往往依赖于丢包率的变化来调整传输速...

    BuyVM色情网站托管服务解析 - 提升成人内容运营安全与效率

    什么是BuyVM色情服务 当我提到BuyVM的时候,可能很多人对这个名字还不太熟悉。简单来说,BuyVM是一家提供虚拟专用服务器(VPS)和网站托管服务的公司,专注于各种类型的内容,包括成人色情内容。它的历史可以追溯到多个年份前,BuyVM在业内逐渐赢得了声誉,成为不少成人网站的首选托管平台。以其可...