其实我们如果看到了cglib所生成的代理类之后,其实就不难猜测,cglib是如何去生成代理类了,我们看一个完整的代理类:

    1. //
    2. // Source code recreated from a .class file by IntelliJ IDEA
    3. // (powered by FernFlower decompiler)
    4. //
    5. package com.zhouyu;
    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 UserService$$EnhancerByCGLIB$$4d890297 extends UserService implements Factory {
    14. private boolean CGLIB$BOUND;
    15. public static Object CGLIB$FACTORY_DATA;
    16. private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    17. private static final Callback[] CGLIB$STATIC_CALLBACKS;
    18. private MethodInterceptor CGLIB$CALLBACK_0;
    19. private static Object CGLIB$CALLBACK_FILTER;
    20. private static final Method CGLIB$test$0$Method;
    21. private static final MethodProxy CGLIB$test$0$Proxy;
    22. private static final Object[] CGLIB$emptyArgs;
    23. private static final Method CGLIB$equals$1$Method;
    24. private static final MethodProxy CGLIB$equals$1$Proxy;
    25. private static final Method CGLIB$toString$2$Method;
    26. private static final MethodProxy CGLIB$toString$2$Proxy;
    27. private static final Method CGLIB$hashCode$3$Method;
    28. private static final MethodProxy CGLIB$hashCode$3$Proxy;
    29. private static final Method CGLIB$clone$4$Method;
    30. private static final MethodProxy CGLIB$clone$4$Proxy;
    31. static void CGLIB$STATICHOOK1() {
    32. CGLIB$THREAD_CALLBACKS = new ThreadLocal();
    33. CGLIB$emptyArgs = new Object[0];
    34. Class var0 = Class.forName("com.zhouyu.UserService$$EnhancerByCGLIB$$4d890297");
    35. Class var1;
    36. Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
    37. CGLIB$equals$1$Method = var10000[0];
    38. CGLIB$equals$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
    39. CGLIB$toString$2$Method = var10000[1];
    40. CGLIB$toString$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
    41. CGLIB$hashCode$3$Method = var10000[2];
    42. CGLIB$hashCode$3$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$3");
    43. CGLIB$clone$4$Method = var10000[3];
    44. CGLIB$clone$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
    45. CGLIB$test$0$Method = ReflectUtils.findMethods(new String[]{"test", "()V"}, (var1 = Class.forName("com.zhouyu.UserService")).getDeclaredMethods())[0];
    46. CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test", "CGLIB$test$0");
    47. }
    48. final void CGLIB$test$0() {
    49. super.test();
    50. }
    51. public final void test() {
    52. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
    53. if (var10000 == null) {
    54. CGLIB$BIND_CALLBACKS(this);
    55. var10000 = this.CGLIB$CALLBACK_0;
    56. }
    57. if (var10000 != null) {
    58. var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);
    59. } else {
    60. super.test();
    61. }
    62. }
    63. final boolean CGLIB$equals$1(Object var1) {
    64. return super.equals(var1);
    65. }
    66. public final boolean equals(Object var1) {
    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 var2 = var10000.intercept(this, CGLIB$equals$1$Method, new Object[]{var1}, CGLIB$equals$1$Proxy);
    74. return var2 == null ? false : (Boolean)var2;
    75. } else {
    76. return super.equals(var1);
    77. }
    78. }
    79. final String CGLIB$toString$2() {
    80. return super.toString();
    81. }
    82. public final String toString() {
    83. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
    84. if (var10000 == null) {
    85. CGLIB$BIND_CALLBACKS(this);
    86. var10000 = this.CGLIB$CALLBACK_0;
    87. }
    88. return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy) : super.toString();
    89. }
    90. final int CGLIB$hashCode$3() {
    91. return super.hashCode();
    92. }
    93. public final int hashCode() {
    94. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
    95. if (var10000 == null) {
    96. CGLIB$BIND_CALLBACKS(this);
    97. var10000 = this.CGLIB$CALLBACK_0;
    98. }
    99. if (var10000 != null) {
    100. Object var1 = var10000.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy);
    101. return var1 == null ? 0 : ((Number)var1).intValue();
    102. } else {
    103. return super.hashCode();
    104. }
    105. }
    106. final Object CGLIB$clone$4() throws CloneNotSupportedException {
    107. return super.clone();
    108. }
    109. protected final Object clone() throws CloneNotSupportedException {
    110. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
    111. if (var10000 == null) {
    112. CGLIB$BIND_CALLBACKS(this);
    113. var10000 = this.CGLIB$CALLBACK_0;
    114. }
    115. return var10000 != null ? var10000.intercept(this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy) : super.clone();
    116. }
    117. public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
    118. String var10000 = var0.toString();
    119. switch(var10000.hashCode()) {
    120. case -1422510685:
    121. if (var10000.equals("test()V")) {
    122. return CGLIB$test$0$Proxy;
    123. }
    124. break;
    125. case -508378822:
    126. if (var10000.equals("clone()Ljava/lang/Object;")) {
    127. return CGLIB$clone$4$Proxy;
    128. }
    129. break;
    130. case 1826985398:
    131. if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
    132. return CGLIB$equals$1$Proxy;
    133. }
    134. break;
    135. case 1913648695:
    136. if (var10000.equals("toString()Ljava/lang/String;")) {
    137. return CGLIB$toString$2$Proxy;
    138. }
    139. break;
    140. case 1984935277:
    141. if (var10000.equals("hashCode()I")) {
    142. return CGLIB$hashCode$3$Proxy;
    143. }
    144. }
    145. return null;
    146. }
    147. public UserService$$EnhancerByCGLIB$$4d890297() {
    148. CGLIB$BIND_CALLBACKS(this);
    149. }
    150. public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
    151. CGLIB$THREAD_CALLBACKS.set(var0);
    152. }
    153. public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
    154. CGLIB$STATIC_CALLBACKS = var0;
    155. }
    156. private static final void CGLIB$BIND_CALLBACKS(Object var0) {
    157. UserService$$EnhancerByCGLIB$$4d890297 var1 = (UserService$$EnhancerByCGLIB$$4d890297)var0;
    158. if (!var1.CGLIB$BOUND) {
    159. var1.CGLIB$BOUND = true;
    160. Object var10000 = CGLIB$THREAD_CALLBACKS.get();
    161. if (var10000 == null) {
    162. var10000 = CGLIB$STATIC_CALLBACKS;
    163. if (var10000 == null) {
    164. return;
    165. }
    166. }
    167. var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
    168. }
    169. }
    170. public Object newInstance(Callback[] var1) {
    171. CGLIB$SET_THREAD_CALLBACKS(var1);
    172. UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297();
    173. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
    174. return var10000;
    175. }
    176. public Object newInstance(Callback var1) {
    177. CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
    178. UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297();
    179. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
    180. return var10000;
    181. }
    182. public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
    183. CGLIB$SET_THREAD_CALLBACKS(var3);
    184. UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297;
    185. switch(var1.length) {
    186. case 0:
    187. var10000.<init>();
    188. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
    189. return var10000;
    190. default:
    191. throw new IllegalArgumentException("Constructor not found");
    192. }
    193. }
    194. public Callback getCallback(int var1) {
    195. CGLIB$BIND_CALLBACKS(this);
    196. MethodInterceptor var10000;
    197. switch(var1) {
    198. case 0:
    199. var10000 = this.CGLIB$CALLBACK_0;
    200. break;
    201. default:
    202. var10000 = null;
    203. }
    204. return var10000;
    205. }
    206. public void setCallback(int var1, Callback var2) {
    207. switch(var1) {
    208. case 0:
    209. this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
    210. default:
    211. }
    212. }
    213. public Callback[] getCallbacks() {
    214. CGLIB$BIND_CALLBACKS(this);
    215. return new Callback[]{this.CGLIB$CALLBACK_0};
    216. }
    217. public void setCallbacks(Callback[] var1) {
    218. this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
    219. }
    220. static {
    221. CGLIB$STATICHOOK1();
    222. }
    223. }

    我们发现,UserService代理类既继承了UserService类,也实现了Factory接口,从而代理中就需要去实现Factory接口中的几个方法:

    1. public Object newInstance(Callback[] var1) {
    2. CGLIB$SET_THREAD_CALLBACKS(var1);
    3. UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297();
    4. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
    5. return var10000;
    6. }
    7. public Object newInstance(Callback var1) {
    8. CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
    9. UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297();
    10. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
    11. return var10000;
    12. }
    13. public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
    14. CGLIB$SET_THREAD_CALLBACKS(var3);
    15. UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297;
    16. switch(var1.length) {
    17. case 0:
    18. var10000.<init>();
    19. CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
    20. return var10000;
    21. default:
    22. throw new IllegalArgumentException("Constructor not found");
    23. }
    24. }
    25. public Callback getCallback(int var1) {
    26. CGLIB$BIND_CALLBACKS(this);
    27. MethodInterceptor var10000;
    28. switch(var1) {
    29. case 0:
    30. var10000 = this.CGLIB$CALLBACK_0;
    31. break;
    32. default:
    33. var10000 = null;
    34. }
    35. return var10000;
    36. }
    37. public void setCallback(int var1, Callback var2) {
    38. switch(var1) {
    39. case 0:
    40. this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
    41. default:
    42. }
    43. }
    44. public Callback[] getCallbacks() {
    45. CGLIB$BIND_CALLBACKS(this);
    46. return new Callback[]{this.CGLIB$CALLBACK_0};
    47. }
    48. public void setCallbacks(Callback[] var1) {
    49. this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
    50. }

    我们可以发现newInstance()方法会重新生成一个代理对象,setCallbacks()和getCallbacks()可以用来设置或获取增强逻辑。

    我们还发现,不仅只有test()方法会生成对应的两个方法,其他方法也会生成,比如:

    1. equals()
    2. toString()
    3. hashCode()
    4. clone()

    对于这些方法的实现上篇文章已经有所介绍了,所以我们再看一下一下代理类中还有什么代码是我们不熟悉的:

    1. //
    2. // Source code recreated from a .class file by IntelliJ IDEA
    3. // (powered by FernFlower decompiler)
    4. //
    5. package com.zhouyu;
    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 UserService$$EnhancerByCGLIB$$4d890297 extends UserService implements Factory {
    14. private boolean CGLIB$BOUND;
    15. public static Object CGLIB$FACTORY_DATA;
    16. private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    17. private static final Callback[] CGLIB$STATIC_CALLBACKS;
    18. private MethodInterceptor CGLIB$CALLBACK_0;
    19. private static Object CGLIB$CALLBACK_FILTER;
    20. private static final Method CGLIB$test$0$Method;
    21. private static final MethodProxy CGLIB$test$0$Proxy;
    22. private static final Object[] CGLIB$emptyArgs;
    23. private static final Method CGLIB$equals$1$Method;
    24. private static final MethodProxy CGLIB$equals$1$Proxy;
    25. private static final Method CGLIB$toString$2$Method;
    26. private static final MethodProxy CGLIB$toString$2$Proxy;
    27. private static final Method CGLIB$hashCode$3$Method;
    28. private static final MethodProxy CGLIB$hashCode$3$Proxy;
    29. private static final Method CGLIB$clone$4$Method;
    30. private static final MethodProxy CGLIB$clone$4$Proxy;
    31. static void CGLIB$STATICHOOK1() {
    32. CGLIB$THREAD_CALLBACKS = new ThreadLocal();
    33. CGLIB$emptyArgs = new Object[0];
    34. Class var0 = Class.forName("com.zhouyu.UserService$$EnhancerByCGLIB$$4d890297");
    35. Class var1;
    36. Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
    37. CGLIB$equals$1$Method = var10000[0];
    38. CGLIB$equals$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
    39. CGLIB$toString$2$Method = var10000[1];
    40. CGLIB$toString$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
    41. CGLIB$hashCode$3$Method = var10000[2];
    42. CGLIB$hashCode$3$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$3");
    43. CGLIB$clone$4$Method = var10000[3];
    44. CGLIB$clone$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
    45. CGLIB$test$0$Method = ReflectUtils.findMethods(new String[]{"test", "()V"}, (var1 = Class.forName("com.zhouyu.UserService")).getDeclaredMethods())[0];
    46. CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test", "CGLIB$test$0");
    47. }
    48. final void CGLIB$test$0() {
    49. super.test();
    50. }
    51. public final void test() {
    52. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
    53. if (var10000 == null) {
    54. CGLIB$BIND_CALLBACKS(this);
    55. var10000 = this.CGLIB$CALLBACK_0;
    56. }
    57. if (var10000 != null) {
    58. var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);
    59. } else {
    60. super.test();
    61. }
    62. }
    63. public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
    64. String var10000 = var0.toString();
    65. switch(var10000.hashCode()) {
    66. case -1422510685:
    67. if (var10000.equals("test()V")) {
    68. return CGLIB$test$0$Proxy;
    69. }
    70. break;
    71. case -508378822:
    72. if (var10000.equals("clone()Ljava/lang/Object;")) {
    73. return CGLIB$clone$4$Proxy;
    74. }
    75. break;
    76. case 1826985398:
    77. if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
    78. return CGLIB$equals$1$Proxy;
    79. }
    80. break;
    81. case 1913648695:
    82. if (var10000.equals("toString()Ljava/lang/String;")) {
    83. return CGLIB$toString$2$Proxy;
    84. }
    85. break;
    86. case 1984935277:
    87. if (var10000.equals("hashCode()I")) {
    88. return CGLIB$hashCode$3$Proxy;
    89. }
    90. }
    91. return null;
    92. }
    93. public UserService$$EnhancerByCGLIB$$4d890297() {
    94. CGLIB$BIND_CALLBACKS(this);
    95. }
    96. public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
    97. CGLIB$THREAD_CALLBACKS.set(var0);
    98. }
    99. public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
    100. CGLIB$STATIC_CALLBACKS = var0;
    101. }
    102. private static final void CGLIB$BIND_CALLBACKS(Object var0) {
    103. UserService$$EnhancerByCGLIB$$4d890297 var1 = (UserService$$EnhancerByCGLIB$$4d890297)var0;
    104. if (!var1.CGLIB$BOUND) {
    105. var1.CGLIB$BOUND = true;
    106. Object var10000 = CGLIB$THREAD_CALLBACKS.get();
    107. if (var10000 == null) {
    108. var10000 = CGLIB$STATIC_CALLBACKS;
    109. if (var10000 == null) {
    110. return;
    111. }
    112. }
    113. var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
    114. }
    115. }
    116. static {
    117. CGLIB$STATICHOOK1();
    118. }
    119. }

    我们发现代理中有很多的属性,仔细阅读可以发现,这些属性中很多都是针对某个方法的Method对象和MethodProxy对象,我们先把equals等所对应的先去掉:

    1. //
    2. // Source code recreated from a .class file by IntelliJ IDEA
    3. // (powered by FernFlower decompiler)
    4. //
    5. package com.zhouyu;
    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 UserService$$EnhancerByCGLIB$$4d890297 extends UserService implements Factory {
    14. private boolean CGLIB$BOUND;
    15. public static Object CGLIB$FACTORY_DATA;
    16. private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    17. private static final Callback[] CGLIB$STATIC_CALLBACKS;
    18. private MethodInterceptor CGLIB$CALLBACK_0;
    19. private static Object CGLIB$CALLBACK_FILTER;
    20. private static final Method CGLIB$test$0$Method;
    21. private static final MethodProxy CGLIB$test$0$Proxy;
    22. private static final Object[] CGLIB$emptyArgs;
    23. static void CGLIB$STATICHOOK1() {
    24. CGLIB$THREAD_CALLBACKS = new ThreadLocal();
    25. CGLIB$emptyArgs = new Object[0];
    26. Class var0 = Class.forName("com.zhouyu.UserService$$EnhancerByCGLIB$$4d890297");
    27. Class var1;
    28. Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
    29. CGLIB$test$0$Method = ReflectUtils.findMethods(new String[]{"test", "()V"}, (var1 = Class.forName("com.zhouyu.UserService")).getDeclaredMethods())[0];
    30. CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test", "CGLIB$test$0");
    31. }
    32. final void CGLIB$test$0() {
    33. super.test();
    34. }
    35. public final void test() {
    36. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
    37. if (var10000 == null) {
    38. CGLIB$BIND_CALLBACKS(this);
    39. var10000 = this.CGLIB$CALLBACK_0;
    40. }
    41. if (var10000 != null) {
    42. var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);
    43. } else {
    44. super.test();
    45. }
    46. }
    47. public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
    48. String var10000 = var0.toString();
    49. switch(var10000.hashCode()) {
    50. case -1422510685:
    51. if (var10000.equals("test()V")) {
    52. return CGLIB$test$0$Proxy;
    53. }
    54. break;
    55. case -508378822:
    56. if (var10000.equals("clone()Ljava/lang/Object;")) {
    57. return CGLIB$clone$4$Proxy;
    58. }
    59. break;
    60. case 1826985398:
    61. if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
    62. return CGLIB$equals$1$Proxy;
    63. }
    64. break;
    65. case 1913648695:
    66. if (var10000.equals("toString()Ljava/lang/String;")) {
    67. return CGLIB$toString$2$Proxy;
    68. }
    69. break;
    70. case 1984935277:
    71. if (var10000.equals("hashCode()I")) {
    72. return CGLIB$hashCode$3$Proxy;
    73. }
    74. }
    75. return null;
    76. }
    77. public UserService$$EnhancerByCGLIB$$4d890297() {
    78. CGLIB$BIND_CALLBACKS(this);
    79. }
    80. public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
    81. CGLIB$THREAD_CALLBACKS.set(var0);
    82. }
    83. public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
    84. CGLIB$STATIC_CALLBACKS = var0;
    85. }
    86. private static final void CGLIB$BIND_CALLBACKS(Object var0) {
    87. UserService$$EnhancerByCGLIB$$4d890297 var1 = (UserService$$EnhancerByCGLIB$$4d890297)var0;
    88. if (!var1.CGLIB$BOUND) {
    89. var1.CGLIB$BOUND = true;
    90. Object var10000 = CGLIB$THREAD_CALLBACKS.get();
    91. if (var10000 == null) {
    92. var10000 = CGLIB$STATIC_CALLBACKS;
    93. if (var10000 == null) {
    94. return;
    95. }
    96. }
    97. var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
    98. }
    99. }
    100. static {
    101. CGLIB$STATICHOOK1();
    102. }
    103. }

    代理类中有一个代理块,会调用CGLIB$STATICHOOK1(),这个方法主要就是给属性赋值,比如:

    1. 构造一个ThreadLocal对象给CGLIB$THREAD_CALLBACKS属性
    2. 获取UserService类中的test方法的Method对象给CGLIB$test$0$Method属性
    3. 构造test()方法所对应的MethodProxy对象给CGLIB$test$0$Proxy属性

    另外,代理类中还有一些其他方法,但是我看了源码后,发现有几个方法它只是生成了,并没有被调用到,其中有一个方法是cglib在生成代理对象后,会主动调用的一个方法,这个方法是CGLIB$SET_THREAD_CALLBACKS,我把其他几个不用的方法去掉:

    1. //
    2. // Source code recreated from a .class file by IntelliJ IDEA
    3. // (powered by FernFlower decompiler)
    4. //
    5. package com.zhouyu;
    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 UserService$$EnhancerByCGLIB$$4d890297 extends UserService implements Factory {
    14. private boolean CGLIB$BOUND;
    15. public static Object CGLIB$FACTORY_DATA;
    16. private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    17. private static final Callback[] CGLIB$STATIC_CALLBACKS;
    18. private MethodInterceptor CGLIB$CALLBACK_0;
    19. private static Object CGLIB$CALLBACK_FILTER;
    20. private static final Method CGLIB$test$0$Method;
    21. private static final MethodProxy CGLIB$test$0$Proxy;
    22. private static final Object[] CGLIB$emptyArgs;
    23. static void CGLIB$STATICHOOK1() {
    24. CGLIB$THREAD_CALLBACKS = new ThreadLocal();
    25. CGLIB$emptyArgs = new Object[0];
    26. Class var0 = Class.forName("com.zhouyu.UserService$$EnhancerByCGLIB$$4d890297");
    27. Class var1;
    28. Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
    29. CGLIB$test$0$Method = ReflectUtils.findMethods(new String[]{"test", "()V"}, (var1 = Class.forName("com.zhouyu.UserService")).getDeclaredMethods())[0];
    30. CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test", "CGLIB$test$0");
    31. }
    32. final void CGLIB$test$0() {
    33. super.test();
    34. }
    35. public final void test() {
    36. MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
    37. if (var10000 == null) {
    38. CGLIB$BIND_CALLBACKS(this);
    39. var10000 = this.CGLIB$CALLBACK_0;
    40. }
    41. if (var10000 != null) {
    42. var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);
    43. } else {
    44. super.test();
    45. }
    46. }
    47. // 构造方法
    48. public UserService$$EnhancerByCGLIB$$4d890297() {
    49. CGLIB$BIND_CALLBACKS(this);
    50. }
    51. public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
    52. CGLIB$THREAD_CALLBACKS.set(var0);
    53. }
    54. private static final void CGLIB$BIND_CALLBACKS(Object var0) {
    55. UserService$$EnhancerByCGLIB$$4d890297 var1 = (UserService$$EnhancerByCGLIB$$4d890297)var0;
    56. if (!var1.CGLIB$BOUND) {
    57. var1.CGLIB$BOUND = true;
    58. Object var10000 = CGLIB$THREAD_CALLBACKS.get();
    59. if (var10000 == null) {
    60. var10000 = CGLIB$STATIC_CALLBACKS;
    61. if (var10000 == null) {
    62. return;
    63. }
    64. }
    65. var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
    66. }
    67. }
    68. static {
    69. CGLIB$STATICHOOK1();
    70. }
    71. }

    这样,我们就可以更加理解这个代理类了,大致流程是:

    1. cglib先生成代理类
    2. 然后调用构造方法得到代理对象
    3. 然后cglib调用代理对象的CGLIB$SET_THREAD_CALLBACKS()方法,把程序员所设置的Callbacks设置到CGLIB$THREAD_CALLBACKS这个ThreadLocal中
    4. 后续代理对象在执行test()方法时,就会从CGLIB$THREAD_CALLBACKS拿到所设置的Callbacks,调用其intercept()方法

    而代理类的生成逻辑就是:

    1. 先生成类的定义,实现UserService和Factory接口
    2. 根据UserService类中的方法生成代理类中对应的方法和属性
    3. 生成一些辅助的属性和方法

    具体源码就不去分析了,感兴趣的可以自己花时间去啃了。

    文章到这里,还有还有一个点没分析,就是MethodProxy对象,下篇文章继续。