-1
public class CustomerDTO {
    private int customerId;
    private String customerName;
    private String customerAddress;

    public int getCustomerId() {
        return customerId;
    }
    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }
    public String getCustomerName() {
        return customerName;
    }
    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
    public String getCustomerAddress() {
        return customerAddress;
    }
    public void setCustomerAddress(String customerAddress) {
        this.customerAddress = customerAddress;
    }
}

CustomerDAO 类:

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

public final class CustomerDAO {
    private CustomerDTO customer;

    public void setCustomer(CustomerDTO customer) {
        this.customer = customer;
    }

    //Trying to get copy of object with BeanUtils
    public final CustomerDTO getCustomer(int customerId){
        CustomerDTO origCustomer = _springContext.getBean(CustomerDTO.class);
        CustomerDTO targetCustomer=null;
        if("you get customer based on customer id") then "targetCustomer got initialized";
        BeanUtils.copyProperties(targetCustomer, origCustomer);//spring BeanUtils
    }

    //Trying to add object returned by above method into the list
    public final List<CustomerDTO> getCustomerList(List<Integer> customerIds){
        List<CustomerDTO> customerList = new ArrayList<CustomerDTO>();
        for(Integer id:customerIds){
            CustomerDTO customer = getCustomer(id);
            System.out.println("correct output: "+customer.getCustomerId());//getting correct output here
            customerList.add(customer);//Trying to add copied object in list
        }
        for(CustomerDTO customer: customerList){
            System.out.println("wrong output: "+customer.getCustomerId());//getting wrong output here
        }
        return Collections.unmodifiableList(customerList);
    }
}

CustomerDTO getCustomer(int customerId)方法中,我试图通过使用 Spring 返回 CustomerDTO 对象的副本BeanUtils.copyProperties(targetCustomer, origCustomer);,但是当我在方法中的列表中添加这些复制的对象时,List<CustomerDTO> getCustomerList(List<Integer> customerIds)我得到了评论中提到的奇怪行为。如果我要删除BeanUtils.copyProperties(targetCustomer, origCustomer);,那么行为是正确的。

测试用例:

getCustomerList with customerIds =[1,2,3,4]

使用复制的对象BeanUtils.copyProperties(targetCustomer, origCustomer);//spring BeanUtils

correct output: 1
correct output: 2
correct output: 3
correct output: 4
wrong output: 4
wrong output: 4
wrong output: 4
wrong output: 4

没有复制的对象: BeanUtils.copyProperties(targetCustomer, origCustomer); //spring BeanUtils

correct output: 1
correct output: 2
correct output: 3
correct output: 4
wrong output: 1
wrong output: 2
wrong output: 3
wrong output: 4

有人可以解释一下这种行为有什么问题或可能的解释吗?

更新:使用 BeanUtils 的目的:

我试图在从方法返回 CustomerDTO 对象之前使用可变对象的防御性副本getCustomer()。所以我尝试在这篇文章之后使用浅克隆。

更新:删除了 Immutability 这个词,因为它是错误的使用。

4

2 回答 2

1

你使用了错误的工具。

您的问题是您将 Spring bean 与 Java bean 混合在一起。

Spring bean 是一个单例,因此您的 Spring 上下文中只有一个CustomerDTO。Spring 上下文不能替代真正的 DAO。

在 DAO 中使用 aMap或数据库,不要尝试使用 Spring 上下文进行数据存储和检索操作。

于 2013-07-09T06:05:22.857 回答
0
wrong output: 4
wrong output: 4
wrong output: 4
wrong output: 4

如果列表包含相同的对象,则可能会发生这种情况,那么为什么列表包含相同的对象以及后续如何工作?

correct output: 1
correct output: 2
correct output: 3
correct output: 4

origCustomer 包含对 CustomerDTO@60bc92 的引用,它是由 spring 维护的单例,所以它总是有相同的引用。targetCustomer 的参考将更改。但是 BeanUtils.copyProperties(targetCustomer, origCustomer); 将 targetCustomer 的属性复制到 origCustomer 意味着 CustomerDTO@60bc92。

for(Integer id:customerIds){
            CustomerDTO customer = getCustomer(id);
            System.out.println("correct output: "+customer.getCustomerId());//getting correct output here
            customerList.add(customer);//Trying to add copied object in list
        }

for(customer ids 1 to 4){
       customer will get reference CustomerDTO@60bc92 and will be updated based on customer ids
       so it is printing correct values 
       but it is adding same reference CustomerDTO@60bc92 to the list
}

 for(CustomerDTO customer: customerList){
            System.out.println("wrong output: "+customer.getCustomerId());//getting wrong output here
        }

for(all customer object in list which is same object reference and having latest value means 4){
      it is printing wrong value as 4
}

现在为什么 origCustomer 是从 Spring 上下文创建的,比如

CustomerDTO origCustomer = _springContext.getBean(CustomerDTO.class);

因为来自 spring 的 BeanUtils 需要默认初始化的 spring bean。

这个问题的解决方案:

CustomerDTO origCustomer = new CustomerDTO();

并使用 BeanUtilsorg.apache.commons.beanutils.BeanUtils;

于 2013-07-09T10:00:26.007 回答