BeanCopier 详解「建议收藏」

BeanCopier 详解「建议收藏」

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

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

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

beanCopier.copy(dad, dadly, null);

查看BeanCopier源码可知:

代码语言:javascript代码运行次数:0运行复制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代码运行次数:0运行复制abstract public void copy(Object from, Object to, Converter converter);

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

BeanCopier的实现类。

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

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

并且:

代码语言:javascript代码运行次数:0运行复制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代码运行次数:0运行复制 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代码运行次数:0运行复制// 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()

{

}

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

相关推荐

Logitech G HUB版本大全-3DM软件

Logitech G HUB版本大全-3DM软件

日博365网 07-04
阅读更多
linux查看tomcat是否启动命令

linux查看tomcat是否启动命令

日博365网 06-27
阅读更多
Kinect 中文教程¶

Kinect 中文教程¶

有人被365黑过钱吗 07-02
阅读更多