BeanCopier 详解「建议收藏」

BeanCopier 详解「建议收藏」 BeanCopier实现属性拷贝的主要代码: BeanCopierbeanCopier=BeanCopier.create(dad.getClass(),dadly.getClass(),false); beanCopier.copy(dad,dadly,null);  查看BeanCopier源码可知: abstractpublicclass…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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

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

 beanCopier.copy(dad, dadly, null);

 

 查看BeanCopier源码可知:

 

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为抽象类,并且:

 

 

abstract public void copy(Object from, Object to, Converter converter);

 
copy为抽象方法,在cglib的包里我们找不到
BeanCopier的实现类。

 

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

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

 并且:

 

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)方法完成的,如下是此方法源码:

 

    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()方法,即如何复制相同名称的属性。

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

   

// 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:   <generated>

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()
    {
    }
}

 

 

  

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/197033.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • oracle 存储过程

    oracle 存储过程

  • Golang语言快速上手到综合实战笔记(Go语言、Beego框架、高并发聊天室、爬虫)

    Golang语言快速上手到综合实战笔记(Go语言、Beego框架、高并发聊天室、爬虫)

  • VC编程入门浅谈「建议收藏」

    VC编程入门浅谈「建议收藏」
    学VC并不是传说的那么难,可不下些功夫是学不成的。学编程急不得,没有编程的基础知识上来就学VC肯定碰一头灰,说VC难就难在这点上了。如果硬上,意志坚强的话还能挺过来,但最后还得回头来补习基础知识。意志不坚强的话,很有可能就此放弃,并留下一个VC难得不得了的印象。

      其实,只要踏踏实实一步一步来,学VC很简单。对于没有编程基础的人首先要学习编程的基础知识,如变量,语句,基本的算法等,然后写一些小的程序,实现些常用算法对自己的思维是很好的锻炼,对以后的学习大有好处。起码要能排

  • 编程路上必定要知道的数据库语言SPL

    编程路上必定要知道的数据库语言SPL要说清这个目标,先要理解数据库是做什么的。数据库这个软件,名字中有个“库”字,会让人觉得它主要是为了存储的。其实不然,数据库实现的重要功能有两条:计算、事务!也就是我们常说的OLAP和OLTP,数据库的存储都是为这两件事服务的,单纯的存储并不是数据库的目标。我们知道,SQL是目前数据库的主流语言。那么,用SQL做这两件事是不是很方便呢?事务类功能主要解决数据在写入和读出时要保持的一致性,实现这件事的难度并不小,但对于应用程序的接口却非常简单,用于操纵数据库读写的代码也很简单。如果假定目前关系数据库的逻辑存储

  • JAVA HD japan_E3X-HD光纤放大器_欧姆龙继电器_欧姆龙PLC_欧姆龙接近开关「建议收藏」

    JAVA HD japan_E3X-HD光纤放大器_欧姆龙继电器_欧姆龙PLC_欧姆龙接近开关「建议收藏」欧姆龙E3X-HD光纤放大器特点免维护免维护,长期稳定检测【智能功率控制】针对LED常年老化造成的投光量降低及脏污等导致的受光量降低现象,通过智能功率控制功能,自动感知并保持最佳检测状态。环境适应性强,免维护。想要检测各种颜色,大小的工件在所有检测场合中游刃有余搭载发光元件GIGARAYⅡE3X-HD特点6同级最高水准的GIGARAYII的压倒性大功率,黑橡胶等低反射率检测及大型被检测…

  • linux上 mysql数据库备份与还原 (mysqldump)

    linux上 mysql数据库备份与还原 (mysqldump)最近要写mysql数据库备份,把自己所得记录下来,防止以后忘了,哈哈哈哈(注 这是远程备份,备份到指定服务器)使用环境   centos7   mysql5.7    远程连接主机免密码登录,   在运行服务器上执行  ssh-keygen   一路回车,还是不要添加密码的好,这时候可以注意一下公钥,秘钥保存位置  把公钥放到备份的服务器上 ssh-…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号