使用javassist代替反射完成类属性操作工具类

工作当中经常遇到需要使用反射进行成员变量遍历的工作,但是使用反射的效率在高并发的情况下会比较低,这里使用了javassit的方式生成了对应的处理类,通过其实例化对象完成遍历工作 


package com.ylink.ncpc.common.util;


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


import org.apache.commons.lang.text.StrBuilder;


import com.ylink.ncpc.common.pojo.CommonRspPojo;


import javassist.CannotCompileException;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;


/**
 * 描述:使用该工具类替代反射,运行效率提高三倍以上
 * 
 * @author songmengqiang 2015年10月26日
 */
public class FeildUtil1 {
public static void main(String[] args) {
CommonRspPojo c = new CommonRspPojo();
long cc = 1000000;
c.setReturn_code("c");
c.setReturn_msg("m");
test(c, cc);
testTmp(c, cc);
}


private static void test(CommonRspPojo c, long cc) {
final List<String> ss = new ArrayList<>();
long currentTimeMillis0 = System.currentTimeMillis();
FeildUtil1.iterate(c, new FeildCallback() {


@Override
public String busiDesc() {
return "CommonRspPojoTest";
}


@Override
public void busi(String fieldName, Object object) {
ss.add((String) object);
}
});
System.out.println("创建处理类使用的时间(毫秒):" + (System.currentTimeMillis() - currentTimeMillis0));


long currentTimeMillis = System.currentTimeMillis();
for (int i = 0; i < cc; i++) {
FeildUtil1.iterate(c, new FeildCallback() {


@Override
public String busiDesc() {
return "CommonRspPojoTest";
}


@Override
public void busi(String fieldName, Object object) {
ss.add((String) object);
}
});
}
System.out.println(ss.size());
System.out.println("javasist使用时间(毫秒):" + (System.currentTimeMillis() - currentTimeMillis));
}


private static void testTmp(CommonRspPojo c, long cc) {
final List<String> ss1 = new ArrayList<>();
FeildUtil1.iterateTemp(c, new FeildCallback() {
@Override
public String busiDesc() {
return "CommonRspPojoTest1";
}


@Override
public void busi(String fieldName, Object object) {
ss1.add((String) object);
}
});
long currentTimeMillis = System.currentTimeMillis();
for (int i = 0; i < cc; i++) {
FeildUtil1.iterateTemp(c, new FeildCallback() {
@Override
public String busiDesc() {
return "CommonRspPojoTest";
}


@Override
public void busi(String fieldName, Object object) {
ss1.add((String) object);
}
});
}
System.out.println(ss1.size());
System.out.println("反射机制使用时间(毫秒):" + (System.currentTimeMillis() - currentTimeMillis));
}


/**
* 通过反射做业务处理,但是反射的性能消耗会比较大,不推荐使用

* @param object
* @param FeildUtil1Callback
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
@Deprecated
public static void iterateTemp(Object object, FeildCallback FeildUtil1Callback) {
try {
Field[] declaredFields = object.getClass().getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
String fieldName = field.getName();
Object fieldObj = field.get(object);
FeildUtil1Callback.busi(fieldName, fieldObj);
}
} catch (Exception e) {
e.printStackTrace();
}
}


/**
* 描述:该遍历器用来遍历所有的成员变量,如果该成员变量有对应的get方法则会调用 callback进行处理

* @param o
* @param fCallback
*/
public static void iterate(Object o, FeildCallback fCallback) {
String busiDesc = fCallback.busiDesc();
FeildHandlerInterface FeildUtil1Interface = handlerMap.get(busiDesc);
if (FeildUtil1Interface == null) {
try {
FeildUtil1Interface = createHandler(o, busiDesc);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
FeildUtil1Interface.iterate(o, fCallback);
}


@SuppressWarnings("unchecked")
private static synchronized FeildHandlerInterface createHandler(Object o, String busiDesc)
throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException {
//===start 当一个线程已经创建完毕,另一个线程刚好进入到该方法时则直接返回创建的结果
FeildHandlerInterface FeildUtil1Interface = handlerMap.get(busiDesc);
if (FeildUtil1Interface != null) {
return FeildUtil1Interface;
}
//===end

// 反射获取属性名数组
Class<? extends Object> class1 = o.getClass();
int busiDescHash = busiDesc.hashCode();
Field[] fields = class1.getDeclaredFields();


Map<String, Method> methodMap = new HashMap<>();
Method[] methods = class1.getMethods();
for (Method method : methods) {
methodMap.put(method.getName(), method);
}
// 反射获取类名
String classPath = class1.getName();
String name = FeildCallback.class.getName();
// 创建类继承FeildUtil1Interface
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(FeildUtil1.class));
CtClass newClass = pool.makeClass("com.ylink.ncpc.common.util.Handler" + busiDescHash);
CtClass[] list = new CtClass[] { pool.getCtClass("com.ylink.ncpc.common.util.FeildHandlerInterface") };
newClass.setInterfaces(list);
// 创建方法实现FeildUtil1Interface.iterate(o, fCallback);
String methodString = "public  void iterate(Object o," + name + " fCallback){\n" + " " + classPath + " tt=("
+ classPath + ")o;\n";
for (Field field : fields) {
if (methodMap.containsKey("get" + capitalise(field.getName()))) {
methodString += "fCallback.busi(\"" + field.getName() + "\",tt.get" + capitalise(field.getName())
+ "());\n";
}
}
methodString += "}\n";
CtMethod f = CtNewMethod.make(methodString, newClass);
newClass.addMethod(f);
Class<FeildHandlerInterface> realClass = newClass.toClass();
FeildHandlerInterface newInstance = realClass.newInstance();
handlerMap.put(busiDesc, newInstance);
return newInstance;
}


/**
* 首字母大写

* @param str
* @return
*/
private static String capitalise(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return str;
}
return new StrBuilder(strLen).append(Character.toTitleCase(str.charAt(0))).append(str.substring(1)).toString();
}


private static Map<String, FeildHandlerInterface> handlerMap = new ConcurrentHashMap<String, FeildHandlerInterface>();
}


interface FeildHandlerInterface {
public abstract void iterate(Object o, FeildCallback fCallback);
}



package com.ylink.ncpc.common.util;



public abstract class FeildCallback{
/**
* 描述:该方法实现具体的业务
* @param fieldName
* @param object
*/
public abstract void busi(String fieldName,Object object);
/**
* 描述必须全局唯一,如果存在一样的定义,那可能会有冲突。
* 不能返回空。。
* @return
*/
public abstract String busiDesc();

}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值