Spring Framework

자바 Reflection 의 활용, EntityUtil 클래스 만들어 보기

swdream 2021. 9. 30. 20:52
반응형

엔티티 멤버변수에 내가 원하는 멤버변수를 제외하고 나머지를 모두 null 처리 하려면? 

서로 다른 클래스의 오브젝트지만 데이터타입과 변수명이 동일한 멤버변수의 값을 체크해서 복사시키려면?

위와 같은 문제를 실제로 해결하고자 직접 Reflection 과 제너릭을 이용하여 일반화해서 사용할 수 있는 클래스를 직접 만들어봤다. 

Entity Object 에서 필요한 기능들을 Reflection 으로 구현

  • Entity 객체에서 특정 멤버변수만 빼고 모두 null 로 값을 바꾸려면? (가령 user 를 탈퇴시킬 때, user entity의 정보를 날리기 위해 해당 엔티티 오브젝트의 멤버변수를 null 처리, 그리고 특정 필드는 그대로 두도록 하려면?)
    • → setAllNullExceptSpecificFields 메서드
  • 서로 다른 class 로부터 만들어진 Entity 간 서로 겹치는 멤버변수들을 모두 복사하려면? (user → usertemp로 이동할 때)
    • → copyFieldValuesToNewObj 메서드
```java
import com.google.common.base.Defaults;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.springframework.util.ReflectionUtils;

public class EntityUtil {

  private static List<Class<?>> PRIMITIVE_TYPES =
      Arrays.asList(
          boolean.class,
          byte.class,
          short.class,
          int.class,
          long.class,
          float.class,
          double.class,
          char.class);

  public static <T> void setAllNullExceptSpecificFields(T targetObj, String... exceptFields) {

    ReflectionUtils.doWithFields(
        targetObj.getClass(),
        field -> {
          field.setAccessible(true);
          Class<?> type = field.getType();

          if (exceptFields.length > 0
              && stringContainsItemFromList(field.getName(), exceptFields)) {

          } else if (PRIMITIVE_TYPES.contains(type)) {
            field.set(targetObj, Defaults.defaultValue(type));
          } else {
            field.set(targetObj, null);
          }
        });
  }

  public static <T> void copyFieldValuesToNewObj(T inputObj, T targetObj) {

    HashMap<String, Object> typeFieldMap = new HashMap<>();

    ReflectionUtils.doWithFields(
        inputObj.getClass(),
        field -> {
          field.setAccessible(true);
          String fieldNameKey = field.getType().toString().concat(field.getName());
          typeFieldMap.put(fieldNameKey, field.get(inputObj));
        });

    ReflectionUtils.doWithFields(
        targetObj.getClass(),
        field -> {
          field.setAccessible(true);
          String targetFieldName = field.getType().toString().concat(field.getName());
          if (typeFieldMap.containsKey(targetFieldName)) {
            field.set(targetObj, typeFieldMap.get(targetFieldName));
          }
        });
  }

  public static boolean stringContainsItemFromList(String inputStr, String[] items) {
    return Arrays.stream(items).filter(inputStr::contains).findAny().isPresent();
  }
}
```
반응형