我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

在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动态代理的原理是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

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

下载Word文档

猜你喜欢

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

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

java中JDK动态代理的原理是什么

这篇文章将为大家详细讲解有关java中JDK动态代理的原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java可以用来干什么Java主要应用于:1. web开发;2. Android
2023-06-14

java动态代理实现的原理是什么

Java动态代理是指在运行时动态生成代理类的技术。它的实现原理主要涉及两个关键组件:接口和InvocationHandler。1. 接口:代理类需要实现一个接口,该接口定义了将要被代理对象的方法。2. InvocationHandler:I
2023-09-09

java动态代理的原理是什么

小编给大家分享一下java动态代理的原理是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、说明使用代理将对象包装起来,然后用该代理对象取代原始对象。任何对原
2023-06-15

Java动态代理的原理及实现方法是什么

本篇内容主要讲解“Java动态代理的原理及实现方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java动态代理的原理及实现方法是什么”吧!代理是指:某些场景下对象会找一个代理对象,来辅助
2023-07-02

Java如何实现JDK动态代理

这篇文章主要讲解了“Java如何实现JDK动态代理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java如何实现JDK动态代理”吧!概念代理:为控制A对象,而创建出新B对象,由B对象代替执行
2023-07-02

Java中动态代理机制的原理是什么

今天就跟大家聊聊有关Java中动态代理机制的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简
2023-06-17

怎么在java中实现动态代理

这篇文章给大家介绍怎么在java中实现动态代理,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序。1、说明代
2023-06-14

Java中的动态代理是什么

本篇内容介绍了“Java中的动态代理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!十分钟理解 Java 中的动态代理一、概述1. 什么
2023-06-02

java中实现多态的原理是什么

什么是多态?多态就是指一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用
java中实现多态的原理是什么
2020-11-11

JDK和CGLib动态代理怎么实现

本篇内容介绍了“JDK和CGLib动态代理怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言:动态代理是一种常用的设计模式,广泛应用
2023-06-02

怎么在java中实现CGLIB动态代理

怎么在java中实现CGLIB动态代理?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,
2023-06-14

java多态实现的原理是什么

Java多态的实现原理是通过方法的重写和方法的动态绑定实现的。多态是指同一个方法在不同的对象上可以有不同的表现形式。在Java中,一个父类可以有多个子类。当一个方法被子类重写时,子类对象调用该方法时会优先调用自己的实现。而在编译时,编译器无
2023-09-22

java中动态绑定的原理是什么

本篇文章为大家展示了java中动态绑定的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java的优点是什么1. 简单,只需理解基本的概念,就可以编写适合于各种情况的应用程序;2. 面向对象
2023-06-14

Java中怎么实现动态代理

今天就跟大家聊聊有关Java中怎么实现动态代理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、概述 代理是一种设计模式,其目的是为其他对象提供一个代理以控制对某个对象的访问,代理类
2023-06-17

动态代理ip的工作原理是什么

这篇文章主要讲解了“动态代理ip的工作原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“动态代理ip的工作原理是什么”吧!所以它要求对HTTP进行请求和响应模拟。基于以下图像直观地展示
2023-06-25

Spring中JDK和cglib动态代理原理的示例分析

这篇文章给大家分享的是有关Spring中JDK和cglib动态代理原理的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Java代理介绍Java中代理的实现一般分为三种:JDK静态代理、JDK动态代理以及C
2023-06-02

java中动态代理的特点是什么

java中动态代理的特点是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。说明1、JDK动态代理不需要实现界面,只有目标对象需要实现界面。2、基于接口的动态代理需要使用JDK
2023-06-20

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录