레벨로그 말하기 때 빈으로 등록하는 방법들에 대해 질문 받은 뒤, @Controller
, @Service
, @Repository
를 @Component
로 대체하면 어떻게 되냐는 질문을 받았다.
레이어드 아키텍처에서 각각의 계층이 하는 역할이 분리되어 있기 때문에 그렇게 하지 않는게 좋겠지만, 어떤식으로 되는지는 몰라서 제대로 대답하지 못했다.
확실히 공식 문서에도 각각의 컴포넌트가 특별한 역할이 있기에 구분하는게 좋다고 되어있다. 예를 들어 @Respository
는 영속화 계층에서 예외를 자동으로 바꿔주는 표시가되는 것이다.
이 경우 예외가 발생했다.
메서드를 지정해줘도 마찬가지였다.
예상외로 잘 동작한다.
심지어 이 경우에도 잘 동작한다.
Controller 어노테이션 코드
Service 어노테이션 코드
Repository 어노테이션 코드
어노테이션만 보면 내부 구성 어노테이션들은 차이가 없다.
공식 문서에서 @Controller
를 붙이면서 웹의 요청을 처리한다는 힌트를 사람과 스프링에게 제공한다고 한다. 하지만 결정적으로 그러한 요청들을 라우팅하는 것은 @RequestMapping
인 것이다.
HandlerMapping이 url과 빈을 잘 찾기만 하면 문제가 안되는 것이다. 그러기 위해서, Spring Context에서 url로 Controller 클래스를 호출하려면 Controller 클래스가 스프링 빈으로 생성되어야 한다. 그래서 @Component
로 빈으로 등록하고, @RequestMapping
을 붙여주면 정상적으로 동작하는 것이다.
그렇다면 왜 클래스레벨에 @Controller
를 @RequestMapping
없이 붙여도 잘 동작할까 추측해보면 핸들러 매핑을 하는 곳에서 @Controller
가 붙어있으면 매핑을 하도록 설정되어 있을 것 같다 (추측)
@Service
의 경우 다른 컴포넌트들로 잘 대체되었다.
밸덩에서도 @Service
의 경우 특별한게 없다고 한다.
@Repository
의 경우 예외를 변환해주는 기능도 있다.
공식문서 - exception translation에 나와있는 것처럼 @Repository
가 붙어있으면 예외 변환 해주는 빈들을 찾아서 적용해준다.
GetMapping, PostMapping 등의 애너테이션 안에 RequestMapping이 들어있어요~
그래서 Component 선언만 해두면 되는 거일 것 같습니다 😃