|
|
|
@ -19,7 +19,6 @@ package org.springframework.beans;
@@ -19,7 +19,6 @@ package org.springframework.beans;
|
|
|
|
|
import java.beans.PropertyDescriptor; |
|
|
|
|
import java.beans.PropertyEditor; |
|
|
|
|
import java.lang.reflect.Constructor; |
|
|
|
|
import java.lang.reflect.Field; |
|
|
|
|
import java.lang.reflect.InvocationTargetException; |
|
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
import java.lang.reflect.Modifier; |
|
|
|
@ -46,7 +45,7 @@ import org.apache.commons.logging.LogFactory;
@@ -46,7 +45,7 @@ import org.apache.commons.logging.LogFactory;
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.KotlinDetector; |
|
|
|
|
import org.springframework.core.MethodParameter; |
|
|
|
|
import org.springframework.core.convert.TypeDescriptor; |
|
|
|
|
import org.springframework.core.ResolvableType; |
|
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
|
import org.springframework.util.Assert; |
|
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
@ -683,11 +682,12 @@ public abstract class BeanUtils {
@@ -683,11 +682,12 @@ public abstract class BeanUtils {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Copy the property values of the given source bean into the given target bean |
|
|
|
|
* and ignored if |
|
|
|
|
* Copy the property values of the given source bean into the given target bean. |
|
|
|
|
* <p>Note: The source and target classes do not have to match or even be derived |
|
|
|
|
* from each other, as long as the properties match. Any bean properties that the |
|
|
|
|
* source bean exposes but the target bean does not will silently be ignored. |
|
|
|
|
* <p>As of Spring Framework 5.3, this method honors generic type information |
|
|
|
|
* when matching properties in the source and target objects. |
|
|
|
|
* @param source the source bean |
|
|
|
|
* @param target the target bean |
|
|
|
|
* @param editable the class (or interface) to restrict property setting to |
|
|
|
@ -717,30 +717,25 @@ public abstract class BeanUtils {
@@ -717,30 +717,25 @@ public abstract class BeanUtils {
|
|
|
|
|
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) { |
|
|
|
|
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName()); |
|
|
|
|
if (sourcePd != null) { |
|
|
|
|
Field sourcefield = ReflectionUtils.findField(source.getClass(), sourcePd.getName()); |
|
|
|
|
Field targetfield = ReflectionUtils.findField(target.getClass(), targetPd.getName()); |
|
|
|
|
|
|
|
|
|
TypeDescriptor sourceTypeDescriptor = new TypeDescriptor(sourcefield); |
|
|
|
|
TypeDescriptor targetTypeDescriptor = new TypeDescriptor(targetfield); |
|
|
|
|
|
|
|
|
|
Method readMethod = sourcePd.getReadMethod(); |
|
|
|
|
|
|
|
|
|
if (readMethod != null && |
|
|
|
|
ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType()) && |
|
|
|
|
sourceTypeDescriptor.getResolvableType().equals(targetTypeDescriptor.getResolvableType())) { |
|
|
|
|
try { |
|
|
|
|
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { |
|
|
|
|
readMethod.setAccessible(true); |
|
|
|
|
if (readMethod != null) { |
|
|
|
|
ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readMethod); |
|
|
|
|
ResolvableType targetResolvableType = ResolvableType.forMethodParameter(writeMethod, 0); |
|
|
|
|
if (targetResolvableType.isAssignableFrom(sourceResolvableType)) { |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|