관리 메뉴

피터의 개발이야기

[Spring] @Component에 잘못 알고 있었던 점 본문

Programming/Spring

[Spring] @Component에 잘못 알고 있었던 점

기록하는 백앤드개발자 2021. 1. 13. 08:00
반응형

서론

종종 Util, Interceptor, client를 만들 때에 @Component를 선언하였습니다. 그래저 저는 Component가 사전적 의미인 "구성 요소"처럼 보다 작은 단위 혹은 @Controller와 @Service처럼 특화된 중요 구성요소보단 덜 중요한 객체를 선언하는 용도라고 생각하고 있습니다. 그리고 @Componet와 @Controller, @Service 등등이 별개의 것이라고 생각했었습니다. 하지만 제가 잘못 이해하고 있었고 그 부분에 대해서 공부를 하였습니다.

 

 

실질적으로 @Controller와 @Service, @Repository는 같은 소스이다.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

	/**
	 * 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)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

	/**
	 * 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)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {

	/**
	 * 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)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}

심지어 Controller에 @Service를 선언하여도 작동은 된다.

 

 

소스를 보면 Component.class의 @AliasFor이다. 

Spring document에서 @AliasFor에 대한 설명에 따르면,

@AliasFor(value="value")
public abstract String attribute
The name of the attribute that this attribute is an alias for.
See Also:
value()
Default:
""

해당 클래스의 별칭을 만드는 것이다.

즉 이름만 바뀌었을 뿐 다 Component인 것이다.

 

 

그럼 왜 각각 다른 이름으로 구분해놨을까?

 

Spring Documentation

3.10.1 @Component and further stereotype annotations

In Spring 2.0 and later, the @Repository annotation is a marker for any class that fulfills the role or stereotype (also known as Data Access Object or DAO) of a repository. Among the uses of this marker is the automatic translation of exceptions as described in Section 13.2.2, “Exception translation”.

Spring 2.5 introduces further stereotype annotations: @Component, @Service, and @Controller. @Component is a generic stereotype for any Spring-managed component. @Repository, @Service, and @Controller are specializations of @Component for more specific use cases, for example, in the persistence, service, and presentation layers, respectively. Therefore, you can annotate your component classes with @Component, but by annotating them with @Repository, @Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts. It is also possible that @Repository, @Service, and @Controller may carry additional semantics in future releases of the Spring Framework. Thus, if you are choosing between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated above, @Repository is already supported as a marker for automatic exception translation in your persistence layer.

 

번역을 하자면...

@Repository, @Service 및 @Controller는 구체적인 사용 사례를위한 @Component의 전문화된 형태이다. 따라서 @Component로 구성 요소 클래스에 annotation을 달 수 있지만 대신 @Repository, @Service 또는 @Controller로 주석을 달면 클래스가 도구로 처리하는 측면(aspects)과 연결하는 데 더 적합하다.

 

모두 @Component를 사용해도 되겠지만, 만약 그렇게 하면 가시성이 떨어진다. 그래서 도구로서 논리적인 의미를 명확히 부여하기 위해 서로 다른 어노테이션을 사용하는 것이 더 적합한 것이다. 

 

 

가시적인 의미들

@Component

Spring에서 빈객체를 관리하는 가장 기본적인 annotation이다. 즉, scan-auto-detection과 dependency injection을 위해 사용되는 가장 기본 어노테이션이다.

 

@Controller(컨트롤러)

서블릿 맴핑을 위해 사용되는 어노테이션이다. @RequestMapping 어노테이션을 해당 어노테이션 밑에서만 사용할 수 있다. 프레젠테이션 레이어, 웹 요청과 응답을 처리한다. 

 

@Service(로직 처리)

비즈니스 로직을 처리하는 함수이다. 서비스 레이어, 내부에서 자바 로직을 처리한다.

 

@Repository (외부I/O처리)

data repository를 나타내는 어노테이션이다. DB나 파일같은 외부 I/O 작업을 처리한다.

 

 

결론

@Component는 결고 작은 것이 아니었다. 어찌보면 @Controller, @Repository, @Service은 허상이라고 볼 수 있지만 논리적인 가시성을 위해 적절하게 사용하는 것이 바람직하다. 

반응형
Comments