一、静态代理

二、动态代理

2.1 JDK

JDK的Proxy动态代理,必须要求有接口和实现类,然后对接口中的方法进行增强,同时,他只能读取接口中方法上的注解信息。
代理 - 图1

2.1.1 示例

Calculator接口

  1. /**
  2. * 计算器接口
  3. *
  4. * @author maomaochong
  5. * @date 2022/07/07 21:27
  6. **/
  7. public interface Calculator {
  8. int add(int i, int j);
  9. int sub(int i, int j);
  10. int mul(int i, int j);
  11. int div(int i, int j);
  12. }

Calculator实现类

  1. /**
  2. * 自定义计算器
  3. *
  4. * @author maomaochong
  5. * @date 2022/07/07 21:28
  6. **/
  7. public class MyCalculator implements Calculator{
  8. @Override
  9. public int add(int i, int j) {
  10. return i + j;
  11. }
  12. @Override
  13. public int sub(int i, int j) {
  14. return i - j;
  15. }
  16. @Override
  17. public int mul(int i, int j) {
  18. return i * j;
  19. }
  20. @Override
  21. public int div(int i, int j) {
  22. return i / j;
  23. }
  24. }

代理生成类

  1. /**
  2. * 计算器代理类
  3. *
  4. * @author maomaochong
  5. * @date 2022/07/07 21:29
  6. **/
  7. public class CalculatorProxy {
  8. public static Calculator getProxy(Calculator calculator) {
  9. // 获取类加载器
  10. ClassLoader classLoader = calculator.getClass().getClassLoader();
  11. // 获取被代理实现的接口
  12. Class<?>[] interfaces = calculator.getClass().getInterfaces();
  13. // 生成InvocationHandler
  14. InvocationHandler invocationHandler = new InvocationHandler() {
  15. @Override
  16. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  17. Object result = null;
  18. try {
  19. result = method.invoke(calculator, args);
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. }
  23. return result;
  24. }
  25. };
  26. Object proxyInstance = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
  27. return (Calculator) proxyInstance;
  28. }
  29. }

测试类

  1. /**
  2. * jdk动态代理测试类
  3. *
  4. * @author maomaochong
  5. * @date 2022/07/07 21:36
  6. **/
  7. public class JdkProxyTest {
  8. public static void main(String[] args) {
  9. // 获取被代理类对象
  10. MyCalculator myCalculator = new MyCalculator();
  11. // 获取代理类对象
  12. Calculator proxy = CalculatorProxy.getProxy(myCalculator);
  13. System.out.println(proxy.add(1, 1));
  14. System.out.println(proxy.getClass());
  15. }
  16. }

2.1.2 源码分析

1. 获取代理类对象核心方法

此方法是生成动态代理的代理类的核心方法:

  1. public static Object newProxyInstance(ClassLoader loader,
  2. Class<?>[] interfaces,
  3. InvocationHandler h)
  4. throws IllegalArgumentException
  5. {
  6. // 判断InvocationHandler,不能为空
  7. Objects.requireNonNull(h);
  8. // 克隆被代理类实现的接口的字节码信息
  9. final Class<?>[] intfs = interfaces.clone();
  10. final SecurityManager sm = System.getSecurityManager();
  11. if (sm != null) {
  12. checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
  13. }
  14. /*
  15. * Look up or generate the designated proxy class.
  16. */
  17. // 此方法是核心,获取代理类的字节码信息
  18. Class<?> cl = getProxyClass0(loader, intfs);
  19. /*
  20. * Invoke its constructor with the designated invocation handler.
  21. */
  22. // 执行InvocationHandler设计好的代理类的构造方法
  23. try {
  24. if (sm != null) {
  25. checkNewProxyPermission(Reflection.getCallerClass(), cl);
  26. }
  27. // 获取构造方法
  28. final Constructor<?> cons = cl.getConstructor(constructorParams);
  29. final InvocationHandler ih = h;
  30. // 判断修饰符,确定是否开启访问权限
  31. if (!Modifier.isPublic(cl.getModifiers())) {
  32. AccessController.doPrivileged(new PrivilegedAction<Void>() {
  33. public Void run() {
  34. cons.setAccessible(true);
  35. return null;
  36. }
  37. });
  38. }
  39. // 生成代理类对象
  40. return cons.newInstance(new Object[]{h});
  41. } catch (IllegalAccessException|InstantiationException e) {
  42. throw new InternalError(e.toString(), e);
  43. } catch (InvocationTargetException e) {
  44. Throwable t = e.getCause();
  45. if (t instanceof RuntimeException) {
  46. throw (RuntimeException) t;
  47. } else {
  48. throw new InternalError(t.toString(), t);
  49. }
  50. } catch (NoSuchMethodException e) {
  51. throw new InternalError(e.toString(), e);
  52. }
  53. }

1.1 获取代理类字节码信息

获取代理类的字节码信息:

  1. private static Class<?> getProxyClass0(ClassLoader loader,
  2. Class<?>... interfaces) {
  3. // 判断被代理类实现的接口数量,超出此数目则抛出异常
  4. if (interfaces.length > 65535) {
  5. throw new IllegalArgumentException("interface limit exceeded");
  6. }
  7. // If the proxy class defined by the given loader implementing
  8. // the given interfaces exists, this will simply return the cached copy;
  9. // otherwise, it will create the proxy class via the ProxyClassFactory
  10. // 如果给定的类加载器定义的实现了指定接口的代理类已经存在,就返回缓存中的副本,
  11. // 否则就通过代理类工厂创建代理类
  12. // 此处实际上调用的是 WeakCache 中 的get方法
  13. return proxyClassCache.get(loader, interfaces);
  14. }

1.1.1 从缓存获取代理类信息

尝试从缓存中获取代理类信息:

  1. public V get(K key, P parameter) {
  2. // 判断给定的接口信息不能为空
  3. Objects.requireNonNull(parameter);
  4. expungeStaleEntries();
  5. Object cacheKey = CacheKey.valueOf(key, refQueue);
  6. // lazily install the 2nd level valuesMap for the particular cacheKey
  7. ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
  8. if (valuesMap == null) {
  9. ConcurrentMap<Object, Supplier<V>> oldValuesMap
  10. = map.putIfAbsent(cacheKey,
  11. valuesMap = new ConcurrentHashMap<>());
  12. if (oldValuesMap != null) {
  13. valuesMap = oldValuesMap;
  14. }
  15. }
  16. // create subKey and retrieve the possible Supplier<V> stored by that
  17. // subKey from valuesMap
  18. // 此处是重点,通过函数式接口,实际使用Proxy内部的ProxyClassFactory中的apply方法获取到代理类的字节码信息
  19. Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
  20. Supplier<V> supplier = valuesMap.get(subKey);
  21. Factory factory = null;
  22. while (true) {
  23. if (supplier != null) {
  24. // supplier might be a Factory or a CacheValue<V> instance
  25. V value = supplier.get();
  26. if (value != null) {
  27. // 上边生成代理类字节码信息之后,在此处返回
  28. return value;
  29. }
  30. }
  31. // else no supplier in cache
  32. // or a supplier that returned null (could be a cleared CacheValue
  33. // or a Factory that wasn't successful in installing the CacheValue)
  34. // lazily construct a Factory
  35. // 因为最初的map中没有其他的键存在,所以会来到这一步,构建工厂
  36. if (factory == null) {
  37. factory = new Factory(key, parameter, subKey, valuesMap);
  38. }
  39. if (supplier == null) {
  40. supplier = valuesMap.putIfAbsent(subKey, factory);
  41. if (supplier == null) {
  42. // successfully installed Factory
  43. // 在此处将工厂赋值给函数式接口
  44. supplier = factory;
  45. }
  46. // else retry with winning supplier
  47. } else {
  48. if (valuesMap.replace(subKey, supplier, factory)) {
  49. // successfully replaced
  50. // cleared CacheEntry / unsuccessful Factory
  51. // with our Factory
  52. supplier = factory;
  53. } else {
  54. // retry with current supplier
  55. supplier = valuesMap.get(subKey);
  56. }
  57. }
  58. }
  59. }

生成代理类的字节码信息:

  1. private static final class ProxyClassFactory
  2. implements BiFunction<ClassLoader, Class<?>[], Class<?>>
  3. {
  4. // prefix for all proxy class names
  5. // 代理类名前缀
  6. private static final String proxyClassNamePrefix = "$Proxy";
  7. // next number to use for generation of unique proxy class names
  8. private static final AtomicLong nextUniqueNumber = new AtomicLong();
  9. @Override
  10. public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
  11. Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
  12. for (Class<?> intf : interfaces) {
  13. /*
  14. * Verify that the class loader resolves the name of this
  15. * interface to the same Class object.
  16. */
  17. Class<?> interfaceClass = null;
  18. try {
  19. // 获取接口字节码
  20. interfaceClass = Class.forName(intf.getName(), false, loader);
  21. } catch (ClassNotFoundException e) {
  22. }
  23. // 验证获取的字节码 类加载是否可见
  24. if (interfaceClass != intf) {
  25. throw new IllegalArgumentException(
  26. intf + " is not visible from class loader");
  27. }
  28. /*
  29. * Verify that the Class object actually represents an
  30. * interface.
  31. */
  32. // 验证字节码对象是一个接口
  33. if (!interfaceClass.isInterface()) {
  34. throw new IllegalArgumentException(
  35. interfaceClass.getName() + " is not an interface");
  36. }
  37. /*
  38. * Verify that this interface is not a duplicate.
  39. */
  40. // 验证此接口是否重复
  41. if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
  42. throw new IllegalArgumentException(
  43. "repeated interface: " + interfaceClass.getName());
  44. }
  45. }
  46. String proxyPkg = null; // package to define proxy class in
  47. int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
  48. /*
  49. * Record the package of a non-public proxy interface so that the
  50. * proxy class will be defined in the same package. Verify that
  51. * all non-public proxy interfaces are in the same package.
  52. */
  53. for (Class<?> intf : interfaces) {
  54. int flags = intf.getModifiers();
  55. if (!Modifier.isPublic(flags)) {
  56. accessFlags = Modifier.FINAL;
  57. String name = intf.getName();
  58. int n = name.lastIndexOf('.');
  59. String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
  60. if (proxyPkg == null) {
  61. proxyPkg = pkg;
  62. } else if (!pkg.equals(proxyPkg)) {
  63. throw new IllegalArgumentException(
  64. "non-public interfaces from different packages");
  65. }
  66. }
  67. }
  68. if (proxyPkg == null) {
  69. // if no non-public proxy interfaces, use com.sun.proxy package
  70. // 如果是非公开的代理接口,使用 com.sun.proxy 包
  71. proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
  72. }
  73. /*
  74. * Choose a name for the proxy class to generate.
  75. */
  76. // 拼接类名前缀和随机数
  77. long num = nextUniqueNumber.getAndIncrement();
  78. // 包名 + 类前缀 + 随机数 组成代理类名
  79. String proxyName = proxyPkg + proxyClassNamePrefix + num;
  80. /*
  81. * Generate the specified proxy class.
  82. */
  83. // 生成特定的代理类的字节数组
  84. byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
  85. proxyName, interfaces, accessFlags);
  86. try {
  87. return defineClass0(loader, proxyName,
  88. proxyClassFile, 0, proxyClassFile.length);
  89. } catch (ClassFormatError e) {
  90. /*
  91. * A ClassFormatError here means that (barring bugs in the
  92. * proxy class generation code) there was some other
  93. * invalid aspect of the arguments supplied to the proxy
  94. * class creation (such as virtual machine limitations
  95. * exceeded).
  96. */
  97. throw new IllegalArgumentException(e.toString());
  98. }
  99. }
  100. }

1.2 调用字节码的构造方法,生成代理类对象

2. 生成具体的代理类文件

我们可以通过配置,来将生成的代理类字节码信息产生具体的文件:

  1. /**
  2. * jdk动态代理测试类
  3. *
  4. * @author maomaochong
  5. * @date 2022/07/07 21:36
  6. **/
  7. public class JdkProxyTest {
  8. public static void main(String[] args) {
  9. // 配置此内容,产生具体的代理类文件
  10. System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
  11. // 获取被代理类对象
  12. MyCalculator myCalculator = new MyCalculator();
  13. // 获取代理类对象
  14. Calculator proxy = CalculatorProxy.getProxy(myCalculator);
  15. System.out.println(proxy.add(1, 1));
  16. System.out.println(proxy.getClass());
  17. }
  18. }

包路径如下:
image.png
具体内容如下:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by FernFlower decompiler)
  4. //
  5. package com.sun.proxy;
  6. import com.moomooyu.proxy.jdk.Calculator;
  7. import java.lang.reflect.InvocationHandler;
  8. import java.lang.reflect.Method;
  9. import java.lang.reflect.Proxy;
  10. import java.lang.reflect.UndeclaredThrowableException;
  11. public final class $Proxy0 extends Proxy implements Calculator {
  12. private static Method m1;
  13. private static Method m2;
  14. private static Method m5;
  15. private static Method m3;
  16. private static Method m4;
  17. private static Method m6;
  18. private static Method m0;
  19. public $Proxy0(InvocationHandler var1) throws {
  20. super(var1);
  21. }
  22. public final boolean equals(Object var1) throws {
  23. try {
  24. return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
  25. } catch (RuntimeException | Error var3) {
  26. throw var3;
  27. } catch (Throwable var4) {
  28. throw new UndeclaredThrowableException(var4);
  29. }
  30. }
  31. public final String toString() throws {
  32. try {
  33. return (String)super.h.invoke(this, m2, (Object[])null);
  34. } catch (RuntimeException | Error var2) {
  35. throw var2;
  36. } catch (Throwable var3) {
  37. throw new UndeclaredThrowableException(var3);
  38. }
  39. }
  40. public final int mul(int var1, int var2) throws {
  41. try {
  42. return (Integer)super.h.invoke(this, m5, new Object[]{var1, var2});
  43. } catch (RuntimeException | Error var4) {
  44. throw var4;
  45. } catch (Throwable var5) {
  46. throw new UndeclaredThrowableException(var5);
  47. }
  48. }
  49. public final int add(int var1, int var2) throws {
  50. try {
  51. return (Integer)super.h.invoke(this, m3, new Object[]{var1, var2});
  52. } catch (RuntimeException | Error var4) {
  53. throw var4;
  54. } catch (Throwable var5) {
  55. throw new UndeclaredThrowableException(var5);
  56. }
  57. }
  58. public final int sub(int var1, int var2) throws {
  59. try {
  60. return (Integer)super.h.invoke(this, m4, new Object[]{var1, var2});
  61. } catch (RuntimeException | Error var4) {
  62. throw var4;
  63. } catch (Throwable var5) {
  64. throw new UndeclaredThrowableException(var5);
  65. }
  66. }
  67. public final int div(int var1, int var2) throws {
  68. try {
  69. return (Integer)super.h.invoke(this, m6, new Object[]{var1, var2});
  70. } catch (RuntimeException | Error var4) {
  71. throw var4;
  72. } catch (Throwable var5) {
  73. throw new UndeclaredThrowableException(var5);
  74. }
  75. }
  76. public final int hashCode() throws {
  77. try {
  78. return (Integer)super.h.invoke(this, m0, (Object[])null);
  79. } catch (RuntimeException | Error var2) {
  80. throw var2;
  81. } catch (Throwable var3) {
  82. throw new UndeclaredThrowableException(var3);
  83. }
  84. }
  85. static {
  86. try {
  87. m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
  88. m2 = Class.forName("java.lang.Object").getMethod("toString");
  89. m5 = Class.forName("com.moomooyu.proxy.jdk.Calculator").getMethod("mul", Integer.TYPE, Integer.TYPE);
  90. m3 = Class.forName("com.moomooyu.proxy.jdk.Calculator").getMethod("add", Integer.TYPE, Integer.TYPE);
  91. m4 = Class.forName("com.moomooyu.proxy.jdk.Calculator").getMethod("sub", Integer.TYPE, Integer.TYPE);
  92. m6 = Class.forName("com.moomooyu.proxy.jdk.Calculator").getMethod("div", Integer.TYPE, Integer.TYPE);
  93. m0 = Class.forName("java.lang.Object").getMethod("hashCode");
  94. } catch (NoSuchMethodException var2) {
  95. throw new NoSuchMethodError(var2.getMessage());
  96. } catch (ClassNotFoundException var3) {
  97. throw new NoClassDefFoundError(var3.getMessage());
  98. }
  99. }
  100. }

2.2 CGLib

Cglib的动态代理是面向父类实现的,和接口没有直接的关系。它不仅仅可以增强接口中定义的方法,还可以增强一个类其他的方法。同时,它还可以利用反射来读取父类方法上的所有注解。

2.2.1 示例

被代理类

  1. /**
  2. * 自定义计算器
  3. *
  4. * @author maomaochong
  5. * @date 2022/07/07 21:28
  6. **/
  7. public class MyCalculator {
  8. public int add(int i, int j) {
  9. return i + j;
  10. }
  11. public int sub(int i, int j) {
  12. return i - j;
  13. }
  14. public int mul(int i, int j) {
  15. return i * j;
  16. }
  17. public int div(int i, int j) {
  18. return i / j;
  19. }
  20. }

方法拦截器

  1. /**
  2. * 计算器方法代理
  3. *
  4. * @author maomaochong
  5. * @date 2022/07/07 21:29
  6. **/
  7. public class CalculatorProxy implements MethodInterceptor {
  8. /**
  9. * Object o:代理类对象
  10. * Method method:拦截方法
  11. * Object[] objects:入参
  12. * MethodProxy methodProxy:未被拦截方法,super方法
  13. *
  14. *
  15. */
  16. @Override
  17. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  18. System.out.println("方法执行之前。。。");
  19. Object result = methodProxy.invokeSuper(o, objects);
  20. System.out.println("方法执行之后。。。");
  21. return result;
  22. }
  23. }

测试类

  1. /**
  2. * cglib动态代理测试类
  3. *
  4. * @author maomaochong
  5. * @date 2022/07/07 21:36
  6. **/
  7. public class CglibProxyTest {
  8. public static void main(String[] args) {
  9. // 生成代理类文件
  10. System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E:\\Workspace\\Study\\thinking-in-spring");
  11. // 创建cglib获取代理对象的操作对象
  12. Enhancer enhancer = new Enhancer();
  13. // 设置enhancer对象的父类
  14. enhancer.setSuperclass(MyCalculator.class);
  15. // 设置enhancer的回调对象
  16. enhancer.setCallback(new CalculatorProxy());
  17. // 创建代理对象
  18. MyCalculator myCalculator = (MyCalculator) enhancer.create();
  19. myCalculator.add(1, 1);
  20. System.out.println(myCalculator.getClass());
  21. }
  22. }

2.2.2 源码分析

  1. public Object create() {
  2. classOnly = false;
  3. argumentTypes = null;
  4. return createHelper();
  5. }
  1. private Object createHelper() {
  2. validate();
  3. if (superclass != null) {
  4. setNamePrefix(superclass.getName());
  5. } else if (interfaces != null) {
  6. setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
  7. }
  8. // KEY_FACTORY.newInstance():生成了一个EnhancerKey代理对象,该代理对象里面保存了用户所设置的代理信息
  9. // super.create():去创建代理对象
  10. return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
  11. ReflectUtils.getNames(interfaces),
  12. filter,
  13. callbackTypes,
  14. useFactory,
  15. interceptDuringConstruction,
  16. serialVersionUID));
  17. }
  1. protected Object create(Object key) {
  2. try {
  3. Class gen = null;
  4. synchronized (source) {
  5. ClassLoader loader = getClassLoader();
  6. Map cache2 = null;
  7. cache2 = (Map)source.cache.get(loader);
  8. if (cache2 == null) {
  9. cache2 = new HashMap();
  10. cache2.put(NAME_KEY, new HashSet());
  11. source.cache.put(loader, cache2);
  12. } else if (useCache) {
  13. Reference ref = (Reference)cache2.get(key);
  14. gen = (Class) (( ref == null ) ? null : ref.get());
  15. }
  16. if (gen == null) {
  17. Object save = CURRENT.get();
  18. CURRENT.set(this);
  19. try {
  20. this.key = key;
  21. if (attemptLoad) {
  22. try {
  23. gen = loader.loadClass(getClassName());
  24. } catch (ClassNotFoundException e) {
  25. // ignore
  26. }
  27. }
  28. if (gen == null) {
  29. // 使用策略生成代理类
  30. byte[] b = strategy.generate(this);
  31. String className = ClassNameReader.getClassName(new ClassReader(b));
  32. getClassNameCache(loader).add(className);
  33. gen = ReflectUtils.defineClass(className, b, loader);
  34. }
  35. // 如果使用缓存,就把生成的代理类加入缓存
  36. if (useCache) {
  37. cache2.put(key, new WeakReference(gen));
  38. }
  39. // 调用代理类的构造方法生成一个代理对象
  40. return firstInstance(gen);
  41. } finally {
  42. CURRENT.set(save);
  43. }
  44. }
  45. }
  46. return firstInstance(gen);
  47. } catch (RuntimeException e) {
  48. throw e;
  49. } catch (Error e) {
  50. throw e;
  51. } catch (Exception e) {
  52. throw new CodeGenerationException(e);
  53. }
  54. }
  1. public byte[] generate(ClassGenerator cg) throws Exception {
  2. DebuggingClassWriter cw = getClassVisitor();
  3. transform(cg).generateClass(cw);
  4. return transform(cw.toByteArray());
  5. }
  1. // import org.objectweb.asm.ClassWriter;
  2. // 使用asm技术生成
  3. protected DebuggingClassWriter getClassVisitor() throws Exception {
  4. return new DebuggingClassWriter(ClassWriter.COMPUTE_MAXS);
  5. }
  1. public void generateClass(ClassVisitor v) throws Exception {
  2. Class sc = (superclass == null) ? Object.class : superclass;
  3. // 被代理类是final,不能有自类,所以抛异常
  4. if (TypeUtils.isFinal(sc.getModifiers()))
  5. throw new IllegalArgumentException("Cannot subclass final class " + sc);
  6. List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
  7. filterConstructors(sc, constructors);
  8. // Order is very important: must add superclass, then
  9. // its superclass chain, then each interface and
  10. // its superinterfaces.
  11. List actualMethods = new ArrayList();
  12. List interfaceMethods = new ArrayList();
  13. final Set forcePublic = new HashSet();
  14. // sc表示superclass,拿到父类或接口中所有的方法
  15. getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
  16. List methods = CollectionUtils.transform(actualMethods, new Transformer() {
  17. public Object transform(Object value) {
  18. Method method = (Method)value;
  19. int modifiers = Constants.ACC_FINAL
  20. | (method.getModifiers()
  21. & ~Constants.ACC_ABSTRACT
  22. & ~Constants.ACC_NATIVE
  23. & ~Constants.ACC_SYNCHRONIZED);
  24. if (forcePublic.contains(MethodWrapper.create(method))) {
  25. modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
  26. }
  27. return ReflectUtils.getMethodInfo(method, modifiers);
  28. }
  29. });
  30. ClassEmitter e = new ClassEmitter(v);
  31. // 生成类,继承父类,实现接口
  32. e.begin_class(Constants.V1_2,
  33. Constants.ACC_PUBLIC,
  34. // 获取代理类名称
  35. getClassName(),
  36. Type.getType(sc),
  37. (useFactory ?
  38. TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) :
  39. TypeUtils.getTypes(interfaces)),
  40. Constants.SOURCE_FILE);
  41. // 生成构造方法,父类有什么构造方法,子类就有什么构造方法
  42. List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
  43. // 生成cglib自己所需要的字段
  44. e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
  45. if (!interceptDuringConstruction) {
  46. e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE, null);
  47. }
  48. e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null);
  49. e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null);
  50. if (serialVersionUID != null) {
  51. e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID);
  52. }
  53. // 根据设置的callback生成对应字段,用来设置代理对象用有用的callback
  54. for (int i = 0; i < callbackTypes.length; i++) {
  55. e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null);
  56. }
  57. emitMethods(e, methods, actualMethods);
  58. emitConstructors(e, constructorInfo);
  59. emitSetThreadCallbacks(e);
  60. emitSetStaticCallbacks(e);
  61. emitBindCallbacks(e);
  62. if (useFactory) {
  63. int[] keys = getCallbackKeys();
  64. emitNewInstanceCallbacks(e);
  65. emitNewInstanceCallback(e);
  66. emitNewInstanceMultiarg(e, constructorInfo);
  67. emitGetCallback(e, keys);
  68. emitSetCallback(e, keys);
  69. emitGetCallbacks(e);
  70. emitSetCallbacks(e);
  71. }
  72. e.end_class();
  73. }
  1. protected Object firstInstance(Class type) throws Exception {
  2. if (classOnly) {
  3. return type;
  4. } else {
  5. return createUsingReflection(type);
  6. }
  7. }
  1. private Object createUsingReflection(Class type) {
  2. // 设置回调方法
  3. setThreadCallbacks(type, callbacks);
  4. try{
  5. if (argumentTypes != null) {
  6. return ReflectUtils.newInstance(type, argumentTypes, arguments);
  7. } else {
  8. return ReflectUtils.newInstance(type);
  9. }
  10. }finally{
  11. // clear thread callbacks to allow them to be gc'd
  12. setThreadCallbacks(type, null);
  13. }
  14. }
  1. private static void setThreadCallbacks(Class type, Callback[] callbacks) {
  2. setCallbacksHelper(type, callbacks, SET_THREAD_CALLBACKS_NAME);
  3. }
  4. private static void setCallbacksHelper(Class type, Callback[] callbacks, String methodName) {
  5. // TODO: optimize
  6. try {
  7. // 获取到对应的方法
  8. Method setter = getCallbacksSetter(type, methodName);
  9. // 静态方法执行,并传入回调方法
  10. setter.invoke(null, new Object[]{ callbacks });
  11. } catch (NoSuchMethodException e) {
  12. throw new IllegalArgumentException(type + " is not an enhanced class");
  13. } catch (IllegalAccessException e) {
  14. throw new CodeGenerationException(e);
  15. } catch (InvocationTargetException e) {
  16. throw new CodeGenerationException(e);
  17. }
  18. }

生成具体的代理类文件

在测试类中配置环境参数,指定文件生成位置:

  1. // 生成代理类文件
  2. System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "生成路径");

生成文件:

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by FernFlower decompiler)
  4. //
  5. package com.moomooyu.proxy.cglib;
  6. import java.lang.reflect.Method;
  7. import net.sf.cglib.core.ReflectUtils;
  8. import net.sf.cglib.core.Signature;
  9. import net.sf.cglib.proxy.Callback;
  10. import net.sf.cglib.proxy.Factory;
  11. import net.sf.cglib.proxy.MethodInterceptor;
  12. import net.sf.cglib.proxy.MethodProxy;
  13. public class MyCalculator$$EnhancerByCGLIB$$5f866cd3 extends MyCalculator implements Factory {
  14. private boolean CGLIB$BOUND;
  15. private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
  16. private static final Callback[] CGLIB$STATIC_CALLBACKS;
  17. private MethodInterceptor CGLIB$CALLBACK_0;
  18. private static final Method CGLIB$add$0$Method;
  19. private static final MethodProxy CGLIB$add$0$Proxy;
  20. private static final Object[] CGLIB$emptyArgs;
  21. private static final Method CGLIB$div$1$Method;
  22. private static final MethodProxy CGLIB$div$1$Proxy;
  23. private static final Method CGLIB$sub$2$Method;
  24. private static final MethodProxy CGLIB$sub$2$Proxy;
  25. private static final Method CGLIB$mul$3$Method;
  26. private static final MethodProxy CGLIB$mul$3$Proxy;
  27. private static final Method CGLIB$finalize$4$Method;
  28. private static final MethodProxy CGLIB$finalize$4$Proxy;
  29. private static final Method CGLIB$equals$5$Method;
  30. private static final MethodProxy CGLIB$equals$5$Proxy;
  31. private static final Method CGLIB$toString$6$Method;
  32. private static final MethodProxy CGLIB$toString$6$Proxy;
  33. private static final Method CGLIB$hashCode$7$Method;
  34. private static final MethodProxy CGLIB$hashCode$7$Proxy;
  35. private static final Method CGLIB$clone$8$Method;
  36. private static final MethodProxy CGLIB$clone$8$Proxy;
  37. static void CGLIB$STATICHOOK1() {
  38. CGLIB$THREAD_CALLBACKS = new ThreadLocal();
  39. CGLIB$emptyArgs = new Object[0];
  40. Class var0 = Class.forName("com.moomooyu.proxy.cglib.MyCalculator$$EnhancerByCGLIB$$5f866cd3");
  41. Class var1;
  42. Method[] var10000 = ReflectUtils.findMethods(new String[]{"add", "(II)I", "div", "(II)I", "sub", "(II)I", "mul", "(II)I"}, (var1 = Class.forName("com.moomooyu.proxy.cglib.MyCalculator")).getDeclaredMethods());
  43. CGLIB$add$0$Method = var10000[0];
  44. CGLIB$add$0$Proxy = MethodProxy.create(var1, var0, "(II)I", "add", "CGLIB$add$0");
  45. CGLIB$div$1$Method = var10000[1];
  46. CGLIB$div$1$Proxy = MethodProxy.create(var1, var0, "(II)I", "div", "CGLIB$div$1");
  47. CGLIB$sub$2$Method = var10000[2];
  48. CGLIB$sub$2$Proxy = MethodProxy.create(var1, var0, "(II)I", "sub", "CGLIB$sub$2");
  49. CGLIB$mul$3$Method = var10000[3];
  50. CGLIB$mul$3$Proxy = MethodProxy.create(var1, var0, "(II)I", "mul", "CGLIB$mul$3");
  51. var10000 = ReflectUtils.findMethods(new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
  52. CGLIB$finalize$4$Method = var10000[0];
  53. CGLIB$finalize$4$Proxy = MethodProxy.create(var1, var0, "()V", "finalize", "CGLIB$finalize$4");
  54. CGLIB$equals$5$Method = var10000[1];
  55. CGLIB$equals$5$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$5");
  56. CGLIB$toString$6$Method = var10000[2];
  57. CGLIB$toString$6$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$6");
  58. CGLIB$hashCode$7$Method = var10000[3];
  59. CGLIB$hashCode$7$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$7");
  60. CGLIB$clone$8$Method = var10000[4];
  61. CGLIB$clone$8$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$8");
  62. }
  63. final int CGLIB$add$0(int var1, int var2) {
  64. return super.add(var1, var2);
  65. }
  66. public final int add(int var1, int var2) {
  67. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  68. if (var10000 == null) {
  69. CGLIB$BIND_CALLBACKS(this);
  70. var10000 = this.CGLIB$CALLBACK_0;
  71. }
  72. if (var10000 != null) {
  73. Object var3 = var10000.intercept(this, CGLIB$add$0$Method, new Object[]{new Integer(var1), new Integer(var2)}, CGLIB$add$0$Proxy);
  74. return var3 == null ? 0 : ((Number)var3).intValue();
  75. } else {
  76. return super.add(var1, var2);
  77. }
  78. }
  79. final int CGLIB$div$1(int var1, int var2) {
  80. return super.div(var1, var2);
  81. }
  82. public final int div(int var1, int var2) {
  83. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  84. if (var10000 == null) {
  85. CGLIB$BIND_CALLBACKS(this);
  86. var10000 = this.CGLIB$CALLBACK_0;
  87. }
  88. if (var10000 != null) {
  89. Object var3 = var10000.intercept(this, CGLIB$div$1$Method, new Object[]{new Integer(var1), new Integer(var2)}, CGLIB$div$1$Proxy);
  90. return var3 == null ? 0 : ((Number)var3).intValue();
  91. } else {
  92. return super.div(var1, var2);
  93. }
  94. }
  95. final int CGLIB$sub$2(int var1, int var2) {
  96. return super.sub(var1, var2);
  97. }
  98. public final int sub(int var1, int var2) {
  99. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  100. if (var10000 == null) {
  101. CGLIB$BIND_CALLBACKS(this);
  102. var10000 = this.CGLIB$CALLBACK_0;
  103. }
  104. if (var10000 != null) {
  105. Object var3 = var10000.intercept(this, CGLIB$sub$2$Method, new Object[]{new Integer(var1), new Integer(var2)}, CGLIB$sub$2$Proxy);
  106. return var3 == null ? 0 : ((Number)var3).intValue();
  107. } else {
  108. return super.sub(var1, var2);
  109. }
  110. }
  111. final int CGLIB$mul$3(int var1, int var2) {
  112. return super.mul(var1, var2);
  113. }
  114. public final int mul(int var1, int var2) {
  115. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  116. if (var10000 == null) {
  117. CGLIB$BIND_CALLBACKS(this);
  118. var10000 = this.CGLIB$CALLBACK_0;
  119. }
  120. if (var10000 != null) {
  121. Object var3 = var10000.intercept(this, CGLIB$mul$3$Method, new Object[]{new Integer(var1), new Integer(var2)}, CGLIB$mul$3$Proxy);
  122. return var3 == null ? 0 : ((Number)var3).intValue();
  123. } else {
  124. return super.mul(var1, var2);
  125. }
  126. }
  127. final void CGLIB$finalize$4() throws Throwable {
  128. super.finalize();
  129. }
  130. protected final void finalize() throws Throwable {
  131. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  132. if (var10000 == null) {
  133. CGLIB$BIND_CALLBACKS(this);
  134. var10000 = this.CGLIB$CALLBACK_0;
  135. }
  136. if (var10000 != null) {
  137. var10000.intercept(this, CGLIB$finalize$4$Method, CGLIB$emptyArgs, CGLIB$finalize$4$Proxy);
  138. } else {
  139. super.finalize();
  140. }
  141. }
  142. final boolean CGLIB$equals$5(Object var1) {
  143. return super.equals(var1);
  144. }
  145. public final boolean equals(Object var1) {
  146. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  147. if (var10000 == null) {
  148. CGLIB$BIND_CALLBACKS(this);
  149. var10000 = this.CGLIB$CALLBACK_0;
  150. }
  151. if (var10000 != null) {
  152. Object var2 = var10000.intercept(this, CGLIB$equals$5$Method, new Object[]{var1}, CGLIB$equals$5$Proxy);
  153. return var2 == null ? false : (Boolean)var2;
  154. } else {
  155. return super.equals(var1);
  156. }
  157. }
  158. final String CGLIB$toString$6() {
  159. return super.toString();
  160. }
  161. public final String toString() {
  162. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  163. if (var10000 == null) {
  164. CGLIB$BIND_CALLBACKS(this);
  165. var10000 = this.CGLIB$CALLBACK_0;
  166. }
  167. return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$6$Method, CGLIB$emptyArgs, CGLIB$toString$6$Proxy) : super.toString();
  168. }
  169. final int CGLIB$hashCode$7() {
  170. return super.hashCode();
  171. }
  172. public final int hashCode() {
  173. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  174. if (var10000 == null) {
  175. CGLIB$BIND_CALLBACKS(this);
  176. var10000 = this.CGLIB$CALLBACK_0;
  177. }
  178. if (var10000 != null) {
  179. Object var1 = var10000.intercept(this, CGLIB$hashCode$7$Method, CGLIB$emptyArgs, CGLIB$hashCode$7$Proxy);
  180. return var1 == null ? 0 : ((Number)var1).intValue();
  181. } else {
  182. return super.hashCode();
  183. }
  184. }
  185. final Object CGLIB$clone$8() throws CloneNotSupportedException {
  186. return super.clone();
  187. }
  188. protected final Object clone() throws CloneNotSupportedException {
  189. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
  190. if (var10000 == null) {
  191. CGLIB$BIND_CALLBACKS(this);
  192. var10000 = this.CGLIB$CALLBACK_0;
  193. }
  194. return var10000 != null ? var10000.intercept(this, CGLIB$clone$8$Method, CGLIB$emptyArgs, CGLIB$clone$8$Proxy) : super.clone();
  195. }
  196. public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
  197. String var10000 = var0.toString();
  198. switch(var10000.hashCode()) {
  199. case -2131682232:
  200. if (var10000.equals("sub(II)I")) {
  201. return CGLIB$sub$2$Proxy;
  202. }
  203. break;
  204. case -1574182249:
  205. if (var10000.equals("finalize()V")) {
  206. return CGLIB$finalize$4$Proxy;
  207. }
  208. break;
  209. case -1287932281:
  210. if (var10000.equals("add(II)I")) {
  211. return CGLIB$add$0$Proxy;
  212. }
  213. break;
  214. case -508378822:
  215. if (var10000.equals("clone()Ljava/lang/Object;")) {
  216. return CGLIB$clone$8$Proxy;
  217. }
  218. break;
  219. case 303407255:
  220. if (var10000.equals("div(II)I")) {
  221. return CGLIB$div$1$Proxy;
  222. }
  223. break;
  224. case 582649156:
  225. if (var10000.equals("mul(II)I")) {
  226. return CGLIB$mul$3$Proxy;
  227. }
  228. break;
  229. case 1826985398:
  230. if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
  231. return CGLIB$equals$5$Proxy;
  232. }
  233. break;
  234. case 1913648695:
  235. if (var10000.equals("toString()Ljava/lang/String;")) {
  236. return CGLIB$toString$6$Proxy;
  237. }
  238. break;
  239. case 1984935277:
  240. if (var10000.equals("hashCode()I")) {
  241. return CGLIB$hashCode$7$Proxy;
  242. }
  243. }
  244. return null;
  245. }
  246. public MyCalculator$$EnhancerByCGLIB$$5f866cd3() {
  247. CGLIB$BIND_CALLBACKS(this);
  248. }
  249. public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
  250. CGLIB$THREAD_CALLBACKS.set(var0);
  251. }
  252. public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
  253. CGLIB$STATIC_CALLBACKS = var0;
  254. }
  255. private static final void CGLIB$BIND_CALLBACKS(Object var0) {
  256. MyCalculator$$EnhancerByCGLIB$$5f866cd3 var1 = (MyCalculator$$EnhancerByCGLIB$$5f866cd3)var0;
  257. if (!var1.CGLIB$BOUND) {
  258. var1.CGLIB$BOUND = true;
  259. Object var10000 = CGLIB$THREAD_CALLBACKS.get();
  260. if (var10000 == null) {
  261. var10000 = CGLIB$STATIC_CALLBACKS;
  262. if (var10000 == null) {
  263. return;
  264. }
  265. }
  266. var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
  267. }
  268. }
  269. public Object newInstance(Callback[] var1) {
  270. CGLIB$SET_THREAD_CALLBACKS(var1);
  271. MyCalculator$$EnhancerByCGLIB$$5f866cd3 var10000 = new MyCalculator$$EnhancerByCGLIB$$5f866cd3();
  272. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
  273. return var10000;
  274. }
  275. public Object newInstance(Callback var1) {
  276. CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
  277. MyCalculator$$EnhancerByCGLIB$$5f866cd3 var10000 = new MyCalculator$$EnhancerByCGLIB$$5f866cd3();
  278. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
  279. return var10000;
  280. }
  281. public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
  282. CGLIB$SET_THREAD_CALLBACKS(var3);
  283. MyCalculator$$EnhancerByCGLIB$$5f866cd3 var10000 = new MyCalculator$$EnhancerByCGLIB$$5f866cd3;
  284. switch(var1.length) {
  285. case 0:
  286. var10000.<init>();
  287. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
  288. return var10000;
  289. default:
  290. throw new IllegalArgumentException("Constructor not found");
  291. }
  292. }
  293. public Callback getCallback(int var1) {
  294. CGLIB$BIND_CALLBACKS(this);
  295. MethodInterceptor var10000;
  296. switch(var1) {
  297. case 0:
  298. var10000 = this.CGLIB$CALLBACK_0;
  299. break;
  300. default:
  301. var10000 = null;
  302. }
  303. return var10000;
  304. }
  305. public void setCallback(int var1, Callback var2) {
  306. switch(var1) {
  307. case 0:
  308. this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
  309. default:
  310. }
  311. }
  312. public Callback[] getCallbacks() {
  313. CGLIB$BIND_CALLBACKS(this);
  314. return new Callback[]{this.CGLIB$CALLBACK_0};
  315. }
  316. public void setCallbacks(Callback[] var1) {
  317. this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
  318. }
  319. static {
  320. CGLIB$STATICHOOK1();
  321. }
  322. }