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();
}
}
```
반응형