BeanCopier 详解「建议收藏」

BeanCopier 详解「建议收藏」

大家好,又见面了,我是你们的朋友全栈君。

BeanCopier 实现属性拷贝的主要代码:

BeanCopier beanCopier = BeanCopier.create(dad.getClass(), dadly.getClass(), false);

beanCopier.copy(dad, dadly, null);

查看BeanCopier源码可知:

代码语言:javascript复制abstract public class BeanCopier

{

private static final BeanCopierKey KEY_FACTORY =

(BeanCopierKey)KeyFactory.create(BeanCopierKey.class);

private static final Type CONVERTER =

TypeUtils.parseType("net.sf.cglib.core.Converter");

private static final Type BEAN_COPIER =

TypeUtils.parseType("net.sf.cglib.beans.BeanCopier");

private static final Signature COPY =

new Signature("copy", Type.VOID_TYPE, new Type[]{ Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER });

private static final Signature CONVERT =

TypeUtils.parseSignature("Object convert(Object, Class, Object)");

BeanCopier为抽象类,并且:

代码语言:javascript复制abstract public void copy(Object from, Object to, Converter converter);

copy为抽象方法,在cglib的包里我们找不到

BeanCopier的实现类。

由此我们可以根据此行代码:

BeanCopier beanCopier = BeanCopier.create(dad.getClass(), dadly.getClass(), false);

并且:

代码语言:javascript复制public static BeanCopier create(Class source, Class target, boolean useConverter) {

Generator gen = new Generator();

gen.setSource(source);

gen.setTarget(target);

gen.setUseConverter(useConverter);

return gen.create();

}

public static class Generator extends AbstractClassGenerator {

....

public BeanCopier create() {

Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter);

return (BeanCopier)super.create(key);

}

...

} 由此可知:

beanCopier 的实际创建工作是由AbstractClassGenerator类的create(Class type)方法完成的,如下是此方法源码:

代码语言:javascript复制 protected Object create(Object key) {

try {

Class gen = null;

synchronized (source) {

ClassLoader loader = getClassLoader();

Map cache2 = null;

cache2 = (Map)source.cache.get(loader);

if (cache2 == null) {

cache2 = new HashMap();

cache2.put(NAME_KEY, new HashSet());

source.cache.put(loader, cache2);

} else if (useCache) {

Reference ref = (Reference)cache2.get(key);

gen = (Class) (( ref == null ) ? null : ref.get());

}

if (gen == null) {

Object save = CURRENT.get();

CURRENT.set(this);

try {

this.key = key;

if (attemptLoad) {

try {

gen = loader.loadClass(getClassName());

} catch (ClassNotFoundException e) {

// ignore

}

}

if (gen == null) {

byte[] b = strategy.generate(this);

String className = ClassNameReader.getClassName(new ClassReader(b));

getClassNameCache(loader).add(className);

gen = ReflectUtils.defineClass(className, b, loader);

}

if (useCache) {

cache2.put(key, new WeakReference(gen));

}

return firstInstance(gen);

} finally {

CURRENT.set(save);

}

}

}

return firstInstance(gen);

} catch (RuntimeException e) {

throw e;

} catch (Error e) {

throw e;

} catch (Exception e) {

throw new CodeGenerationException(e);

}

} 熟悉cglib动态代理源码的都知道,此处代码就是cglib操作字节码生成动态代理类的主要实现方法。

所以beanCopier 实际上是BeanCopier的代理类,该代理类实现了 copy()方法,即如何复制相同名称的属性。

以下是生成的动态代理类:

代码语言:javascript复制// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov Date: 2013/10/17 22:01:37

// Home Page : http://members.fortunecity.com/neshkov/dj.html - Check often for new version!

// Decompiler options: packimports(3)

// Source File Name:

package proxy;

import net.sf.cglib.beans.BeanCopier;

import net.sf.cglib.core.Converter;

// Referenced classes of package proxy:

// Dadly, Dad

public class Dadly$$BeanCopierByCGLIB$$a6acdbb5 extends BeanCopier

{

public void copy(Object obj, Object obj1, Converter converter)

{

(Dadly)obj1;

(Dad)obj;

JVM INSTR dup2 ;

getAge();

setAge();

JVM INSTR dup2 ;

getName();

setName();

}

public Dadly$$BeanCopierByCGLIB$$a6acdbb5()

{

}

}版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

相关推荐

中药药浴的操作方法和药物选择都有哪些?
bt365全程担保

中药药浴的操作方法和药物选择都有哪些?

📅 11-08 👁️ 8618
【真假对比】教你如何辨别洋河海之蓝真伪!
365bet官网开户

【真假对比】教你如何辨别洋河海之蓝真伪!

📅 09-01 👁️ 1458
为什么选择隐藏式行车记录仪?
365bet官网开户

为什么选择隐藏式行车记录仪?

📅 10-01 👁️ 5434
2025浪琴表国际马联场地障碍世界杯中国联赛总决赛在成都收官
【每日皮肤评
bt365全程担保

【每日皮肤评

📅 11-16 👁️ 1674
风暴聚集
bt365全程担保

风暴聚集

📅 10-22 👁️ 5277