1 Star 0 Fork 28

johnhan / hp-reflect

forked from 快鸟 / hp-reflect 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 2.57 KB
一键复制 编辑 原始数据 按行查看 历史
快鸟 提交于 2018-08-14 21:48 . update

hp-reflect (high performance reflect)

项目介绍

hp-reflect 是一个高性能的反射工具。它使用字节码技术动态生成 access class。通过不同的 access class,可以高效的获取字段的值,或者调用方法,或者生成实例。
在基础框架中非常实用。

软件实现

使用 javassist 动态生成 access class,让JDK原生的反射调用可以通过一个具体的实体类来实现直接调用,而不是反射调用,大大提高的反射性能。
举例:
比如我知道一个类 A 的实例 instance 和需要调用的方法名 methodX ,我们使用 JDK 来反射调用的话,会使用如下代码:

instance.getClass().getMethod("methodX", xxxType).invoke(instance, xxx);

同样,我也可以通过生成如下的字节码来调用方法 methodX:

public class A {
	public Object methodX(xxxType param) {
		......
	}
	public Object methodY(yyyType param) {
		......
	}
}

// 利用动态字节码技术生成类似如下类
public class AMethodAccess {
	public Object invoke(Object instance, String methodName, Object[] params){
		A a = (A) instance;
		switch(methodName) {
			case "methodX":
				return a.methodX(params[0]);
			case "methodY":
				return a.methodY(params[0]);
			default:
				throw new RuntimeException("method not found:" + methodName);
		}
	}
}

// 实际调用
new AMethodAccess().invoke(instance, "methodX"), new Object[]{param});

沿着这个思路,我们就可以利用 javassist 来动态生成字节码,并实例化出我们想要的 access 类,这样就能像直接调用方法一样来实现反射了。
同理,对类属性 field 和 构造函数 constructor 也可以采用类似的方法来加快反射调用速度。

上面的思想是参考 RelectASM,不过 RelectASM 是使用 asm 来实现的,且不支持 private 类型的方法和属性的调用。所以这里就使用 javassist 来实现了一把,并且加入扩展了 private 类型的方法和属性的调用,让它更加通用。

使用说明

  • 1 调用类方法
	MethodAccess methodAccess = MethodAccess.get(fooInstance.getClass());
	Object rlt = methodAccess.invoke(fooInstance, "method11", "xxx");
  • 2 获取/设置类属性的值
	FieldAccess fieldAccess = FieldAccess.get(fooInstance.getClass());
	fieldAccess.set(fooInstance, "stringField1", "abc");
  • 3 实例化一个类
	ConstructorAccess<FooService> access = ConstructorAccess.get(FooService.class);
    FooService fooService = access.newInstance();
Java
1
https://gitee.com/han/hp-reflect.git
git@gitee.com:han/hp-reflect.git
han
hp-reflect
hp-reflect
master

搜索帮助