# 테스트 환경
1. jdk1.6.0_23
2. 프로파일러 : JProfiler v.5.2.4
# 케이스별 테스트 소스와 프로파일링 결과
1. 모델의 setter메서드로 셋팅
public static JaxbMessage validateUrlParam(BindingResult result) {
if (result.hasErrors()) {
JaxbMessage message = getDefaultMessage();
LOGGER.info("바인딩결과 : {} ", result);
JaxbError error = new JaxbError();
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
error.setCode(errorCode);
error.setMsg(ValidationErrorMessageAccessor.getMessages().get(errorCode));
LOGGER.info("{}", error);
message.setError(error);
return message;
}
return null;
}
20번 호출에 15,653us 소요됨
2. Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 사용
public M validateUrlParamOld(M message, E error, String service, String type, String version, BindingResult result) {
if (result.hasErrors()) {
LOGGER.info("바인딩결과 : {} ", result);
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
try {
PropertyDescriptor[] errorPds = BeanUtils.getPropertyDescriptors(error.getClass());
for (PropertyDescriptor desc : errorPds) {
if ("code".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(error, errorCode);
}
if ("msg".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(error, ValidationErrorMessageAccessor.getMessages().get(errorCode));
}
}
PropertyDescriptor[] messagePds = BeanUtils.getPropertyDescriptors(message.getClass());
for (PropertyDescriptor desc : messagePds) {
if ("error".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, error);
}
if ("service".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, service);
}
if ("type".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, type);
}
if ("version".equals(desc.getName())) {
Method setter = desc.getWriteMethod();
setter.invoke(message, version);
}
}
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
return message;
}
return null;
}
20번 호출에 21,372us 소요됨
3. Spring의 ReflectionUtils 사용
public M validateUrlParam(M message, E error, String service, String type, String version, BindingResult result) {
if (result.hasErrors()) {
LOGGER.info("바인딩결과 : {} ", result);
final String errorCode = result.getFieldErrors().get(0).getDefaultMessage();
try {
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setCode", String.class), error, errorCode);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(error.getClass(), "setMsg", String.class), error,
ValidationErrorMessageAccessor.getMessages().get(errorCode));
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setError", error.getClass()), message, error);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setService", String.class), message, service);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setType", String.class), message, type);
ReflectionUtils.invokeMethod(ReflectionUtils.findMethod(message.getClass(), "setVersion", String.class), message, version);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
return message;
}
return null;
}
20번 호출에 13,008us 소요됨
# 정리
1. 순수하게 JDK의 리플렉션을 사용한 테스트 수치는 없음
2. Spring ReflectionUtils < 모델 setter 메서드 < Spring의 BeanUtils.getPropertyDescriptors() 메서드와 Java의 리플렉션 순으로 소요시간이 적음
3. 모델 setter 메서드 방식이 가장 빠를 것으로 짐작했으나, 예상과 다른 결과가 나타남. 좀더 테스트가 필요할 것으로 생각됨