1. 举例

  • 委托类
  1. public class DelegateClass {
  2. public DelegateClass() {
  3. }
  4. public DelegateClass(String string) {
  5. }
  6. public boolean add(String string, int i) {
  7. System.out.println("This is add method: " + string + ", " + i);
  8. return true;
  9. }
  10. public void update() {
  11. System.out.println("This is update method");
  12. }
  13. }
  • 测试
  1. public static void main(String[] args) throws Exception {
  2. // 保留生成的FastClass类文件
  3. System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\Temp\\CGLib\\FastClass");
  4. Class delegateClass = DelegateClass.class;
  5. // Java Reflect
  6. // 反射构造类
  7. Constructor delegateConstructor = delegateClass.getConstructor(String.class);
  8. // 创建委托类实例
  9. DelegateClass delegateInstance = (DelegateClass) delegateConstructor.newInstance("Tom");
  10. // 反射方法类
  11. Method addMethod = delegateClass.getMethod("add", String.class, int.class);
  12. // 调用方法
  13. addMethod.invoke(delegateInstance, "Tom", 30);
  14. Method updateMethod = delegateClass.getMethod("update");
  15. updateMethod.invoke(delegateInstance);
  16. // CGLib FastClass
  17. // FastClass动态子类实例
  18. FastClass fastClass = FastClass.create(DelegateClass.class);
  19. // 创建委托类实例
  20. DelegateClass fastInstance = (DelegateClass) fastClass.newInstance(
  21. new Class[] {String.class}, new Object[]{"Jack"});
  22. // 调用委托类方法
  23. fastClass.invoke("add", new Class[]{ String.class, int.class}, fastInstance,
  24. new Object[]{ "Jack", 25});
  25. fastClass.invoke("update", new Class[]{}, fastInstance, new Object[]{});
  26. }

2. FastClass

FastClass不使用反射类(Constructor或Method)来调用委托类方法,而是动态生成一个新的类(继承FastClass),向类中写入委托类实例直接调用方法的语句,用模板方式解决Java语法不支持问题,同时改善Java反射性能。 动态类为委托类方法调用语句建立索引,使用者根据方法签名(方法名+参数类型)得到索引值,再通过索引值进入相应的方法调用语句,得到调用结果。

  • FastClass
  1. public abstract class FastClass{
  2. // 委托类
  3. private Class type;
  4. // 子类访问构造方法
  5. protected FastClass() {}
  6. protected FastClass(Class type) {
  7. this.type = type;
  8. }
  9. // 创建动态FastClass子类
  10. public static FastClass create(Class type) {
  11. // Generator:子类生成器,继承AbstractClassGenerator
  12. Generator gen = new Generator();
  13. gen.setType(type);
  14. gen.setClassLoader(type.getClassLoader());
  15. return gen.create();
  16. }
  17. /**
  18. * 调用委托类方法
  19. *
  20. * @param name 方法名
  21. * @param parameterTypes 方法参数类型
  22. * @param obj 委托类实例
  23. * @param args 方法参数对象
  24. */
  25. public Object invoke(String name, Class[] parameterTypes, Object obj, Object[] args) {
  26. return invoke(getIndex(name, parameterTypes), obj, args);
  27. }
  28. /**
  29. * 根据方法描述符找到方法索引
  30. *
  31. * @param name 方法名
  32. * @param parameterTypes 方法参数类型
  33. */
  34. public abstract int getIndex(String name, Class[] parameterTypes);
  35. /**
  36. * 根据方法索引调用委托类方法
  37. *
  38. * @param index 方法索引
  39. * @param obj 委托类实例
  40. * @param args 方法参数对象
  41. */
  42. public abstract Object invoke(int index, Object obj, Object[] args);
  43. /**
  44. * 调用委托类构造方法
  45. *
  46. * @param parameterTypes 构造方法参数类型
  47. * @param args 构造方法参数对象
  48. */
  49. public Object newInstance(Class[] parameterTypes, Object[] args) throws {
  50. return newInstance(getIndex(parameterTypes), args);
  51. }
  52. /**
  53. * 根据构造方法描述符(参数类型)找到构造方法索引
  54. *
  55. * @param parameterTypes 构造方法参数类型
  56. */
  57. public abstract int getIndex(Class[] parameterTypes);
  58. /**
  59. * 根据构造方法索引调用委托类构造方法
  60. *
  61. * @param index 构造方法索引
  62. * @param args 构造方法参数对象
  63. */
  64. public abstract Object newInstance(int index, Object[] args);
  65. }
  • 动态子类
  1. public class DelegateClass$$FastClassByCGLIB$$4af5b667 extends FastClass {
  2. /**
  3. * 动态子类构造方法
  4. */
  5. public DelegateClass$$FastClassByCGLIB$$4af5b667(Class delegateClass) {
  6. super(delegateClass);
  7. }
  8. /**
  9. * 根据方法签名得到方法索引
  10. *
  11. * @param name 方法名
  12. * @param parameterTypes 方法参数类型
  13. */
  14. public int getIndex(String methodName, Class[] parameterTypes) {
  15. switch(methodName.hashCode()) {
  16. // 委托类方法add索引:0
  17. case 96417:
  18. if (methodName.equals("add")) {
  19. switch(parameterTypes.length) {
  20. case 2:
  21. if (parameterTypes[0].getName().equals("java.lang.String") &&
  22. parameterTypes[1].getName().equals("int")) {
  23. return 0;
  24. }
  25. }
  26. }
  27. break;
  28. // 委托类方法update索引:1
  29. case -838846263:
  30. if (methodName.equals("update")) {
  31. switch(parameterTypes.length) {
  32. case 0:
  33. return 1;
  34. }
  35. }
  36. break;
  37. // Object方法equals索引:2
  38. case -1295482945:
  39. if (methodName.equals("equals")) {
  40. switch(parameterTypes.length) {
  41. case 1:
  42. if (parameterTypes[0].getName().equals("java.lang.Object")) {
  43. return 2;
  44. }
  45. }
  46. }
  47. break;
  48. // Object方法toString索引:3
  49. case -1776922004:
  50. if (methodName.equals("toString")) {
  51. switch(parameterTypes.length) {
  52. case 0: return 3;
  53. }
  54. }
  55. break;
  56. // Object方法hashCode索引:4
  57. case 147696667:
  58. if (methodName.equals("hashCode")) {
  59. switch(parameterTypes.length) {
  60. case 0:
  61. return 4;
  62. }
  63. }
  64. }
  65. return -1;
  66. }
  67. /**
  68. * 根据方法索引调用委托类方法
  69. *
  70. * @param methodIndex 方法索引
  71. * @param delegateInstance 委托类实例
  72. * @param parameterValues 方法参数对象
  73. */
  74. public Object invoke(int methodIndex, Object delegateInstance, Object[] parameterValues) {
  75. DelegateClass instance = (DelegateClass) delegateInstance;
  76. int index = methodIndex;
  77. try {
  78. switch(index) {
  79. case 0:
  80. // 委托类实例直接调用方法语句
  81. return new Boolean(instance.add((String)parameterValues[0],
  82. ((Number)parameterValues[1]).intValue()));
  83. case 1:
  84. instance.update();
  85. return null;
  86. case 2:
  87. return new Boolean(instance.equals(parameterValues[0]));
  88. case 3:
  89. return instance.toString();
  90. case 4:
  91. return new Integer(instance.hashCode());
  92. }
  93. } catch (Throwable t) {
  94. throw new InvocationTargetException(t);
  95. }
  96. throw new IllegalArgumentException("Cannot find matching method/constructor");
  97. }
  98. /**
  99. * 根据构造方法描述符(参数类型)找到构造方法索引
  100. *
  101. * @param parameterTypes 构造方法参数类型
  102. */
  103. public int getIndex(Class[] parameterTypes) {
  104. switch(parameterTypes.length) {
  105. // 无参构造方法索引:0
  106. case 0:
  107. return 0;
  108. // 有参构造方法索引:1
  109. case 1:
  110. if (parameterTypes[0].getName().equals("java.lang.String")) {
  111. return 1;
  112. }
  113. default:
  114. return -1;
  115. }
  116. }
  117. /**
  118. * 根据构造方法索引调用委托类构造方法
  119. *
  120. * @param methodIndex 构造方法索引
  121. * @param parameterValues 构造方法参数对象
  122. */
  123. public Object newInstance(int methodIndex, Object[] parameterValues) {
  124. // 创建委托类实例
  125. DelegateClass newInstance = new DelegateClass;
  126. DelegateClass newObject = newInstance;
  127. int index = methodIndex;
  128. try {
  129. switch(index) {
  130. // 调用构造方法(<init>)
  131. case 0:
  132. newObject.<init>();
  133. return newInstance;
  134. case 1:
  135. newObject.<init>((String)parameterValues[0]);
  136. return newInstance;
  137. }
  138. } catch (Throwable t) {
  139. throw new InvocationTargetException(t);
  140. }
  141. throw new IllegalArgumentException("Cannot find matching method/constructor");
  142. }
  143. public int getMaxIndex() {
  144. return 4;
  145. }
  146. }

作者:毛小力
链接:https://www.jianshu.com/p/0604d79435f1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。