java高级群329019348
1、java动态代理是通过实现InvovationHandler的invoke方法完成的。原理就是在代理类ProxyClass生成的时候把InvocationHandler当作入参传入到构造函数中,同时在静态模块中根据类名反射生成class。
下面一步一步揭开上述的流程。
IService service=new ServiceImp(); ProxyHandler proxyHandler=new ProxyHandler(service); IService iService=(IService)Proxy.newProxyInstance(ServiceImp.class.getClassLoader(), ServiceImp.class.getInterfaces(),proxyHandler);
iService.doService();
上述是我们的调用流程,ServiceImp实现了接口Iservice,第二行是产生一个ProxyHandler的实例,第三行是通过静态方法Proxy. newProxyInstance生成的Object强转为IService接口,第四行就是通过强转的接口来调用doService方法。
下面来分析Proxy.newProxyInstance这个方法,源码中有这么一句
/* * Look up or generate the designated proxy class. */ Class<?> cl = getProxyClass0(loader, intfs);
看注释就知道这句是生成代理类的,继续往下追
// 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);
不懂就看注释,其实就是将代理类和ClassLoader做了一个缓存,如果缓存中找不到,就通过ProxyClassFactory创建一个代理类,那么我们重点关注一下下面源码中有ProxyClassFactory实例的地方
// create subKey and retrieve the possible Supplier<V> stored by that // subKey from valuesMap Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
在动态调试到这里的时候发现,paramer是需要代理的接口,而apply接口的实现类其中就有一个ProxyClassFactory,我们看一下apply内部的实现
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length); for (Class<?> intf : interfaces) { /* * Verify that the class loader resolves the name of this * interface to the same Class object. */ 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"); } /* * Verify that the Class object actually represents an * interface. */ if (!interfaceClass.isInterface()) { throw new IllegalArgumentException( interfaceClass.getName() + " is not an interface"); } /* * Verify that this interface is not a duplicate. */ if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) { throw new IllegalArgumentException( "repeated interface: " + interfaceClass.getName()); } }
上面对需要代理的类进行了一系列的预判断,抛出了一系列的异常,其中一个就是代理的必须是接口。如果不是接口就会抛出异常,那代理的类是怎么生成的呢?我们继续往下看,
byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces);
通过上面的代码,就生成了class的二进制文件。 generateProxyClass的两个参数。第一个是代理的类的名字,第二个是接口,就是和我们手动创建一个类实现接口是一个意思。本来是想继续往下看的,结果再往下看无法看到源码了,那就手动调用一次看看输出的class二进制文件长的啥样。
byte[]classFile= ProxyGenerator.generateProxyClass("com.newService",new Class[]{IService.class}); File file=new File("Test.class"); try { file.createNewFile();//建立输出字节流
FileOutputStream fos = new FileOutputStream(file);
//用FileOutputStream 的write方法写入字节数组 fos.write(classFile); System.out.println("写入成功"); }catch (Exception e) { e.printStackTrace(); }
反编译后的class文件如下:
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package com; import com.mfuny.proxy.IService; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class newService extends Proxy implements IService { private static Method m1; private static Method m0; private static Method m3; private static Method m2; public newService(InvocationHandler var1) throws { super(var1); } public final boolean equals(Object var1) throws { try { return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue(); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final int hashCode() throws { try { return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue(); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final void doService() throws { try { super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final String toString() throws { try { return (String)super.h.invoke(this, m2, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } static { try { 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]); m3 = Class.forName("com.mfuny.proxy.IService").getMethod("doService", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } } }可以看到在代理类继承了Proxy类,实现了代理的接口。在静态方法里面初始化了代理的类的方法。在doService方法里调用了基类的handler的invoke方法。
相关推荐
Java动态代理是Java编程中一个重要的特性,它允许我们在运行时创建代理对象,这些代理对象可以代表并增强原对象的功能。动态代理在很多场景下都非常有用,比如日志记录、性能监控、事务管理等。本示例将带你深入理解...
Java动态代理是Java语言提供的一种在运行时创建代理对象的技术,它允许我们为已存在的接口创建代理类,以便在调用真实目标对象的方法时添加额外的功能或行为。在这个实例中,我们将深入探讨Java动态代理的核心概念,...
Java动态代理是Java编程中一个重要的特性,它允许在运行时创建代理对象,这些代理对象可以代表并增强原对象的功能。动态代理主要应用于面向切面编程(AOP)和事件监听等场景,使得代码更加模块化,易于维护。以下是...
Java动态代理技术是Java编程中一个非常重要的特性,它允许我们在运行时动态创建具有特定行为的对象。这种技术常用于AOP(面向切面编程)和框架中,如Spring AOP,用于实现方法拦截、事务管理等功能。Java提供了两种...
本篇文章将深入探讨Java动态代理的概念、原理以及如何通过一个简单的"Hello, World!"示例来理解它。 动态代理,顾名思义,是在程序运行时动态地生成代理对象。与静态代理(编译时已知)相比,动态代理更加灵活,...
JDK 动态代理JDK 提供了 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口来支持动态代理。Proxy 类用于创建一个代理对象,而 InvocationHandler 接口则定义了代理对象的方法调用处理逻辑。...
Java动态代理是Java语言提供的一种在运行时创建代理对象的技术,它允许我们为已存在的接口创建代理类,以便在调用方法时添加额外的功能或控制。动态代理在很多场景下非常有用,比如日志记录、性能监控、事务管理等。...
Java动态代理机制是Java语言提供的一种强大的功能,它允许在运行时创建代理对象来实现特定接口,从而可以灵活地扩展或增强已有代码的功能。在Java中,动态代理主要通过两个类来实现:`java.lang.reflect.Proxy` 和 `...
### Java动态代理实现AOP详解 #### 一、引言 随着软件开发复杂度的提升,传统的面向对象编程(OOP)已经难以满足现代软件工程的需求。为了更好地管理跨切面的关注点,如日志记录、性能监控、安全控制等,面向切面...
java动态代理 public class HireProxy implements InvocationHandler { //被代理的真实角色 private Object obj; public HireProxy(Object obj) { super(); this.obj = obj; } //第二个参数method,被...
Java动态代理是Java提供的一种在运行时创建代理对象的技术,主要由`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口组成。在这个简单的Java动态代理实例中,我们将探讨如何利用这两个核心...
Java动态代理机制是Java语言提供的一种强大的功能,它允许在运行时创建代理对象来实现指定的接口。这一机制使得我们可以在不修改已有代码的情况下,为已有接口增加额外的功能或者增强已有功能的行为。在Java中,动态...
Java动态代理机制的优点在于灵活性和便捷性,它允许在运行时动态创建符合特定接口的代理对象,无需对原有代码做任何修改,使得我们可以方便地实现诸如日志、事务控制等跨切面的逻辑。不过,动态代理仅限于代理接口,...
Java动态代理实现AOP Java动态代理是实现Aspect Oriented Programming(AOP)的重要手段。在Java中,动态代理可以通过java.lang.reflect InvocationHandler接口和java.lang.reflect.Proxy类来实现。AOP的主要思想...
Java动态代理是Java编程中一个非常重要的特性,它允许我们在运行时创建代理对象来代替目标对象,以便在不修改原有代码的情况下对目标对象的行为进行增强或扩展。在Java.lang.reflect包下,动态代理主要涉及两个核心...
对代理模式与Java动态代理类的理解说明
总之,基于Java动态代理和反射机制实现ORM,可以有效地解耦业务逻辑和数据库操作,提高代码的可读性和可维护性。虽然现有的ORM框架如Hibernate、MyBatis已经相当成熟,但对于学习和理解Java的高级特性,这样的实践...
Java动态代理是Java语言提供的一种机制,它允许在运行时创建一个对象的代理,这个代理对象可以在调用实际方法之前和之后添加额外的功能。在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang....