티스토리 뷰

spring

@Component만 사용하면 안되나요?

주다애 2024. 12. 12. 13:48

약간의 사견이 들어있는 글입니다.

💼 @Component

@Component 어노테이션은 Spring Context에 Bean(빈)을 추가하는 방식이다.

 

스프링 컨텍스트에 빈을 추가하는 것은 스프링이 관리해야 하는 객체를 인식하게 하는 것이다.

즉, 스프링 컨텍스트에 빈을 추가해야 스프링이 객체를 볼 수 있게된다.(그 후 객체 간의 의존성 설정이라던지 메소드 호출이라던지 다양한 기능을 수행할 수 있다.)

 

그 방법 중 하나가 @Component 어노테이션을 사용하는 것이다.

 

간단히 과정을 설명하면

@Component
@Getter
@Setter
public class Parrot {
    private String name;
} // Parrot.class
@Configuration
@ComponentScan(basePackages = "com.spring.study.component")
public class ProjectConfig {
} // ProjectConfig.class
public class ComponentMain {
    public static void main(String[] args) {
        var context = new AnnotationConfigApplicationContext(ProjectConfig.class);
        Parrot p = context.getBean(Parrot.class);
        p.setName("앵무새");
        System.out.println(p);
        System.out.println(p.getName());
    }
} // ComponentMain.class
  1. 빈으로 만들 클래스에 @Component 어노테이션을 추가한다.
  2. @ComponentScan 어노테이션으로 스프링이 @Component 어노테이션이 추가된 클래스를 찾을 수 있게 한다. 이 때 basePackages의 속성으로 해당 빈(Parrot)이 위치한 정확한 패키지 명을 작성해주어야 한다.
  3. Main 클래스에서 스프링 컨텍스트가 빈을 생성하고 추가하는 것을 확인한다.

빈이 제대로 등록되었음을 알 수 있다.

 

@Component 어노테이션은 가장 일반적인 형태의 어노테이션으로 특정 역할에 종속되지 않는 일반적인 스프링 빈을 생성할 때 사용한다. 

 

다른 어노테이션은 없나?

@Service, @Repository, @Controller와 같은 어노테이션을 통해 스프링 빈을 등록할 수 있다.

 

@Service

@Serivce 어노테이션은 서비스 레이어에 해당하는 클래스에서 사용한다.

"이 클래스는 비즈니스 로직을 처리하는 서비스이다."라는 의미를 담고 있다.

 

@Repository

@Repository 어노테이션은 데이터 접근 계층 클래스에서 사용된다.

"이 클래스는 데이터베이스와의 상호작용을 담당한다."라는 의미를 담고 있다.

 

@Controller

@Controller 어노테이션은 웹 컨트롤러 클래스에서 사용한다.

"이 클래스는 HTTP 요청과 응답을 처리한다."라는 의미를 담고 있다.

Spring MVC에서 모델 객체를 만들어서 데이터를 담고 뷰를 반환한다.

 

필자도 그렇고 다양한 Spring 프로젝트를 보면 위의 세 개의 어노테이션을 거의 사용하는 것을 볼 수 있다.

 

@Component만 사용하면 안되나요?

다시 질문으로 돌아가서 스프링 빈으로 등록하기 위해 @Component 어노테이션만 사용하면 안되나요?에 대한 대답을 해보자.

그러지 말자..!

1️⃣ 의미의 명확성 부족

모든 빈에 @Component 어노테이션을 붙이면 클래스의 역할을 파악하기 힘들다.

 

각 클래스의 역할을 표현하는 다른 어노테이션(@Service 등등)이 있음에도 사용하지 않는 것은 좋은 선택은 아닌 듯하다.

 

2️⃣ 특화된 기능 부족

@Service, @Repository, @Controller 에는 각각 고유한 기능이 포함되어 있다.

 

  1. @Repository로 예를 들어 보자
    @Repository는 데이터 계층에서 발생하는 예외 처리에 특화되어 있다.
    PersistenceExceptionTranslationPostProcessor는 예외를 DataAccessException으로 변환한다.
    그럼 스프링은 데이터 접근 계층의 예외를 일관된 스프링의 데이터 접근 예외(DataAccessException)으로 처리할 수 있다.
    해당 어노테이션을 사용하면 PersistenceExceptionTranslationPostProcessor가 자동으로적용된다.

    즉, 데이터베이스에 종속적이지 않은 기술 독립적이고 일관된 예외 처리가 가능해지는 것이다.

  2. @Controller로 예를 들어보자
    Spring 5 및 Spring Boot 2.x 이전에는 @Component + @RequestMapping 조합으로 웹 요청 처리 핸들러로 해당 클래스를 등록할 수 있었다.
    즉, @Controller 없이도 HTTP 요청 처리가 가능했다.(기본적으로 @Controller가 @Component를 확장한 구조였기 때문)

    그런데 Spring 6(Spring Boot 3.x) 이후부터는 HTTP 요청 처리를 위한 핸들러로 등록할 때 반드시 @Controller나 @RestController를 사용해야 한다. 그렇지 않으면 HTTP 요청을 제대로 처리할 수 없다.
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
		implements MatchableHandlerMapping, EmbeddedValueResolverAware {
    ...
    @Override
    protected boolean isHandler(Class<?> beanType) {
		// 컨트롤러 애너테이션인지 확인	
        return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class);
    }
    ...
}

 

3️⃣ 유지 보수의 어려움

클래스가 많아질수록 @Component만 사용하면 클래스 역할을 구분하기 어려워 유지 보수의 어려움이 생긴다.

 

의미적 명확성 부족과도 일맥상통하는 부분이다.

프로젝트의 구조가 복잡해질수록 @Component만 사용하면 클래스의 역할을 파악하기 어려워진다.

 

 

유틸리티 클래스나 특정 기능과 관련되지 않은 일반적인 구성 요소를 스프링 빈으로 등록할 때 @Component 어노테이션을 사용하자

'spring' 카테고리의 다른 글

Servlet(서블릿) 이란?  (0) 2024.11.26
@Value 어노테이션 주의점  (0) 2024.11.14
싱글톤 패턴  (0) 2022.11.11
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함