iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >在Java中实现JDK动态代理的原理是什么
  • 222
分享到

在Java中实现JDK动态代理的原理是什么

javajdk动态代理 2023-05-31 10:05:40 222人浏览 泡泡鱼
摘要

在Java中实现jdk动态代理的原理是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、什么是代理?代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对

在Java中实现jdk动态代理的原理是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

一、什么是代理?

代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

代理模式UML图:

在Java中实现JDK动态代理的原理是什么

简单结构示意图:

在Java中实现JDK动态代理的原理是什么

为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。Java 动态代理机制以巧妙的方式近乎完美地实践了代理模式的设计理念。

二、Java 动态代理类

Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:

(1)Interface InvocationHandler:该接口中仅定义了一个方法

publicobject invoke(Object obj,Method method, Object[] args)

在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。

(2)Proxy:该类即为动态代理类,其中主要包含以下内容:

protected Proxy(InvocationHandler h) :构造函数,用于给内部的h赋值。

static Class getProxyClass (ClassLoaderloader, Class[] interfaces) :获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

static Object newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h) :返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)

所谓DynamicProxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然,这个DynamicProxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

在使用动态代理类时,我们必须实现InvocationHandler接口

通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。

动态代理步骤:

       1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法

       2.创建被代理的类以及接口

       3.通过Proxy的静态方法

           newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理

       4.通过代理调用方法

三、JDK的动态代理怎么使用?

1、需要动态代理的接口:

package jiankunking;   public interface Subject {    public String SayHello(String name);     public String SayGoodBye(); }

2、需要代理的实际对象

package jiankunking;   public class RealSubject implements Subject {     public String SayHello(String name)  {  return "hello " + name;  }     public String SayGoodBye()  {  return " good bye ";  } }

3、调用处理器实现类(有木有感觉这里就是传说中的AOP啊)

package jiankunking;  import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;    public class InvocationHandlerImpl implements InvocationHandler {     private Object subject;     public InvocationHandlerImpl(Object subject)  {  this.subject = subject;  }     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable  {  //在代理真实对象前我们可以添加一些自己的操作  System.out.println("在调用之前,我要干点啥呢?");   System.out.println("Method:" + method);   //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用  Object returnValue = method.invoke(subject, args);   //在代理真实对象后我们也可以添加一些自己的操作  System.out.println("在调用之后,我要干点啥呢?");   return returnValue;  } }

4、测试

package jiankunking;  import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy;   public class DynamicProxyDemonstration {  public static void main(String[] args)  {  //代理的真实对象  Subject realSubject = new RealSubject();     InvocationHandler handler = new InvocationHandlerImpl(realSubject);   ClassLoader loader = realSubject.getClass().getClassLoader();  Class[] interfaces = realSubject.getClass().getInterfaces();    Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);   System.out.println("动态代理对象的类型:"+subject.getClass().getName());   String hello = subject.SayHello("jiankunking");  System.out.println(hello); // String goodbye = subject.SayGoodBye(); // System.out.println(goodbye);  }  }

5、输出结果如下:

演示demo下载地址:Http://xiazai.jb51.net/201707/yuanma/DynamicProxyDemo(jb51.net).rar

四、动态代理怎么实现的?

从使用代码中可以看出,关键点在:

Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);

通过跟踪提示代码可以看出:当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用。

也就是说,当代码执行到:

subject.SayHello("jiankunking")这句话时,会自动调用InvocationHandlerImpl的invoke方法。这是为啥呢?

=======横线之间的是代码跟分析的过程,不想看的朋友可以直接看结论============

以下代码来自:JDK1.8.0_92

既然生成代理对象是用的Proxy类的静态方newProxyInstance,那么我们就去它的源码里看一下它到底都做了些什么?

 @CallerSensitive public static Object newProxyInstance(ClassLoader loader,    Class<?>[] interfaces,    InvocationHandler h)  throws IllegalArgumentException  {  //检查h 不为空,否则抛异常  Objects.requireNonNull(h);   final Class<?>[] intfs = interfaces.clone();  final SecurityManager sm = System.getSecurityManager();  if (sm != null) {  checkProxyAccess(Reflection.getCallerClass(), loader, intfs);  }     Class<?> cl = getProxyClass0(loader, intfs);     try {  if (sm != null) {  checkNewProxyPermission(Reflection.getCallerClass(), cl);  }  //获取代理对象的构造方法(也就是$Proxy0(InvocationHandler h))  final Constructor<?> cons = cl.getConstructor(constructorParams);  final InvocationHandler ih = h;  if (!Modifier.isPublic(cl.getModifiers())) {  AccessController.doPrivileged(new PrivilegedAction<Void>() {   public Void run() {   cons.setAccessible(true);   return null;   }  });  }  //生成代理类的实例并把InvocationHandlerImpl的实例传给它的构造方法  return cons.newInstance(new Object[]{h});  } catch (IllegalAccessException|InstantiationException e) {  throw new InternalError(e.toString(), e);  } catch (InvocationTargetException e) {  Throwable t = e.getCause();  if (t instanceof RuntimeException) {  throw (RuntimeException) t;  } else {  throw new InternalError(t.toString(), t);  }  } catch (NoSuchMethodException e) {  throw new InternalError(e.toString(), e);  }  }

我们再进去getProxyClass0方法看一下:

  private static Class<?> getProxyClass0(ClassLoader loader,    Class<?>... interfaces) {  if (interfaces.length > 65535) {  throw new IllegalArgumentException("interface limit exceeded");  }   // If the proxy class defined by the given loader implementing  // the given interfaces exists, this will simply return the cached copy;  // otherwise, it will create the proxy class via the ProxyClassFactory  return proxyClassCache.get(loader, interfaces);  }

 真相还是没有来到,继续,看一下proxyClassCache

  private static final WeakCache<ClassLoader, Class<?>[], Class<?>>  proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

奥,原来用了一下缓存

那么它对应的get方法啥样呢?

  public V get(K key, P parameter) {  Objects.requireNonNull(parameter);   expungeStaleEntries();   Object cacheKey = CacheKey.valueOf(key, refQueue);   // lazily install the 2nd level valuesMap for the particular cacheKey  ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);  if (valuesMap == null) {  //putIfAbsent这个方法在key不存在的时候加入一个值,如果key存在就不放入  ConcurrentMap<Object, Supplier<V>> oldValuesMap  = map.putIfAbsent(cacheKey,    valuesMap = new ConcurrentHashMap<>());  if (oldValuesMap != null) {  valuesMap = oldValuesMap;  }  }   // create subKey and retrieve the possible Supplier<V> stored by that  // subKey from valuesMap  Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));  Supplier<V> supplier = valuesMap.get(subKey);  Factory factory = null;   while (true) {  if (supplier != null) {  // supplier might be a Factory or a CacheValue<V> instance  V value = supplier.get();  if (value != null) {   return value;  }  }  // else no supplier in cache  // or a supplier that returned null (could be a cleared CacheValue  // or a Factory that wasn't successful in installing the CacheValue)   // lazily construct a Factory  if (factory == null) {  factory = new Factory(key, parameter, subKey, valuesMap);  }   if (supplier == null) {  supplier = valuesMap.putIfAbsent(subKey, factory);  if (supplier == null) {   // successfully installed Factory   supplier = factory;  }  // else retry with winning supplier  } else {  if (valuesMap.replace(subKey, supplier, factory)) {   // successfully replaced   // cleared CacheEntry / unsuccessful Factory   // with our Factory   supplier = factory;  } else {   // retry with current supplier   supplier = valuesMap.get(subKey);  }  }  }  }

我们可以看到它调用了 supplier.get(); 获取动态代理类,其中supplier是Factory,这个类定义在WeakCach的内部。

来瞅瞅,get里面又做了什么?

public synchronized V get() { // serialize access  // re-check  Supplier<V> supplier = valuesMap.get(subKey);  if (supplier != this) {  // something changed while we were waiting:  // might be that we were replaced by a CacheValue  // or were removed because of failure ->  // return null to signal WeakCache.get() to retry  // the loop  return null;  }  // else still us (supplier == this)   // create new value  V value = null;  try {  value = Objects.requireNonNull(valueFactory.apply(key, parameter));  } finally {  if (value == null) { // remove us on failure   valuesMap.remove(subKey, this);  }  }  // the only path to reach here is with non-null value  assert value != null;   // wrap value with CacheValue (WeakReference)  CacheValue<V> cacheValue = new CacheValue<>(value);   // try replacing us with CacheValue (this should always succeed)  if (valuesMap.replace(subKey, this, cacheValue)) {  // put also in reverseMap  reverseMap.put(cacheValue, Boolean.TRUE);  } else {  throw new AssertionError("Should not reach here");  }   // successfully replaced us with new CacheValue -> return the value  // wrapped by it  return value;  }  }

发现重点还是木有出现,但我们可以看到它调用了valueFactory.apply(key, parameter)方法:

  private static final class ProxyClassFactory  implements BiFunction<ClassLoader, Class<?>[], Class<?>>  {  // prefix for all proxy class names  private static final String proxyClassNamePrefix = "$Proxy";   // next number to use for generation of unique proxy class names  private static final AtomicLong nextUniqueNumber = new AtomicLong();   @Override  public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {   Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);  for (Class<?> intf : interfaces) {    Class<?> interfaceClass = null;  try {   interfaceClass = Class.forName(intf.getName(), false, loader);  } catch (ClassNotFoundException e) {  }  if (interfaceClass != intf) {   throw new IllegalArgumentException(   intf + " is not visible from class loader");  }    if (!interfaceClass.isInterface()) {   throw new IllegalArgumentException(   interfaceClass.getName() + " is not an interface");  }    if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {   throw new IllegalArgumentException(   "repeated interface: " + interfaceClass.getName());  }  }   String proxyPkg = null; // package to define proxy class in  int accessFlags = Modifier.PUBLIC | Modifier.FINAL;     for (Class<?> intf : interfaces) {  int flags = intf.getModifiers();  if (!Modifier.isPublic(flags)) {   accessFlags = Modifier.FINAL;   String name = intf.getName();   int n = name.lastIndexOf('.');   String pkg = ((n == -1) ? "" : name.substring(0, n + 1));   if (proxyPkg == null) {   proxyPkg = pkg;   } else if (!pkg.equals(proxyPkg)) {   throw new IllegalArgumentException(   "non-public interfaces from different packages");   }  }  }   if (proxyPkg == null) {  // if no non-public proxy interfaces, use com.sun.proxy package  proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";  }     long num = nextUniqueNumber.getAndIncrement();  String proxyName = proxyPkg + proxyClassNamePrefix + num;     byte[] proxyClassFile = ProxyGenerator.generateProxyClass(  proxyName, interfaces, accessFlags);  try {  return defineClass0(loader, proxyName,    proxyClassFile, 0, proxyClassFile.length);  } catch (ClassFORMatError e) {    throw new IllegalArgumentException(e.toString());  }  }  }

通过看代码终于找到了重点:

//生成字节码 byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);

那么接下来我们也使用测试一下,使用这个方法生成的字节码是个什么样子:

package jiankunking;  import sun.misc.ProxyGenerator;  import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy;   public class DynamicProxyDemonstration {  public static void main(String[] args)  {  //代理的真实对象  Subject realSubject = new RealSubject();     InvocationHandler handler = new InvocationHandlerImpl(realSubject);   ClassLoader loader = handler.getClass().getClassLoader();  Class[] interfaces = realSubject.getClass().getInterfaces();    Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);   System.out.println("动态代理对象的类型:"+subject.getClass().getName());   String hello = subject.SayHello("jiankunking");  System.out.println(hello);  // 将生成的字节码保存到本地,  createProxyClassFile();  }  private static void createProxyClassFile(){  String name = "ProxySubject";  byte[] data = ProxyGenerator.generateProxyClass(name,new Class[]{Subject.class});  FileOutputStream out =null;  try {  out = new FileOutputStream(name+".class");  System.out.println((new File("hello")).getAbsolutePath());  out.write(data);  } catch (FileNotFoundException e) {  e.printStackTrace();  } catch (IOException e) {  e.printStackTrace();  }finally {  if(null!=out) try {  out.close();  } catch (IOException e) {  e.printStackTrace();  }  }  }  }

可以看一下这里代理对象的类型:

在Java中实现JDK动态代理的原理是什么

我们用jd-jui 工具将生成的字节码反编译:

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import jiankunking.Subject;  public final class ProxySubject  extends Proxy  implements Subject {  private static Method m1;  private static Method m3;  private static Method m4;  private static Method m2;  private static Method m0;   public ProxySubject(InvocationHandler paramInvocationHandler)  {  super(paramInvocationHandler);  }   public final boolean equals(Object paramObject)  {  try  {  return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();  }  catch (Error|RuntimeException localError)  {  throw localError;  }  catch (Throwable localThrowable)  {  throw new UndeclaredThrowableException(localThrowable);  }  }   public final String SayGoodBye()  {  try  {  return (String)this.h.invoke(this, m3, null);  }  catch (Error|RuntimeException localError)  {  throw localError;  }  catch (Throwable localThrowable)  {  throw new UndeclaredThrowableException(localThrowable);  }  }   public final String SayHello(String paramString)  {  try  {  return (String)this.h.invoke(this, m4, new Object[] { paramString });  }  catch (Error|RuntimeException localError)  {  throw localError;  }  catch (Throwable localThrowable)  {  throw new UndeclaredThrowableException(localThrowable);  }  }   public final String toString()  {  try  {  return (String)this.h.invoke(this, m2, null);  }  catch (Error|RuntimeException localError)  {  throw localError;  }  catch (Throwable localThrowable)  {  throw new UndeclaredThrowableException(localThrowable);  }  }   public final int hashCode()  {  try  {  return ((Integer)this.h.invoke(this, m0, null)).intValue();  }  catch (Error|RuntimeException localError)  {  throw localError;  }  catch (Throwable localThrowable)  {  throw new UndeclaredThrowableException(localThrowable);  }  }   static  {  try  {  m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });  m3 = Class.forName("jiankunking.Subject").getMethod("SayGoodBye", new Class[0]);  m4 = Class.forName("jiankunking.Subject").getMethod("SayHello", new Class[] { Class.forName("java.lang.String") });  m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);  m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);  return;  }  catch (NoSuchMethodException localNoSuchMethodException)  {  throw new NoSuchMethodError(localNoSuchMethodException.getMessage());  }  catch (ClassNotFoundException localClassNotFoundException)  {  throw new NoClassDefFoundError(localClassNotFoundException.getMessage());  }  } }

这就是最终真正的代理类,它继承自Proxy并实现了我们定义的Subject接口

也就是说:

Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);

这里的subject实际是这个类的一个实例,那么我们调用它的:

public final String SayHello(String paramString)

就是调用我们定义的InvocationHandlerImpl的 invoke方法:

在Java中实现JDK动态代理的原理是什么

=======横线之间的是代码跟分析的过程,不想看的朋友可以直接看结论================

五、结论

到了这里,终于解答了:

subject.SayHello("jiankunking")这句话时,为什么会自动调用InvocationHandlerImpl的invoke方法?

因为JDK生成的最终真正的代理类,它继承自Proxy并实现了我们定义的Subject接口,在实现Subject接口方法的内部,通过反射调用了InvocationHandlerImpl的invoke方法。

包含生成本地class文件的demo:

http://xiazai.jb51.net/201707/yuanma/DynamicProxyDemo2(jb51.net).rar

通过分析代码可以看出Java 动态代理,具体有如下四步骤:

  • 通过实现 InvocationHandler 接口创建自己的调用处理器;

  • 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;

  • 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;

  • 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

看完上述内容,你们掌握在Java中实现JDK动态代理的原理是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网精选频道,感谢各位的阅读!

--结束END--

本文标题: 在Java中实现JDK动态代理的原理是什么

本文链接: https://www.lsjlt.com/news/224788.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 在Java中实现JDK动态代理的原理是什么
    在Java中实现JDK动态代理的原理是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、什么是代理?代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对...
    99+
    2023-05-31
    java jdk 动态代理
  • java中JDK动态代理的原理是什么
    这篇文章将为大家详细讲解有关java中JDK动态代理的原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java可以用来干什么Java主要应用于:1. web开发;2. Android...
    99+
    2023-06-14
  • Java实现JDK动态代理的原理详解
    目录概念案例静态代理JDK动态代理模式原理分析真相大白概念 代理:为控制A对象,而创建出新B对象,由B对象代替执行A对象所有操作,称之为代理。一个代理体系建立涉及到3个参与角色:真实...
    99+
    2022-11-13
  • java动态代理实现的原理是什么
    Java动态代理是指在运行时动态生成代理类的技术。它的实现原理主要涉及两个关键组件:接口和InvocationHandler。1. ...
    99+
    2023-09-09
    java
  • java动态代理的原理是什么
    小编给大家分享一下java动态代理的原理是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、说明使用代理将对象包装起来,然后用该代理对象取代原始对象。任何对原...
    99+
    2023-06-15
  • Java如何实现JDK动态代理
    这篇文章主要讲解了“Java如何实现JDK动态代理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java如何实现JDK动态代理”吧!概念代理:为控制A对象,而创建出新B对象,由B对象代替执行...
    99+
    2023-07-02
  • Java动态代理的原理及实现方法是什么
    本篇内容主要讲解“Java动态代理的原理及实现方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java动态代理的原理及实现方法是什么”吧!代理是指:某些场景下对象会找一个代理对象,来辅助...
    99+
    2023-07-02
  • Java中动态代理机制的原理是什么
    今天就跟大家聊聊有关Java中动态代理机制的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java 动态代理机制的出现,使得 Java  开发人员不用手工编写代理...
    99+
    2023-06-17
  • JDK动态代理过程原理及手写实现详解
    目录JDK动态代理的过程手写实现JDK动态代理创建MyInvocationHandler接口创建MyClassLoader类加载器创建代理类使用自定义动态代理类创建接口创建被代理接口...
    99+
    2022-11-13
  • JDK和CGLib动态代理怎么实现
    本篇内容介绍了“JDK和CGLib动态代理怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言:动态代理是一种常用的设计模式,广泛应用...
    99+
    2023-06-02
  • 怎么在java中实现动态代理
    这篇文章给大家介绍怎么在java中实现动态代理,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序。1、说明代...
    99+
    2023-06-14
  • Java中的动态代理是什么
    本篇内容介绍了“Java中的动态代理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!十分钟理解 Java 中的动态代理一、概述 什么是代...
    99+
    2023-06-02
  • java中实现多态的原理是什么
    什么是多态?多态就是指一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上...
    99+
    2020-11-11
    java 实现 多态 原理
  • Spring中JDK和cglib动态代理原理的示例分析
    这篇文章给大家分享的是有关Spring中JDK和cglib动态代理原理的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Java代理介绍Java中代理的实现一般分为三种:JDK静态代理、JDK动态代理以及C...
    99+
    2023-06-02
  • 怎么在java中实现CGLIB动态代理
    怎么在java中实现CGLIB动态代理?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,...
    99+
    2023-06-14
  • 深入理解java动态代理的两种实现方式(JDK/Cglib)
    什么是代理模式?代理模式:在调用处不直接调用目标类进行操作,而是调用代理类,然后通过代理类来调用目标类进行操作。在代理类调用目标类的前后可以添加一些预处理和后处理操作来完成一些不属于目标类的功能。为什么要使用代理模式?通过代理模式可以实现对...
    99+
    2023-05-31
    cglib jdk java
  • java多态实现的原理是什么
    Java多态的实现原理是通过方法的重写和方法的动态绑定实现的。多态是指同一个方法在不同的对象上可以有不同的表现形式。在Java中,一...
    99+
    2023-09-22
    java
  • Java中JDK动态代理的超详细讲解
    目录1. 什么是动态代理?2.动态代理的实现方式有几种?3. JDK动态代理4. CGLB动态代理5.动态代理的效率6.为什么要使用动态代理呢?7. JDK动态代理详细使用介绍总结1...
    99+
    2022-11-13
    Java jdk动态代理 java动态代理原理 jdk动态代理是如何实现的
  • 深入浅析java 中JDK的动态代理类
    这期内容当中小编将会给大家带来有关深入浅析java 中JDK的动态代理类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。详解java JDK 动态代理类分析(java.lang.reflect.Proxy)...
    99+
    2023-05-31
    java jdk 动态代理类
  • java中动态绑定的原理是什么
    本篇文章为大家展示了java中动态绑定的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java的优点是什么1. 简单,只需理解基本的概念,就可以编写适合于各种情况的应用程序;2. 面向对象...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作