How to use BeanUtils.copyProperties?

烂漫一生 提交于 2019-11-30 00:30:36
Raghu

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

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.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!