java实现把一个bean的属性复制到另一个bean中的几种实现方案

本文介绍了Java中将一个bean的属性复制到另一个bean的七种实现方式,包括Spring BeanUtils工具类、Apache Commons BeanUtils、反射、CGLIB的BeanCopier、Spring的CGLIB BeanCopier、ModelMapper以及MapStruct。每种方法都有其特点和适用场景,如BeanUtils的完全复制、反射的灵活性以及MapStruct的接口定义等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.

java使用 org.springframework.beans.BeanUtils 工具类,把一个bean的属性值复制到另一个bean中,前提是这个复制的bean的字段要完全包含在被复制的bean中

代码如下

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    private String name;

    private String city;

    private Integer age;
}

@Data
public class Child extends Person{

    private String hobby;

    private String work;

}

import org.springframework.beans.BeanUtils;

public class CopyBean {

    public static void main(String[] args) {
        Person person = new Person("jack", "北京", 12);

        Child child = new Child();

        BeanUtils.copyProperties(person,child);

        child.setHobby("看电视");
        child.setWork("看门");

        System.out.println(child.getCity());
    }
}

可以实现bean之间的属性的完全复制

2.使用org.apache.commons.beanutils.BeanUtils.copyProperties

需要的jar包

<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    private String name;

    private String city;

    private Integer age;
}

@Data
public class Child extends Person{

    private String hobby;

    private String work;

}

import org.apache.commons.beanutils.BeanUtils;

public class CopyBean {

    public static void main(String[] args) throws Exception{
        Person person = new Person("jack", "北京", 12);
        Child child = new Child();
        BeanUtils.copyProperties(child,person);

        System.out.println(child.getName());
    }
}

与第一种实现方式的不同在于,source和target的位置相反

3.反射实现

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    private String name;

    private String city;

    private Integer age;
}

@Data
public class Child extends Person{

    private String hobby;

    private String work;

}



import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class CopyBean {

    public static void main(String[] args) throws Exception{
        Person person = new Person("jack", "北京", 12);

        Child child = new Child();

        child = copyBean(child,person);

        System.out.println(child.getName());
    }

    public static <T extends PO, PO> T copyBean(T dest, PO source) throws             IntrospectionException {
        BeanInfo beanInfo = Introspector.getBeanInfo(dest.getClass()) ;
        PropertyDescriptor[] pdes = beanInfo.getPropertyDescriptors() ;
        for(int i = 0,length =pdes.length ;i<length ;i++ ){
            PropertyDescriptor pd = pdes[i] ;
            try {
                PropertyDescriptor sourcePd = new PropertyDescriptor(pd.getName(), source.getClass()) ;
                Method sourceMethod = sourcePd.getReadMethod() ;
                Object result = sourceMethod.invoke(source) ;
                Method pdWriteMethod = pd.getWriteMethod() ;
                pdWriteMethod.invoke(dest, result) ;
            } catch (Exception e) {
                continue ;
            }
        }
        return dest ;
    }
}

4.使用 net.sf.cglib.beans.BeanCopier.copy的方式,需要自定义转换器Converter实现类

需要的jar包

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.1</version>
</dependency>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    private String name;

    private String city;

    private Integer age;
}

@Data
public class Child extends Person{

    private String hobby;

    private String work;

}

//自定义转换类 converter的具体实现类

import net.sf.cglib.core.Converter;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;

public class CopyConverter implements Converter {
    @Override
    public Object convert(Object value, Class target, Object context) {

        String s = value.toString();
        if (target.equals(int.class) || target.equals(Integer.class)) {
            return Integer.parseInt(s);
        }
        if (target.equals(long.class) || target.equals(Long.class)) {
            return Long.parseLong(s);
        }
        if (target.equals(float.class) || target.equals(Float.class)) {
            return Float.parseFloat(s);
        }
        if (target.equals(double.class) || target.equals(Double.class)) {
            return Double.parseDouble(s);
        }
        if (target.equals(Date.class)) {
            while (s.indexOf("-") > 0) {
                s = s.replace("-", "/");
            }
            return new Date(s);
        }
        if (target.equals(BigDecimal.class)) {
            if (!StringUtils.isEmpty(s) && !s.equals("NaN")) {
                return new BigDecimal(s);
            }
        }
        return value;
    }
}



import net.sf.cglib.beans.BeanCopier;


public class CopyBean {

    public static void main(String[] args) throws Exception{
        Person person = new Person("jack", "北京", 12);
        Child child = new Child();

        BeanCopier beanCopier = BeanCopier.create(Person.class,
                Child.class, true);

        beanCopier.copy(person, child, new CopyConverter());

        System.out.println(child.getCity());
    }


}

5.使用org.springframework.cglib.beans.BeanCopier.copy

实现方式同4

6.Orika实现方式  Orika 是 Java Bean 映射框架,可以实现从一个对象递归拷贝数据至另一个对象。它的优点是:名字相同类型不同也能直接复制

需要的jar包

<dependency>
    <groupId>ma.glasnost.orika</groupId>
    <artifactId>orika-core</artifactId>
    <version>1.5.4</version>
</dependency>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    private String name;

    private String city;

    private Integer age;
}


@Data
public class Child extends Person{

    private String hobby;

    private String work;

}


import ma.glasnost.orika.impl.DefaultMapperFactory;

public class CopyBean {

    public static void main(String[] args) throws Exception{
        Person person = new Person("jack", "北京", 12);
        Child child = new Child();

        new DefaultMapperFactory.Builder().build().getMapperFacade().map(person,child);

        System.out.println(child.getName());
    }
}

7.使用MapStruct实现

需要的jar 包

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.3.0.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.3.0.Final</version>
</dependency>

首先定义Mapper转换接口

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface CopyMapper {

    @Mapping(source = "name",target = "name")
    Child mapperToBean(Person person);

}

再通过反射机制实现复制bean

import org.mapstruct.factory.Mappers;

public class CopyBean {

    public static void main(String[] args) throws Exception {
        Person person = new Person("jack", "北京", 12);

        CopyMapper copyMapper = Mappers.getMapper(CopyMapper.class);
        Child child = copyMapper.mapperToBean(person);

        System.out.println(child.getAge());
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值