Struts中Form2Bean的两种reflect机制 以及性能对比
来源:互联网 发布:深圳经纬之创网络 编辑:程序博客网 时间:2024/06/08 15:12
在用Struts开发时,在Web层需要一个FormBean,在Model层又需要一个ModelBean,而这两个Bean几乎是一模一样的(FormBean中可能会有一些界面控制的隐含域属性),起码ModelBean所需要的数据在FormBean中全部都有。
在编程中,需要将FormBean的值传递给ModelBean,通常需要用很多的:
ModelBean.setXxx(FormBean.getXxx());
烦不胜烦。 利用java的reflect机制可以偷个懒,但是偷懒归偷懒,不能忽略了性能。
下面就是用两种不同的算法实现的FormBean→ModelBean的方法,其性能差距是比较大的,而且Bean的属性越多,这种差距就越大。代码如下:
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import com.perspace.model.Relation;
import com.perspace.struts.form.RelationForm;
public class BeanUtil ...{
/** *//**
* @parameter Object obj1,Object obj2
* @return Object 用到反射机制 此方法将调用obj1的getter方法,将得到的值作为相应的参数传给obj2的setter方法
* 注意,obj1的getter方法和obj2方法必须是public类型
*/
public static Object duplicateBeans(Object obj1, Object obj2)
throws Exception ...{
Method[] method1 = obj1.getClass().getMethods();
Method[] method2 = obj2.getClass().getMethods();
String methodName1;
String propertyName1;
String methodName2;
String propertyName2;
for (int i = 0; i < method1.length; i++) ...{
methodName1 = method1[i].getName();
propertyName1 = methodName1.substring(3, methodName1.length());
if (methodName1.startsWith("get")) ...{
for (int j = 0; j < method2.length; j++) ...{
methodName2 = method2[j].getName();
propertyName2 = methodName2.substring(3, methodName2
.length());
if (methodName2.startsWith("set")) ...{
if (propertyName2.equals(propertyName1)) ...{
Object[] objs1 = new Object[0];
Object[] objs2 = new Object[1];
// 激活obj1的相应的get的方法,objs1数组存放调用该方法的参数,此例中没有参数,该数组的长度为0
objs2[0] = method1[i].invoke(obj1, objs1);
// 激活obj2的相应的set的方法,objs2数组存放调用该方法的参数
method2[j].invoke(obj2, objs2);
continue;
}
}
}
}
}
return obj2;
}
/** *//**
* do the following things: bean2.setXxx(bean1.getXxx());
* Note:
* bean1 maybe have more properties than bean2, bean2 gets all values if bean1 has.
* @param bean1
* @param bean2
* @return
*/
public static Object duplicateBean2(Object bean1, Object bean2)
throws Exception ...{
Method[] method1 = bean1.getClass().getMethods();
Method[] method2 = bean2.getClass().getMethods();
HashMap map1 = new HashMap();
HashMap map2 = new HashMap();
String methodName;
String propertyName;
for (int i = 0; i < method1.length; i++) ...{
methodName = method1[i].getName();
if (methodName.startsWith("get")) ...{
propertyName = methodName.substring(3, methodName.length());
map1.put(propertyName, methodName);
}
}
for (int i = 0; i < method2.length; i++) ...{
methodName = method2[i].getName();
if (methodName.startsWith("set")) ...{
propertyName = methodName.substring(3, methodName.length());
map2.put(propertyName, methodName);
}
}
int propertyCount = map2.size();
String key;
Object getterMethod;
Iterator iterator = map2.keySet().iterator();
while (iterator.hasNext())...{
key = (String)iterator.next();
getterMethod = map1.get(key);
if (getterMethod != null)...{
Object[] objs1 = new Object[0];
Object[] objs2 = new Object[1];
// 激活obj1的相应的get的方法,objs1数组存放调用该方法的参数,此例中没有参数,该数组的长度为0
objs2[0] = bean1.getClass().getMethod(((String)getterMethod), null).invoke(bean1, objs1);
// 激活obj2的相应的set的方法,objs2数组存放调用该方法的参数
bean2.getClass().getMethod((String)map2.get(key), String.class).invoke(bean2, objs2);
}
}
return bean2;
}
public static void main(String[] args)...{
RelationForm rf = new RelationForm();
Relation r = new Relation();
Relation r1 = new Relation();
rf.setId("2342342342342342");
rf.setId1("11111111111111");
rf.setId2("22222222222222222");
rf.setType("type");
rf.setGrade("grade");
rf.setDate("date");
rf.setNote("note");
try...{
long begin = System.currentTimeMillis();
r = (Relation)BeanUtil.duplicateBeans(rf, r);
long end = System.currentTimeMillis();
System.out.println("first run:" + (end -begin));
long begin1 = System.currentTimeMillis();
r1 = (Relation)BeanUtil.duplicateBean2(rf, r1);
long end1 = System.currentTimeMillis();
System.out.println("second run:" + (end1 -begin1));
}catch(Exception e)...{
e.printStackTrace();
}
System.out.println(r.getId() + ":" + r.getId1() + ":" + r.getId2() + ":" + r.getType() + ":" + r.getGrade() + ":" + r.getDate() + ":" + r.getNote());
}
}
import java.util.HashMap;
import java.util.Iterator;
import com.perspace.model.Relation;
import com.perspace.struts.form.RelationForm;
public class BeanUtil ...{
/** *//**
* @parameter Object obj1,Object obj2
* @return Object 用到反射机制 此方法将调用obj1的getter方法,将得到的值作为相应的参数传给obj2的setter方法
* 注意,obj1的getter方法和obj2方法必须是public类型
*/
public static Object duplicateBeans(Object obj1, Object obj2)
throws Exception ...{
Method[] method1 = obj1.getClass().getMethods();
Method[] method2 = obj2.getClass().getMethods();
String methodName1;
String propertyName1;
String methodName2;
String propertyName2;
for (int i = 0; i < method1.length; i++) ...{
methodName1 = method1[i].getName();
propertyName1 = methodName1.substring(3, methodName1.length());
if (methodName1.startsWith("get")) ...{
for (int j = 0; j < method2.length; j++) ...{
methodName2 = method2[j].getName();
propertyName2 = methodName2.substring(3, methodName2
.length());
if (methodName2.startsWith("set")) ...{
if (propertyName2.equals(propertyName1)) ...{
Object[] objs1 = new Object[0];
Object[] objs2 = new Object[1];
// 激活obj1的相应的get的方法,objs1数组存放调用该方法的参数,此例中没有参数,该数组的长度为0
objs2[0] = method1[i].invoke(obj1, objs1);
// 激活obj2的相应的set的方法,objs2数组存放调用该方法的参数
method2[j].invoke(obj2, objs2);
continue;
}
}
}
}
}
return obj2;
}
/** *//**
* do the following things: bean2.setXxx(bean1.getXxx());
* Note:
* bean1 maybe have more properties than bean2, bean2 gets all values if bean1 has.
* @param bean1
* @param bean2
* @return
*/
public static Object duplicateBean2(Object bean1, Object bean2)
throws Exception ...{
Method[] method1 = bean1.getClass().getMethods();
Method[] method2 = bean2.getClass().getMethods();
HashMap map1 = new HashMap();
HashMap map2 = new HashMap();
String methodName;
String propertyName;
for (int i = 0; i < method1.length; i++) ...{
methodName = method1[i].getName();
if (methodName.startsWith("get")) ...{
propertyName = methodName.substring(3, methodName.length());
map1.put(propertyName, methodName);
}
}
for (int i = 0; i < method2.length; i++) ...{
methodName = method2[i].getName();
if (methodName.startsWith("set")) ...{
propertyName = methodName.substring(3, methodName.length());
map2.put(propertyName, methodName);
}
}
int propertyCount = map2.size();
String key;
Object getterMethod;
Iterator iterator = map2.keySet().iterator();
while (iterator.hasNext())...{
key = (String)iterator.next();
getterMethod = map1.get(key);
if (getterMethod != null)...{
Object[] objs1 = new Object[0];
Object[] objs2 = new Object[1];
// 激活obj1的相应的get的方法,objs1数组存放调用该方法的参数,此例中没有参数,该数组的长度为0
objs2[0] = bean1.getClass().getMethod(((String)getterMethod), null).invoke(bean1, objs1);
// 激活obj2的相应的set的方法,objs2数组存放调用该方法的参数
bean2.getClass().getMethod((String)map2.get(key), String.class).invoke(bean2, objs2);
}
}
return bean2;
}
public static void main(String[] args)...{
RelationForm rf = new RelationForm();
Relation r = new Relation();
Relation r1 = new Relation();
rf.setId("2342342342342342");
rf.setId1("11111111111111");
rf.setId2("22222222222222222");
rf.setType("type");
rf.setGrade("grade");
rf.setDate("date");
rf.setNote("note");
try...{
long begin = System.currentTimeMillis();
r = (Relation)BeanUtil.duplicateBeans(rf, r);
long end = System.currentTimeMillis();
System.out.println("first run:" + (end -begin));
long begin1 = System.currentTimeMillis();
r1 = (Relation)BeanUtil.duplicateBean2(rf, r1);
long end1 = System.currentTimeMillis();
System.out.println("second run:" + (end1 -begin1));
}catch(Exception e)...{
e.printStackTrace();
}
System.out.println(r.getId() + ":" + r.getId1() + ":" + r.getId2() + ":" + r.getType() + ":" + r.getGrade() + ":" + r.getDate() + ":" + r.getNote());
}
}
执行结果如下:
first run:15
second run:0
2342342342342342:11111111111111:22222222222222222:type:grade:date:note
可见,第二种算法比第一种算法要优化很多。在Struts大量做form2Model的环境中,这种点滴的积累还是很可观的。
另外:优化归优化,但是一直这个second run=0的结果让我十分不解,难道性能真的好的不到一个milli second就可以执行完?
还是我的测试方法有问题?各位一起探讨一下吧
- Struts中Form2Bean的两种reflect机制 以及性能对比
- Java中ReentrantLock和synchronized两种锁定机制的对比
- JS代码中!!的用法,以及代码性能对比
- 两种不同字符串比较方法的性能对比
- ReentrantLock和synchronized两种锁定机制的对比
- Go的reflect机制和reflect包
- iOS多线程安全的几种解决方案以及性能对比
- Java设计模式(四):原型模式深拷贝的两种实现方式,以及和new对象的性能测试对比
- SqlServer两种分页以及效率对比
- Java中字符串两种等于的方法的对比
- Java中读取Map的两种方法对比
- Java中读取Map的两种方法对比
- Oracle数据库中B-Tree以及BitMap index 的性能对比
- Oracle数据库中B-Tree以及BitMap index 的性能对比
- btHashMap vs std::unodered_map ——两种hashmap的性能对比测试
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- 一个月的轮休假——我的梦想
- 关于电脑的兼容和选配
- frame buffer device驱动程序 --zt
- Modern C++ Design 书中的两个错误
- Cookie备忘
- Struts中Form2Bean的两种reflect机制 以及性能对比
- 内嵌Python import时undefined symbol错误及解决
- 无题——异曲同工
- SOA学习
- 2006年最经典爆笑、低调变态的精品语录
- 介绍对象,我又做错了
- 网页中的平衡、对比、连贯和留白
- 动态树的创建
- 单点登录方案(SSO)