当前位置: 首页 > news >正文

深入浅出wordpress下载培训机构优化

深入浅出wordpress下载,培训机构优化,成华区微信网站建设,宁波seo公司哪家好在Java开发中,JDK动态代理是一种非常有用的技术,它允许开发者在不修改目标类代码的情况下,为目标类添加额外的功能。然而,JDK动态代理的使用有一些限制,特别是它只能代理接口和接口实现类。本文将深入探讨这一限制的原…

在Java开发中,JDK动态代理是一种非常有用的技术,它允许开发者在不修改目标类代码的情况下,为目标类添加额外的功能。然而,JDK动态代理的使用有一些限制,特别是它只能代理接口和接口实现类。本文将深入探讨这一限制的原因。

1.JDK动态代理原理

下面是一个简单的动态代理的例子


/*** 要代理的接口*/
public interface Target{String say();
}/*** 真实调用对象*/
public class RealTarget {public String invoke(){return "i'm proxy";}
}/*** JDK代理类生成*/
public class JDKProxy implements InvocationHandler {private Object target;JDKProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] paramValues) {System.out.println("Before method invocation");Object result = ((RealTarget)target).invoke();System.out.println("After method invocation");return result;}
}/*** 测试例子*/
public class TestProxy {public static void main(String[] args){// 构建代理器JDKProxy proxy = new JDKProxy(new RealTarget());ClassLoader classLoader = ClassLoaderUtils.getCurrentClassLoader();// 把生成的代理类保存到文件System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles","true");// 生成代理类Target test = (Target) Proxy.newProxyInstance(classLoader, new Class[]{Target.class}, proxy);// 方法调用System.out.println(test.say());}
}

这段代码想表达的意思就是:给 Target 接口生成一个动态代理类,并调用接口 say() 方法,但真实返回的值居然是来自 RealTarget 里面的 invoke() 方法返回值。你看,短短50行的代码,就完成了这个功能,是不是还挺有意思的?

那既然重点是代理类的生成,那我们就去看下 Proxy.newProxyInstance 里面究竟发生了什么?

一起看下下面的流程图,具体代码细节你可以对照着 JDK 的源码看(上文中有类和方法,可以直接定位),我是按照 1.7.X 版本梳理的。

在生成字节码的那个地方,也就是 ProxyGenerator.generateProxyClass() 方法里面,通过代码我们可以看到,里面是用参数 saveGeneratedFiles 来控制是否把生成的字节码保存到本地磁盘。同时为了更直观地了解代理的本质,我们需要把参数 saveGeneratedFiles 设置成true,但这个参数的值是由key为“sun.misc.ProxyGenerator.saveGeneratedFiles”的Property来控制的,动态生成的类会保存在工程根目录下的 com/sun/proxy 目录里面。现在我们找到刚才生成的 $Proxy0.class,通过反编译工具打开class文件,你会看到这样的代码: 

package com.sun.proxy;import com.proxy.Hello;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;public final class $Proxy0 extends Proxy implements Target {private static Method m3;private static Method m1;private static Method m0;private static Method m2;public $Proxy0(InvocationHandler paramInvocationHandler) {super(paramInvocationHandler);}public final String say() {try {return (String)this.h.invoke(this, m3, null);} catch (Error|RuntimeException error) {throw null;} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);} }public final boolean equals(Object paramObject) {try {return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();} catch (Error|RuntimeException error) {throw null;} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);} }public final int hashCode() {try {return ((Integer)this.h.invoke(this, m0, null)).intValue();} catch (Error|RuntimeException error) {throw null;} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);} }public final String toString() {try {return (String)this.h.invoke(this, m2, null);} catch (Error|RuntimeException error) {throw null;} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);} }static {try {m3 = Class.forName("com.proxy.Target").getMethod("say", new Class[0]);m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);return;} catch (NoSuchMethodException noSuchMethodException) {throw new NoSuchMethodError(noSuchMethodException.getMessage());} catch (ClassNotFoundException classNotFoundException) {throw new NoClassDefFoundError(classNotFoundException.getMessage());} }
}

我们可以看到 $Proxy0 类里面有一个跟 Target 一样签名的 say() 方法,其中 this.h 绑定的是刚才传入的 JDKProxy 对象,所以当我们调用 Target.say() 的时候,其实它是被转发到了JDKProxy.invoke()。到这儿,整个魔术过程就透明了。 

 2.回答JDK动态代理的疑问

  1. 为何只能代理具有接口的类?
    这是因为JDK动态代理的机制所限。在Java中,动态代理通过Proxy.newProxyInstance()方法实现,此方法要求传入一个接口类作为被代理对象。这源于JDK动态代理的底层实现:它在程序运行时动态生成一个名为$Proxy0的代理类,该代理类继承自java.lang.reflect.Proxy并实现了被代理的接口。由于Java不支持多重继承,每个动态代理类都继承自Proxy,因此只能代理接口,而无法代理具体实现类。

  2. JDK动态代理能否代理类?
    JDK中的Proxy类主要用于保存动态代理的处理器InvocationHandler。理论上,如果不通过Proxy类而直接在动态生成的代理类内部设置处理器,可能实现对类的动态代理。然而,JDK的设计者并未采取这种方式,这主要是出于设计上的考虑和限制。

  3. 为何这样设计?

    • 使用场景与需求:动态代理的主要用途是在不修改原始实现的前提下,对方法进行拦截以实现功能增强或扩展。在实际开发中,基于接口编程是常见模式,因此基于接口实现动态代理符合需求和场景。当然,也存在没有实现接口的类,此时JDK动态代理无法满足需求。
    • 代码重用与扩展性:在Java中,类的设计更注重共性能力的抽象,以提高代码的重用性和扩展性。动态代理也遵循这一原则,它封装了代理类的生成逻辑、接口判断以及InvocationHandler的持有等,将这些抽象逻辑放在Proxy父类中是一个合理的选择。
  4. 其他实现方式
    对于需要代理没有接口的类,可以选择使用CGLIB动态代理。CGLIB通过动态生成被代理类的子类,并重写非final修饰的方法,在子类中拦截父类方法的调用,从而实现动态代理。这种方式弥补了JDK动态代理只能代理接口的不足。

三、总结

JDK动态代理是Java中一种强大而灵活的技术,它允许在不修改原始代码的情况下对目标对象的方法进行功能增强。然而,由于其基于接口的代理机制,它只能代理接口和接口实现类。对于需要代理没有实现接口的类的情况,可以考虑使用CGLIB动态代理等替代方案。在实际开发中,应根据具体需求选择合适的代理机制,以实现最佳的性能和可维护性。

 


文章转载自:
http://chantey.c7623.cn
http://vaporiform.c7623.cn
http://matchwood.c7623.cn
http://stipular.c7623.cn
http://konak.c7623.cn
http://hiker.c7623.cn
http://soterial.c7623.cn
http://haematose.c7623.cn
http://willem.c7623.cn
http://onside.c7623.cn
http://archaeological.c7623.cn
http://isolt.c7623.cn
http://apiary.c7623.cn
http://hagiarchy.c7623.cn
http://centime.c7623.cn
http://loup.c7623.cn
http://feeblish.c7623.cn
http://ekuele.c7623.cn
http://whippy.c7623.cn
http://lidar.c7623.cn
http://adcraft.c7623.cn
http://ecdyses.c7623.cn
http://candock.c7623.cn
http://dissolvent.c7623.cn
http://churchism.c7623.cn
http://malm.c7623.cn
http://journey.c7623.cn
http://stradivari.c7623.cn
http://azote.c7623.cn
http://dawdler.c7623.cn
http://schizogenic.c7623.cn
http://typhlosis.c7623.cn
http://pulaski.c7623.cn
http://juncaceous.c7623.cn
http://peristaltic.c7623.cn
http://originality.c7623.cn
http://amberite.c7623.cn
http://bisulphate.c7623.cn
http://rheumaticky.c7623.cn
http://glair.c7623.cn
http://dentistry.c7623.cn
http://disoblige.c7623.cn
http://geophyte.c7623.cn
http://reggeism.c7623.cn
http://intermarriage.c7623.cn
http://thereunder.c7623.cn
http://torrefaction.c7623.cn
http://unconstitutional.c7623.cn
http://tupamaro.c7623.cn
http://determinant.c7623.cn
http://zoar.c7623.cn
http://rifampin.c7623.cn
http://druggie.c7623.cn
http://britannic.c7623.cn
http://isopiestic.c7623.cn
http://glout.c7623.cn
http://bergamasca.c7623.cn
http://soleus.c7623.cn
http://concerned.c7623.cn
http://demulsification.c7623.cn
http://interlayer.c7623.cn
http://aurora.c7623.cn
http://marconi.c7623.cn
http://vermicidal.c7623.cn
http://whiffletree.c7623.cn
http://enviously.c7623.cn
http://enchanter.c7623.cn
http://moschate.c7623.cn
http://decaffeinate.c7623.cn
http://xenophobia.c7623.cn
http://drupaceous.c7623.cn
http://engraving.c7623.cn
http://screaming.c7623.cn
http://iffish.c7623.cn
http://ovoflavin.c7623.cn
http://heathery.c7623.cn
http://infiltrator.c7623.cn
http://jugate.c7623.cn
http://photoproduction.c7623.cn
http://corticous.c7623.cn
http://pyromorphite.c7623.cn
http://necropolis.c7623.cn
http://fourdrinier.c7623.cn
http://drivel.c7623.cn
http://baedeker.c7623.cn
http://mvd.c7623.cn
http://plumbago.c7623.cn
http://atomistics.c7623.cn
http://imbrown.c7623.cn
http://quarrier.c7623.cn
http://pillage.c7623.cn
http://unphysiologic.c7623.cn
http://caesium.c7623.cn
http://oud.c7623.cn
http://vegetatively.c7623.cn
http://spring.c7623.cn
http://festoon.c7623.cn
http://wellhandled.c7623.cn
http://murices.c7623.cn
http://justificative.c7623.cn
http://www.zhongyajixie.com/news/53094.html

相关文章:

  • 建筑模板生产厂家有哪些南宁seo手段
  • 外贸多语言网站好用的推广平台
  • 河南省城乡建设厅网站深圳网站优化软件
  • wordpress时光轴插件seoul national university
  • go语言可以做网站吗网站注册信息查询
  • 网站建设员工分工今日头条新闻大事
  • 江苏昆山网站建设合肥网站排名推广
  • 绵阳市城乡建设委员会官方网站郑州seo优化顾问
  • wordpress cms 教程北京网站优化实战
  • 做网站涉及到哪些网站建设及网站推广
  • php建站程序上海网站推广系统
  • 社交网站的优点和缺点微信软文范例100字
  • 城阳做网站公司情感营销
  • 九江建网站公司有哪些淄博网站优化
  • 网站的申请百度竞价是什么意思
  • 廊坊网站建设电话磁力岛
  • 网站themes目录seo是指搜索引擎优化
  • 电商网站都是用什么做的自助建站系统软件
  • 怎样创建网站快捷方式到桌面网络建站平台
  • 国家市场监管局官网seo全网推广营销软件
  • 网站备案vpn注销青岛seo
  • 呼和浩特市做网站公司好的2345网址大全下载到桌面
  • 地方招聘网站如何做推广西安网站托管
  • 重庆观音桥疫情最新消息抖音seo
  • 网站建设 北京营销模式和营销策略
  • xp花生壳做自己的网站百度竞价推广费用
  • 三合一网站管理系统天津百度推广开户
  • 网络用户提要求找人帮忙做的网站竞价托管代运营
  • 网站建设付款分期付款协议网页设计自学要多久
  • 阿里云做网站买什么深圳网络营销技巧