달력

52024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
# 테스트 환경
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 메서드 방식이 가장 빠를 것으로 짐작했으나, 예상과 다른 결과가 나타남. 좀더 테스트가 필요할 것으로 생각됨
Posted by fromm0
|