How to use BeanUtils.copyProperties?

前端 未结 3 1643
臣服心动
臣服心动 2020-12-24 08:14

I am trying to copy properties from one bean to another. Here are the signature of two beans:

SearchContent:

public cla         


        
相关标签:
3条回答
  • 2020-12-24 08:40

    There are two BeanUtils.copyProperties(parameter1, parameter2) in Java.

    One is

    org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest, Object orig)

    Another is

    org.springframework.beans.BeanUtils.copyProperties(Object source, Object target)

    Pay attention to the opposite position of parameters.

    0 讨论(0)
  • 2020-12-24 08:46

    If you want to copy from searchContent to content, then code should be as follows

    BeanUtils.copyProperties(content, searchContent);
    

    You need to reverse the parameters as above in your code.

    From API,

    public static void copyProperties(Object dest, Object orig)
                               throws IllegalAccessException,
                                      InvocationTargetException)
    

    Parameters:

    dest - Destination bean whose properties are modified

    orig - Origin bean whose properties are retrieved

    0 讨论(0)
  • 2020-12-24 08:50

    As you can see in the below source code, BeanUtils.copyProperties internally uses reflection and there's additional internal cache lookup steps as well which is going to add cost wrt performance

     private static void copyProperties(Object source, Object target, @Nullable Class<?> editable,
                    @Nullable String... ignoreProperties) throws BeansException {
    
                Assert.notNull(source, "Source must not be null");
                Assert.notNull(target, "Target must not be null");
    
                Class<?> actualEditable = target.getClass();
                if (editable != null) {
                    if (!editable.isInstance(target)) {
                        throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
                                "] not assignable to Editable class [" + editable.getName() + "]");
                    }
                    actualEditable = editable;
                }
                **PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);**
                List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
    
                for (PropertyDescriptor targetPd : targetPds) {
                    Method writeMethod = targetPd.getWriteMethod();
                    if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
                        PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
                        if (sourcePd != null) {
                            Method readMethod = sourcePd.getReadMethod();
                            if (readMethod != null &&
                                    ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                                try {
                                    if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                                        readMethod.setAccessible(true);
                                    }
                                    Object value = readMethod.invoke(source);
                                    if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                        writeMethod.setAccessible(true);
                                    }
                                    writeMethod.invoke(target, value);
                                }
                                catch (Throwable ex) {
                                    throw new FatalBeanException(
                                            "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
                                }
                            }
                        }
                    }
                }
            }
    

    So it's better to use plain setters given the cost reflection

    0 讨论(0)
提交回复
热议问题