티스토리 뷰
약간의 사견이 들어있는 글입니다.
💼 @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
- 빈으로 만들 클래스에 @Component 어노테이션을 추가한다.
- @ComponentScan 어노테이션으로 스프링이 @Component 어노테이션이 추가된 클래스를 찾을 수 있게 한다. 이 때 basePackages의 속성으로 해당 빈(Parrot)이 위치한 정확한 패키지 명을 작성해주어야 한다.
- Main 클래스에서 스프링 컨텍스트가 빈을 생성하고 추가하는 것을 확인한다.
@Component 어노테이션은 가장 일반적인 형태의 어노테이션으로 특정 역할에 종속되지 않는 일반적인 스프링 빈을 생성할 때 사용한다.
다른 어노테이션은 없나?
@Service, @Repository, @Controller와 같은 어노테이션을 통해 스프링 빈을 등록할 수 있다.
@Service
@Serivce 어노테이션은 서비스 레이어에 해당하는 클래스에서 사용한다.
"이 클래스는 비즈니스 로직을 처리하는 서비스이다."라는 의미를 담고 있다.
@Repository
@Repository 어노테이션은 데이터 접근 계층 클래스에서 사용된다.
"이 클래스는 데이터베이스와의 상호작용을 담당한다."라는 의미를 담고 있다.
@Controller
@Controller 어노테이션은 웹 컨트롤러 클래스에서 사용한다.
"이 클래스는 HTTP 요청과 응답을 처리한다."라는 의미를 담고 있다.
Spring MVC에서 모델 객체를 만들어서 데이터를 담고 뷰를 반환한다.
필자도 그렇고 다양한 Spring 프로젝트를 보면 위의 세 개의 어노테이션을 거의 사용하는 것을 볼 수 있다.
@Component만 사용하면 안되나요?
다시 질문으로 돌아가서 스프링 빈으로 등록하기 위해 @Component 어노테이션만 사용하면 안되나요?에 대한 대답을 해보자.
그러지 말자..!

1️⃣ 의미의 명확성 부족
모든 빈에 @Component 어노테이션을 붙이면 클래스의 역할을 파악하기 힘들다.
각 클래스의 역할을 표현하는 다른 어노테이션(@Service 등등)이 있음에도 사용하지 않는 것은 좋은 선택은 아닌 듯하다.
2️⃣ 특화된 기능 부족
@Service, @Repository, @Controller 에는 각각 고유한 기능이 포함되어 있다.
- @Repository로 예를 들어 보자
@Repository는 데이터 계층에서 발생하는 예외 처리에 특화되어 있다.
PersistenceExceptionTranslationPostProcessor는 예외를 DataAccessException으로 변환한다.
그럼 스프링은 데이터 접근 계층의 예외를 일관된 스프링의 데이터 접근 예외(DataAccessException)으로 처리할 수 있다.
해당 어노테이션을 사용하면 PersistenceExceptionTranslationPostProcessor가 자동으로적용된다.
즉, 데이터베이스에 종속적이지 않은 기술 독립적이고 일관된 예외 처리가 가능해지는 것이다. - @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
- springboot
- null
- 백준
- upperBound
- Optional
- Thymeleaf
- 메인메소드
- N+1문제
- NPE
- uncheckedException
- 일급컬렉션
- @Spring
- 오블완
- lowerBound
- 티스토리챌린지
- Java
- 유효성 검사
- JPA
- ddl-auto
- @NoArgsConstructor
- 생성자
- @Value
- StreamAPI
- id생성전략
- checkedException
- 이진탐색
- 자바
- 동등성
- Spring
- @ConfigurationProperties
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |