티스토리 뷰
스프링 컨테이너
스프링 컨테이너는 애플리케이션의 객체(Bean)를 생성하고 관리하는 핵심 역할을 수행합니다.
이를 통해 의존성 주입(Dependency Injection), 빈 생명주기 관리 등을 자동화하여 개발자의 부담을 줄이고 효율적인 애플리케이션 개발을 가능하게 합니다.
1️⃣ 스프링 컨테이너의 역할
1. 빈(Bean) 생성
스프링 컨테이너는 특정 애너테이션이 붙은 클래스를 자동으로 스캔하여 빈으로 등록합니다.
- @Component, @Service, @Repository, @Controller 등의 애너테이션이 붙은 클래스를 스캔하여 자동으로 빈을 생성
- @Bean을 사용하여 명시적으로 빈을 등록할 수도 있음
@Component vs @Bean
스프링은 내부적으로 BeanDefinition이라는 메타데이터를 사용하여 객체를 관리합니다. 이때 빈을 등록하는 두 가지 주요 방식이 있습니다.
@Component | @Bean | |
등록 방식 | 클래스 레벨에서 선언 | 메서드 레벨에서 선언 |
스캔 방식 | @ComponentScan을 통해 자동 감지 | @Configuration 내에서 수동 등록 |
사용 목적 | 일반적인 서비스, 레포지토리, 컨트롤러 등록 | 외부 라이브러리 객체 또는 직접 생성한 객체 등록 |
예제 | @Service, @Repository, @Controller | @Configuration을 활용한 팩토리 메서드 방식 |
@Component와 @Bean 선택 기준
상황 | @Component | @Bean |
일반적인 서비스, DAO, 컨트롤러 클래스 | ✅ | ❌ |
직접 구현한 유틸 클래스 빈 등록 | ✅ | ❌ |
외부 라이브러리 클래스를 빈으로 등록 | ❌ | ✅ |
팩토리 메서드를 통해 객체를 생성해야 하는 경우 | ❌ | ✅ |
커스텀한 객체 설정이 필요한 경우 (ex. JSON ObjectMapper 설정) | ❌ | ✅ |
2. 빈 관리 및 의존성 주입 (DI)
스프링 컨테이너는 @Autowired, @Inject 등의 애너테이션을 활용하여 객체 간의 의존성을 자동으로 주입합니다.
@Service
public class OrderService {
private final MemberRepository memberRepository;
@Autowired // 자동 의존성 주입
public OrderService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
이처럼 new 키워드를 직접 사용하지 않아도 OrderService가 MemberRepository를 사용할 수 있습니다.
3. 빈 생명주기 관리
스프링 컨테이너는 빈을 생성한 후 초기화 및 소멸 단계까지 관리합니다.
- 객체 초기화: @PostConstruct
- 객체 소멸: @PreDestroy
@Component
public class SampleBean {
@PostConstruct
public void init() {
System.out.println("빈 초기화");
}
@PreDestroy
public void destroy() {
System.out.println("빈 소멸");
}
}
2️⃣ 스프링 컨테이너 종류
1. BeanFactory (기본 컨테이너)
- 가장 간단한 컨테이너로, 객체를 필요할 때(lazy loading) 생성
- 스프링 프레임워크 내부적으로 사용됨
BeanFactory factory = new ClassPathXmlApplicationContext("appConfig.xml");
2. ApplicationContext (일반적으로 사용하는 컨테이너)
- BeanFactory를 확장한 컨테이너로, 빈을 미리 생성(eager loading)
- 트랜잭션 관리, 메시지 처리, 이벤트 핸들링 등의 기능을 지원
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = context.getBean(OrderService.class);
✅ 비교
BeanFactory ApplicationContext
빈 생성 시점 | 필요할 때(lazy) | 애플리케이션 실행 시(eager) |
주요 기능 | 단순한 빈 관리 | 트랜잭션, 메시지 처리 등 추가 기능 |
사용 사례 | 성능 최적화가 필요한 경우 | 일반적인 스프링 애플리케이션 |
3️⃣ Spring Boot와 자동 설정(Auto-Configuration)
Spring Boot에서는 ApplicationContext를 명시적으로 생성하지 않아도 자동으로 컨테이너가 실행됩니다.
이는 @SpringBootApplication 애너테이션 덕분이며, 내부적으로 아래 두 가지를 포함합니다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
}
- @SpringBootConfiguration: @Configuration 역할 수행
- @EnableAutoConfiguration: 자동 설정(Auto-Configuration) 활성화
- @ComponentScan: @Component, @Service, @Repository, @Controller 빈 자동 등록
✅ 즉, Spring Boot에서는 개발자가 ApplicationContext를 직접 생성하지 않아도 컨테이너가 자동으로 초기화됩니다.
4️⃣ 스프링 컨테이너의 동작 과정
예제 코드
1. 빈 등록 - @Component 기반 자동 등록
@Component
public class MemberRepository {
public void save(Member member) {
System.out.println("회원 저장: " + member.getName());
}
}
@Service
public class OrderService {
private final MemberRepository memberRepository;
@Autowired // 자동 의존성 주입
public OrderService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
public void order() {
System.out.println("주문 서비스 실행");
memberRepository.save(new Member("홍길동"));
}
}
@Configuration
@ComponentScan(basePackages = "com.example") // 자동으로 빈을 스캔
public class AppConfig {
}
2. 스프링 컨테이너 실행
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = context.getBean(OrderService.class);
orderService.order();
}
}
✅ 실행 결과:
주문 서비스 실행
회원 저장: 홍길동