@Controller handlerMethod register
스프링 웹 프레임워크를 사용하면서 헨들러 메서드를 사용할 때, 우리는 흔히 @Controller 또는 @RestController를 사용하고 있습니다.
스프링에서 @Controller, @RestController 를 살펴보면 아래와 같이 되어있습니다.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}
결국 @Component 어노테이션이 사용되어있는데 그렇다면 @Controller 대신 @Component를 써도 동작은 할까? (물론 맞진않지만..) 에 대한 궁금증으로 테스트를 해보게 되었습니다.
그 결과 실패..
그렇다면 왜 @Controller 는 등록이 되고 @Component는 등록이 되지않을까를 찾아보게 되었습니다.
해답은 AbstractHandlerMethodMapping 클레스의 initHandlerMethods()라는 부분에 찾을 수 있었는데요 빈을 등록하는과정에서 핸들러를 등록하는 부분이 바로 initHandlerMethods()입니다.
해당 코드 안을 보다보면 다음과 같은 동작을 하게됩니다.
protected void processCandidateBean(String beanName) {
Class<?> beanType = null;
try {
beanType = obtainApplicationContext().getType(beanName);
}
catch (Throwable ex) {
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
if (logger.isTraceEnabled()) {
logger.trace("Could not resolve type for bean '" + beanName + "'", ex);
}
}
if (beanType != null && isHandler(beanType)) {
detectHandlerMethods(beanName);
}
}
@Override
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
해당 부분을 확인 해보면 @Controller, @RequestMapping 어노테이션을 포함하고 있을경우에만, 핸들러로 등록이되고 있었습니다. 그래서 @Component만 등록했을땐 따로 동작하지않았던것...
그렇다면 마지막으로!!
@Component에 @RequestMapping을 추가해본 결과!
이 경우 정상적으로 핸들러로 등록된것을 확인할 수 있었습니다.
Controller니까 당연히 @Controller를 사용하고 있었는데... 간단한 궁금증 덕분에 핸들러 메서드를 등록하는부분을 다시 살펴볼 수 있었네요