1. 举例
- 委托类
public class DelegateClass {
public DelegateClass() {
}
public DelegateClass(String string) {
}
public boolean add(String string, int i) {
System.out.println("This is add method: " + string + ", " + i);
return true;
}
public void update() {
System.out.println("This is update method");
}
}
- 测试
public static void main(String[] args) throws Exception {
// 保留生成的FastClass类文件
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\Temp\\CGLib\\FastClass");
Class delegateClass = DelegateClass.class;
// Java Reflect
// 反射构造类
Constructor delegateConstructor = delegateClass.getConstructor(String.class);
// 创建委托类实例
DelegateClass delegateInstance = (DelegateClass) delegateConstructor.newInstance("Tom");
// 反射方法类
Method addMethod = delegateClass.getMethod("add", String.class, int.class);
// 调用方法
addMethod.invoke(delegateInstance, "Tom", 30);
Method updateMethod = delegateClass.getMethod("update");
updateMethod.invoke(delegateInstance);
// CGLib FastClass
// FastClass动态子类实例
FastClass fastClass = FastClass.create(DelegateClass.class);
// 创建委托类实例
DelegateClass fastInstance = (DelegateClass) fastClass.newInstance(
new Class[] {String.class}, new Object[]{"Jack"});
// 调用委托类方法
fastClass.invoke("add", new Class[]{ String.class, int.class}, fastInstance,
new Object[]{ "Jack", 25});
fastClass.invoke("update", new Class[]{}, fastInstance, new Object[]{});
}
2. FastClass
FastClass不使用反射类(Constructor或Method)来调用委托类方法,而是动态生成一个新的类(继承FastClass),向类中写入委托类实例直接调用方法的语句,用模板方式解决Java语法不支持问题,同时改善Java反射性能。 动态类为委托类方法调用语句建立索引,使用者根据方法签名(方法名+参数类型)得到索引值,再通过索引值进入相应的方法调用语句,得到调用结果。
- FastClass
public abstract class FastClass{
// 委托类
private Class type;
// 子类访问构造方法
protected FastClass() {}
protected FastClass(Class type) {
this.type = type;
}
// 创建动态FastClass子类
public static FastClass create(Class type) {
// Generator:子类生成器,继承AbstractClassGenerator
Generator gen = new Generator();
gen.setType(type);
gen.setClassLoader(type.getClassLoader());
return gen.create();
}
/**
* 调用委托类方法
*
* @param name 方法名
* @param parameterTypes 方法参数类型
* @param obj 委托类实例
* @param args 方法参数对象
*/
public Object invoke(String name, Class[] parameterTypes, Object obj, Object[] args) {
return invoke(getIndex(name, parameterTypes), obj, args);
}
/**
* 根据方法描述符找到方法索引
*
* @param name 方法名
* @param parameterTypes 方法参数类型
*/
public abstract int getIndex(String name, Class[] parameterTypes);
/**
* 根据方法索引调用委托类方法
*
* @param index 方法索引
* @param obj 委托类实例
* @param args 方法参数对象
*/
public abstract Object invoke(int index, Object obj, Object[] args);
/**
* 调用委托类构造方法
*
* @param parameterTypes 构造方法参数类型
* @param args 构造方法参数对象
*/
public Object newInstance(Class[] parameterTypes, Object[] args) throws {
return newInstance(getIndex(parameterTypes), args);
}
/**
* 根据构造方法描述符(参数类型)找到构造方法索引
*
* @param parameterTypes 构造方法参数类型
*/
public abstract int getIndex(Class[] parameterTypes);
/**
* 根据构造方法索引调用委托类构造方法
*
* @param index 构造方法索引
* @param args 构造方法参数对象
*/
public abstract Object newInstance(int index, Object[] args);
}
- 动态子类
public class DelegateClass$$FastClassByCGLIB$$4af5b667 extends FastClass {
/**
* 动态子类构造方法
*/
public DelegateClass$$FastClassByCGLIB$$4af5b667(Class delegateClass) {
super(delegateClass);
}
/**
* 根据方法签名得到方法索引
*
* @param name 方法名
* @param parameterTypes 方法参数类型
*/
public int getIndex(String methodName, Class[] parameterTypes) {
switch(methodName.hashCode()) {
// 委托类方法add索引:0
case 96417:
if (methodName.equals("add")) {
switch(parameterTypes.length) {
case 2:
if (parameterTypes[0].getName().equals("java.lang.String") &&
parameterTypes[1].getName().equals("int")) {
return 0;
}
}
}
break;
// 委托类方法update索引:1
case -838846263:
if (methodName.equals("update")) {
switch(parameterTypes.length) {
case 0:
return 1;
}
}
break;
// Object方法equals索引:2
case -1295482945:
if (methodName.equals("equals")) {
switch(parameterTypes.length) {
case 1:
if (parameterTypes[0].getName().equals("java.lang.Object")) {
return 2;
}
}
}
break;
// Object方法toString索引:3
case -1776922004:
if (methodName.equals("toString")) {
switch(parameterTypes.length) {
case 0: return 3;
}
}
break;
// Object方法hashCode索引:4
case 147696667:
if (methodName.equals("hashCode")) {
switch(parameterTypes.length) {
case 0:
return 4;
}
}
}
return -1;
}
/**
* 根据方法索引调用委托类方法
*
* @param methodIndex 方法索引
* @param delegateInstance 委托类实例
* @param parameterValues 方法参数对象
*/
public Object invoke(int methodIndex, Object delegateInstance, Object[] parameterValues) {
DelegateClass instance = (DelegateClass) delegateInstance;
int index = methodIndex;
try {
switch(index) {
case 0:
// 委托类实例直接调用方法语句
return new Boolean(instance.add((String)parameterValues[0],
((Number)parameterValues[1]).intValue()));
case 1:
instance.update();
return null;
case 2:
return new Boolean(instance.equals(parameterValues[0]));
case 3:
return instance.toString();
case 4:
return new Integer(instance.hashCode());
}
} catch (Throwable t) {
throw new InvocationTargetException(t);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
/**
* 根据构造方法描述符(参数类型)找到构造方法索引
*
* @param parameterTypes 构造方法参数类型
*/
public int getIndex(Class[] parameterTypes) {
switch(parameterTypes.length) {
// 无参构造方法索引:0
case 0:
return 0;
// 有参构造方法索引:1
case 1:
if (parameterTypes[0].getName().equals("java.lang.String")) {
return 1;
}
default:
return -1;
}
}
/**
* 根据构造方法索引调用委托类构造方法
*
* @param methodIndex 构造方法索引
* @param parameterValues 构造方法参数对象
*/
public Object newInstance(int methodIndex, Object[] parameterValues) {
// 创建委托类实例
DelegateClass newInstance = new DelegateClass;
DelegateClass newObject = newInstance;
int index = methodIndex;
try {
switch(index) {
// 调用构造方法(<init>)
case 0:
newObject.<init>();
return newInstance;
case 1:
newObject.<init>((String)parameterValues[0]);
return newInstance;
}
} catch (Throwable t) {
throw new InvocationTargetException(t);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 4;
}
}
作者:毛小力
链接:https://www.jianshu.com/p/0604d79435f1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。