์๋ก
์คํ๋ง์ ๊ณต๋ถํ๋ค ๋ณด๋ฉด ๊ฐ์ฒด์ ๊ฐ์ ๊ทธ๋๋ก ๋ณต์ฌํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๊ทธ๋ด ๋ Setter ๋ฉ์๋๋ก ์ผ์ผ์ด ๋ชจ๋ ์์ฑํ๋ ๊ฒ์ ์ฝ๋์ ๊ธธ์ด์ ์์ฑ ์๊ฐ์ด ๋์ด๋๊ณ , ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๊ฒ ๋ฉ๋๋ค. ์ด๋ BeanUtils.copyProperties๋ฅผ ํตํด ํ ์ค๋ก ํด๊ฒฐํ ์ ์์ต๋๋ค. ๋ํ, ์ํ์ง ์๋ ๊ฐ๋ค์ ์ถ๋ ค๋ด์ด ์ํ๋ ๊ฐ๋ค๋ง ๋ณต์ฌํ ์๋ ์์ต๋๋ค.
BeanUtils.copyProperties
copyProperties์ Spring์์ ์ ๊ณตํ๋ BeanUtils ํด๋์ค์ ๋ฉ์๋์ ๋๋ค.
์ฌ์ฉ๋ฒ์ ์๋์ ๊ฐ์ต๋๋ค.
BeanUtils.copyProperties(Object source, Object target, String... ignoreProperties)
- source: ์๋ณธ ๊ฐ์ฒด
- target: ๋ณต์ฌ ๊ฐ์ฒด
- ignoreProperties: ๋ณต์ฌํ์ง ์์ ํ๋๋ช
ignoreProperties๋ ์๋ต ๊ฐ๋ฅํ๋ฉฐ, ์๋ต ์ ๋ชจ๋ ํ๋๊ฐ ๋ณต์ฌ๋ฉ๋๋ค.
ํ๋ฒ ์์ ๋ฅผ ํตํด ์คํํด๋ณด๊ฒ ์ต๋๋ค.
@SpringBootTest
class Test {
@org.junit.jupiter.api.Test
public void test() {
// given
class User {
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
User user1 = new User();
user1.setName("์์ฃผํ");
user1.setAge(25);
// when
User user2 = new User();
BeanUtils.copyProperties(user1, user2);
//then
assertEquals(user1, user2);
System.out.println("user1: " + user1.getName());
System.out.println("user1: " + user1.getAge());
System.out.println("user2: " + user2.getName());
System.out.println("user2: " + user2.getAge());
}
}
์ ์ฝ๋์ ๋ก์ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- User์ ์ธ์คํด์ค {name: "์์ฃผํ", age:25}์ธ ์ธ์คํด์ค user1 ์์ฑ
- User์ ์ธ์คํด์ค user2๋ฅผ ์์ฑ
- user1์ ํ๋ ๊ฐ์ user2์ ๋ณต์ฌ
- ๊ฐ์ฒด์ ์ฃผ์๊ฐ ์๋ ํ๋ ๊ฐ์ ๋น๊ตํ๊ธฐ ์ํด equals์ hashCode ์ค๋ฒ๋ผ์ด๋ฉ
- assertEquals(user1, user2)๋ฅผ ํตํ ํ ์คํธ
์ฝ๋์ ์ํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
copyProperties์ ์ค์ ๊ตฌํ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
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) {
ResolvableType sourceResolvableType = ResolvableType.forMethodReturnType(readMethod);
ResolvableType targetResolvableType = ResolvableType.forMethodParameter(writeMethod, 0);
// Ignore generic types in assignable check if either ResolvableType has unresolvable generics.
boolean isAssignable =
(sourceResolvableType.hasUnresolvableGenerics() || targetResolvableType.hasUnresolvableGenerics() ?
ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType()) :
targetResolvableType.isAssignableFrom(sourceResolvableType));
if (isAssignable) {
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);
}
}
}
}
}
}
}
์ฃผ์
๋ณต์ฌํ๋ ค๋ ์์ชฝ ๊ฐ์ฒด์ Setter๊ฐ ๊ตฌํ๋์ด ์์ด์ผ๋ง ๋์ํฉ๋๋ค.
๋๊ธ