Static convenience methods for JavaBeans:
for instantiating beans, checking bean property types, copying bean properties, etc.
Mainly for use within the framework, but to some degree also useful for application classes
BeanUtils
스프링 프레임워크에서 제공하는 bean들간의 작업을 도와주는 추상 클래스
-> 주로 copying been properties에 사용됨
해당 포스팅에서는 copyProperties method에 대하여 알아보도록 하자
// public abstract class BeanUtils에서 copyProperties 관련 method
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, (Class)null, (String[])null);
}
public static void copyProperties(Object source, Object target, Class<?> editable) throws BeansException {
copyProperties(source, target, editable, (String[])null);
}
public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException {
copyProperties(source, target, (Class)null, ignoreProperties);
}
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;
PropertyDescriptor[] var7 = targetPds;
int var8 = targetPds.length;
for(int var9 = 0; var9 < var8; ++var9) {
PropertyDescriptor targetPd = var7[var9];
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 var15) {
throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", var15);
}
}
}
}
}
}
Spring을 사용하다가 class간 property를 복사해야할 경우에 해당 기능을 사용한다.
원시적인 방법으로는 setter method로 property를 하나 하나 복사하는 방법이 있으나,
이는 매우 비효율적이고 가독성 최악에 아주 아주 쓸데없는 짓이다.
특히나 접근해야 할 property가 수십, 수백개가 되는 상황이라면 이러한 방식은 멍청한 짓이 아닐 수 없다.
그래서 Spring에서 제공하는 BeanUtils를 이용하여 복사하는 방법을 사용한다.
해당 클래스를 그대로 복사해서 쓰는 방법을 사용하면 되지,
왜 굳이 property를 복사하냐는 질문이 있을 수 있다.
여러 클래스들의 값을 가지고 비지니스 로직을 짜다보면 변경되어서는 안될 값들이 생긴다.
(collection에 들어가있는 값을 덮어쓰게 되면 문제가 발생할 수 있다.)
또한 필요한 property만 복사하여 쓰고 싶은 경우에 BeanUtils 메소드를 사용한다.
static 메소드 하나만 호출해도 아래와 같은 기능을 간단하게 사용할 수 있다.
// before
person2.setName(person1.getName());
person2.setAddress(person1.getAddress());
person2.setId(person1.getId());
person2.setPhone(person1.getPhone());
// after
// persion1의 property를 person2에 복사
BeanUtils.copyProperties(person1, person2);
모든 값이 아닌 필요한 property만 복사하고 싶은 경우에는
ignore할 property를 지정해주어 필요한 값만 복사한다.
아래와 같이 ignore 기능을 사용하면 "name"과 "phone"의 property는 복사하지 않는다.
BeanUtils.copyProperties(person1, person2, "name", "phone");
BeanUtils에는 copyProperty 목적 이외에도 여러가지 기능을 더 가지고 있는데, 해당 사이트를 참조하도록 하자
참고 및 참조:https://gompangs.tistory.com/entry/JAVASpring-BeanUtils-%EA%B4%80%EB%A0%A8#footnote_link_119_1
'Programming > SpringFramework' 카테고리의 다른 글
[Spring] 파라미터없이 session값 가져오기(로그인한 Member Id 가져오기) (0) | 2020.12.10 |
---|---|
[Spring] REST API 방식 / RESTful 시스템 (0) | 2020.08.19 |
객체를 리턴타입으로 받아 객체의 정보를 JSON타입으로 리턴시키고 싶을 때? (0) | 2020.08.13 |
[Spring] mybatis-config.xml (mybatis에 필요한 설정 정보) (0) | 2020.08.12 |
[Spring] log4jdbc-log4j2t 설정 (SQL 쿼리 로그) (0) | 2020.08.07 |