@Component로 @Controller 대체하기

June·2022년 7월 4일
0

우테코

목록 보기
57/84

학습 배경

레벨로그 말하기 때 빈으로 등록하는 방법들에 대해 질문 받은 뒤, @Controller, @Service, @Repository@Component로 대체하면 어떻게 되냐는 질문을 받았다.

레이어드 아키텍처에서 각각의 계층이 하는 역할이 분리되어 있기 때문에 그렇게 하지 않는게 좋겠지만, 어떤식으로 되는지는 몰라서 제대로 대답하지 못했다.

문제

확실히 공식 문서에도 각각의 컴포넌트가 특별한 역할이 있기에 구분하는게 좋다고 되어있다. 예를 들어 @Respository는 영속화 계층에서 예외를 자동으로 바꿔주는 표시가되는 것이다.

@Controller

클래스에 @Controller 대신 @Component 붙이는 경우

이 경우 예외가 발생했다.

메서드를 지정해줘도 마찬가지였다.

클래스에 @Controller 대신 @Component를 붙이고 @RequestMapping도 붙이는 경우

예상외로 잘 동작한다.

심지어 이 경우에도 잘 동작한다.

Controller 어노테이션 코드

Service 어노테이션 코드

Repository 어노테이션 코드

어노테이션만 보면 내부 구성 어노테이션들은 차이가 없다.

공식 문서에서 @Controller를 붙이면서 웹의 요청을 처리한다는 힌트를 사람과 스프링에게 제공한다고 한다. 하지만 결정적으로 그러한 요청들을 라우팅하는 것은 @RequestMapping인 것이다.

HandlerMapping이 url과 빈을 잘 찾기만 하면 문제가 안되는 것이다. 그러기 위해서, Spring Context에서 url로 Controller 클래스를 호출하려면 Controller 클래스가 스프링 빈으로 생성되어야 한다. 그래서 @Component로 빈으로 등록하고, @RequestMapping을 붙여주면 정상적으로 동작하는 것이다.

그렇다면 왜 클래스레벨에 @Controller@RequestMapping없이 붙여도 잘 동작할까 추측해보면 핸들러 매핑을 하는 곳에서 @Controller가 붙어있으면 매핑을 하도록 설정되어 있을 것 같다 (추측)

@Service

@Service의 경우 다른 컴포넌트들로 잘 대체되었다.

밸덩에서도 @Service의 경우 특별한게 없다고 한다.

@Repository

@Repository의 경우 예외를 변환해주는 기능도 있다.

공식문서 - exception translation에 나와있는 것처럼 @Repository가 붙어있으면 예외 변환 해주는 빈들을 찾아서 적용해준다.

1개의 댓글

comment-user-thumbnail
2022년 7월 4일

GetMapping, PostMapping 등의 애너테이션 안에 RequestMapping이 들어있어요~
그래서 Component 선언만 해두면 되는 거일 것 같습니다 😃

답글 달기