본문 바로가기
Spring

@Controller, @Service, @Repository 차이

코동이 2022. 8. 25.

개요


 스프링을 사용하면서 아마 가장 처음 접했던 것이 @Controller, @Service, @Repository였다. 이 어노테이션들을 무의식적으로 사용했는데, 각 차이점은 있을까? 있다면 어떤 것일까? 알아보도록 해보겠습니다.

 

 

@Component


 @Controller, @Service, @Repository의 공통점, 차이점을 비교하기 이전에 먼저 @Component를 알아야 합니다. 스프링은 과거 XML에만 빈 정의가 가능했지만, 스프링 2.5버전부터는 어노테이션을 이용한 의존성 주입이 가능해졌습니다.

 

 @Component 가 사용된 클래스들은 스프링 빈으로 등록되고 자동으로 빈 탐색의 대상입니다

 

Component의 실체!

 

 

 @Controller, @Service, @Repository


 공통점은 @Controller, @Service, @Repository은 @Component의 구체화된 형태로 해당 어노테이션이 사용된 곳은 @Component와 마찬가지로 자동으로 스프링 빈으로 등록됩니다. 따라서 @Controller 자리에 @Component를, @Service와 @Repository 자리에도 마찬가지로 @Component를 사용할 수 있습니다. 각 클래스의 역할을 명확하게 구분 지을 수 있어서 좋습니다.

 

 

차이점은 다음과 같습니다.

 

  • @Repository

특정 예외를 잡아, 스프링의 unchecked 예외로 다시 던집니다. PersistenceExceptionTranslationPostProcessor를 구현하여야 합니다. 따라서 플랫폼 상세 예외를 잡으면, 스프링의 DataAccessException로 다시 던질 수 있습니다.

 

Indicates that an annotated class is a "Repository", originally defined by Domain-Driven Design (Evans, 2003) as "a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects".

Teams implementing traditional Java EE patterns such as "Data Access Object" may also apply this stereotype to DAO classes, though care should be taken to understand the distinction between Data Access Object and DDD-style repositories before doing so. This annotation is a general-purpose stereotype and individual teams may narrow their semantics and use as appropriate.

A class thus annotated is eligible for Spring DataAccessException translation when used in conjunction with a PersistenceExceptionTranslationPostProcessor. The annotated class is also clarified as to its role in the overall application architecture for the purpose of tooling, aspects, etc.

As of Spring 2.5, this annotation also serves as a specialization of @Component, allowing for implementation classes to be autodetected through classpath scanning.

 

DDD(Evans, 2003)에서 정의된 Repository는 "저장, 검색, 객체 컬렉션을 에뮬레이트하는 검색 행위를 캡슐화하는 메커니즘"이라고 합니다

 

전통적인 Java EE 패턴(DAO)를 구현하는 팀은 @Repository를 DAO 클래스로 활용할 수 있는데, DAO와 DDD 스타일 저장소의 차이를 이해하고 사용하도록 주의해야 합니다. 이 어노테이션은 개인이나 팀이 의미를 좁혀서 적절하게 사용하도록 권장하고 있습니다.

 

PersistenceExceptionTranslationPostProcessor과 함께 사용될 때, 스프링의 DataAccessException으로 변환됩니다.

 

 

 

  • @Service

비지니스 로직이 있으며 저장소 계층을 사용합니다. 이외에 별다른 특징 사항은 없습니다.

 

Indicates that an annotated class is a "Service", originally defined by Domain-Driven Design (Evans, 2003) as "an operation offered as an interface that stands alone in the model, with no encapsulated state."

May also indicate that a class is a "Business Service Facade" (in the Core J2EE patterns sense), or something similar. This annotation is a general-purpose stereotype and individual teams may narrow their semantics and use as appropriate.

This annotation serves as a specialization of @Component, allowing for implementation classes to be autodetected through classpath scanning.

 

DDD(Evans, 2003)에서 정의된 Service는 "캡슐화된 상태 없이 모델에서 단독으로 독립된 인터페이스로 제공되는 작업" 입니다.

 

Business Service Facade에서 정의된 비슷한 내용을 가진다고 하는데 ( 링크 ) , 개인이나 팀이 의미를 좁혀서 적절하게 사용하도록 권장하고 있습니다.

 

 

 

 

  • @Controller

Dispatcher는 @Controller가 있는 클래스들을 확인해서 @RequestMapping이 있는 메서드들을 확인합하여 요청을 처리합니다. 해당 어노테이션은 @Service, @Repository와는 구분되어 사용됩니다.

 

Indicates that an annotated class is a "Controller" (e.g. a web controller).

This annotation serves as a specialization of @Component, allowing for implementation classes to be autodetected through classpath scanning. It is typically used in combination with annotated handler methods based on the org.springframework.web.bind.annotation.RequestMapping annotation.

 

RequestingMapping 어노테이션과 같은 핸들러 메서드에 같이 사용됩니다. 

 

 

 

결론


@Controller, @Service, @Repository의 공통점과 차이점도 알았지만, 이 개념들이 DDD에서 영향을 받았다는 사실을 알았습니다. 추후 DDD를 공부할 때 다시 한번 확인해보면 좋을 것 같습니다

 

  1. @Component 이 있으면 스프링 컨테이너 빈으로 관리된다.
  2. @Repository는 persistence layer이다.
  3. @Service는 service layer이다
  4. @Controller는 presentation layer이다. (spring-MVC).

 

 

 

* 참고

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.html

https://www.javacodegeeks.com/2017/11/difference-component-service-controller-repository-spring.html

https://stackoverflow.com/questions/6827752/whats-the-difference-between-component-repository-service-annotations-in

반응형

'Spring' 카테고리의 다른 글

트랜잭션의 역사  (0) 2022.09.04
@Controller @RestContrller  (0) 2022.08.25
DI(Dependency Injection)  (0) 2022.07.14
Servlet  (0) 2022.07.11
ApplicationContext  (0) 2022.07.08