Spring Framework에서 자주 사용되는 두 가지 중요한 애노테이션이 있습니다: @Component와 @Configuration. 이 두 애노테이션은 모두 빈(Bean)을 정의하는 데 사용되지만, 사용하는 목적과 동작 방식에서 큰 차이가 있습니다. 이 글에서는 각각의 애노테이션에 대해 상세히 알아보고, 어떤 상황에서 어떤 애노테이션을 선택해야 하는지 명확히 이해할 수 있도록 설명하겠습니다.
1. @Component란?
@Component는 Spring에서 관리되는 일반적인 빈(Bean)을 정의하기 위해 사용됩니다. Spring 컨테이너는 @Component가 붙은 클래스를 스캔하여 자동으로 빈으로 등록합니다.
주요 특징:
- 자동 감지:
- @Component는 클래스 레벨에서 선언되며, Spring의 컴포넌트 스캔(component scan)에 의해 자동으로 감지됩니다.
- @ComponentScan 또는 @SpringBootApplication이 있는 패키지와 그 하위 패키지에서 스캔됩니다.
- 기본 사용 예:
@Component
public class MyComponent {
public void doSomething() {
System.out.println("Doing something in MyComponent");
}
}
- 주요 애노테이션의 기반:
- @Repository, @Service, @Controller는 모두 @Component의 특화된 형태입니다.
- 각 애노테이션은 역할에 맞는 추가적인 기능을 제공합니다.
- @Repository: 데이터 접근 계층(DAO)에서 사용, 예외 변환 기능 포함.
- @Service: 서비스 계층에서 사용, 특별한 추가 기능은 없음.
- @Controller: Spring MVC의 컨트롤러에서 사용, HTTP 요청 처리에 적합.
- 의존성 주입:
- @Autowired를 사용하여 @Component로 정의된 빈을 주입할 수 있습니다.
@Component
public class MyService {
public String getMessage() {
return "Hello from MyService!";
}
}
@Component
public class MyController {
private final MyService myService;
@Autowired
public MyController(MyService myService) {
this.myService = myService;
}
public void printMessage() {
System.out.println(myService.getMessage());
}
}
2. @Configuration란?
@Configuration은 Java 기반의 설정 클래스에서 사용되며, Spring 컨테이너에서 관리할 빈들을 정의하는 데 사용됩니다. 이 애노테이션은 특히 명시적으로 빈을 정의하고 설정해야 할 때 유용합니다.
주요 특징:
- 설정 클래스:
- @Configuration은 클래스를 설정 파일로 지정합니다. 이 클래스 내부에서 @Bean을 사용해 하나 이상의 빈을 정의합니다.
- @Bean 등록:
- @Configuration 클래스는 메서드에 @Bean 애노테이션을 사용하여 직접 빈을 생성하고 반환할 수 있습니다.
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
@Bean
public MyController myController(MyService myService) {
return new MyController(myService);
}
}
- 싱글톤 보장:
- @Configuration 클래스는 @Bean으로 정의된 빈들이 싱글톤임을 보장합니다.
- 내부적으로 CGLIB 프록시를 사용하여 메서드 호출을 관리합니다.
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
System.out.println("Creating MyService instance");
return new MyService();
}
@Bean
public AnotherService anotherService() {
System.out.println("Using MyService in AnotherService");
return new AnotherService(myService());
}
}
위 코드에서 myService()는 한 번만 호출됩니다.
- 외부 설정 파일 연계:
- @Configuration 클래스는 외부 설정 파일(properties, YAML 등)과 함께 사용되어 동적으로 빈을 구성할 수 있습니다.
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
@Value("${app.name}")
private String appName;
@Bean
public AppInfo appInfo() {
return new AppInfo(appName);
}
}
3. @Component와 @Configuration의 차이점
특징 | @Component | @Configuration |
주요 목적 | 일반적인 빈 정의 | 설정 클래스 및 @Bean 기반 빈 정의 |
빈 등록 방식 | 자동 등록 (컴포넌트 스캔) | 명시적 등록 (@Bean 메서드) |
싱글톤 보장 | 빈 자체에서 보장하지 않음 | CGLIB 프록시를 통해 보장 |
사용 위치 | 일반 클래스 | 설정 클래스 |
주요 사용 사례 | 비즈니스 로직, 서비스 클래스 | 복잡한 빈 설정, 외부 라이브러리 빈 등록 |
4. 언제 사용해야 할까?
@Component를 사용할 때:
- 클래스가 간단한 비즈니스 로직을 수행하거나 특정 역할을 수행하는 서비스 또는 DAO일 때.
- Spring 컨테이너가 자동으로 빈을 스캔하고 등록하도록 하고 싶을 때.
@Configuration을 사용할 때:
- 복잡한 빈 설정이 필요하거나 외부 라이브러리를 Spring 컨텍스트에 통합해야 할 때.
- 명시적인 빈 정의와 세밀한 제어가 필요한 경우.
- @PropertySource, @Value와 함께 외부 설정 파일을 처리해야 할 때.
5. 함께 사용하기
실제 프로젝트에서는 @Component와 @Configuration을 혼합하여 사용하는 경우가 많습니다. 다음은 두 애노테이션을 함께 사용하는 예입니다.
@Component
public class ServiceA {
public String getMessage() {
return "Hello from ServiceA!";
}
}
@Configuration
public class AppConfig {
@Bean
public ServiceB serviceB(ServiceA serviceA) {
return new ServiceB(serviceA);
}
}
public class ServiceB {
private final ServiceA serviceA;
public ServiceB(ServiceA serviceA) {
this.serviceA = serviceA;
}
public void printMessage() {
System.out.println(serviceA.getMessage());
}
}
결론
- @Component는 단순하고 자동화된 빈 정의를 위해, @Configuration은 명시적이고 세밀한 설정이 필요할 때 사용됩니다.
'IT 개발 라이프 > Back_End' 카테고리의 다른 글
자바(JAVA) try-with-resources (0) | 2024.12.31 |
---|---|
자바에서 Generic을 쓰는 이유 (1) | 2024.12.27 |
자바(Java)의 메모리 영역 (1) | 2024.12.19 |
JRE, JDK, JVM: 자바의 핵심 구성 요소 🚀 (1) | 2024.12.18 |
자바의 가비지 컬렉터 (Garbage Collector) 🗑️ (0) | 2024.12.18 |