ModelAttributeMethodProcessor 클래스에서 resolveArgument 메소드를 통해 객체 바인딩 처리
생성자로 바인딩하는 걸로 처리할지
if (mavContainer.containsAttribute(name)) {
if (bindingResult == null) {
ResolvableType type = ResolvableType.forMethodParameter(parameter);
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name, type);
if (attribute == null) {
this.constructAttribute(binder, webRequest);
attribute = wrapAsOptionalIfNecessary(parameter, binder.getTarget());
}
만약 통과하면 세터로 여기서도 bindingResult 봄
protected AbstractPropertyBindingResult getInternalBindingResult() {
if (this.bindingResult == null) {
this.bindingResult = this.directFieldAccess ? this.createDirectFieldBindingResult() : this.createBeanPropertyBindingResult();
}
return this.bindingResult;
}
바인딩 시도하면 오류난 데이터들이 담긴다
if (!binder.getBindingResult().hasErrors()) {
if (!mavContainer.isBindingDisabled(name)) {
this.bindRequestParameters(binder, webRequest);
}
this.validateIfApplicable(binder, parameter);
}
if (binder.getBindingResult().hasErrors() && this.isBindExceptionRequired(binder, parameter)) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
여기서 중요한 점
if (binder.getBindingResult().hasErrors() && this.isBindExceptionRequired(binder, parameter)) {
bindingResult 선언했는지 본다
protected boolean isBindExceptionRequired(MethodParameter parameter) {
int i = parameter.getParameterIndex();
Class<?>[] paramTypes = parameter.getExecutable().getParameterTypes();
boolean hasBindingResult = paramTypes.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]);
return !hasBindingResult;
}
결국 true 면 예외를 발생시킨다
if (binder.getBindingResult().hasErrors() && this.isBindExceptionRequired(binder, parameter)) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
그래서 컨트롤을 호출하지 않는다