스프링의 Bean은 스프링 프레임워크에서 객체를 관리하는 기본 단위입니다. 스프링 컨테이너가 생성하고 관리하는 객체를 **빈(Bean)**이라고 부르며, 스프링 애플리케이션에서는 이러한 빈들이 서로 의존성을 주입받거나 협력하며 애플리케이션 로직을 처리하게 됩니다.
1. Bean의 정의
• 스프링 빈은 스프링 IoC(제어의 역전) 컨테이너에 의해 생성, 관리되고, 의존성을 주입받아 사용되는 객체입니다.
• 빈은 스프링 애플리케이션의 핵심 구성 요소이며, 각 객체는 컨테이너에 의해 생성 시점, 라이프사이클, 종료 시점까지 관리됩니다.
2. 스프링 Bean의 생성 과정
스프링 애플리케이션이 실행되면 스프링 컨테이너는 설정 파일(예: XML, 자바 설정 파일)이나 애노테이션을 기반으로 빈을 생성하고, 애플리케이션에서 사용될 객체들을 관리하게 됩니다.
빈 등록 방법:
1. 컴포넌트 스캔(Component Scan): 스프링은 클래스에 @Component, @Service, @Repository, @Controller 등의 애노테이션이 붙은 클래스들을 자동으로 스캔하고 빈으로 등록합니다.
@Component // 스프링이 자동으로 빈으로 등록
public class Engine {
public void start() {
System.out.println("Engine started");
}
}
2. 자바 설정 파일에서 빈 등록: @Configuration 클래스 안에서 @Bean 애노테이션을 사용하여 빈을 직접 등록할 수도 있습니다.
@Configuration
public class AppConfig {
@Bean
public Engine engine() {
return new Engine(); // 직접 생성해서 빈으로 등록
}
}
메서드를 @Bean으로 등록하는 것은, 그 메서드가 반환하는 객체를 스프링 컨텍스트에 등록하여 싱글톤으로 관리하고 재사용하겠다는 의미입니다. 즉, 메서드 자체를 재사용하려는 것이 아니라, 메서드가 반환하는 객체를 빈으로 등록하여 재사용하는 것입니다.
3. XML 설정 파일: 전통적인 방식으로 XML 설정 파일에서 <bean> 태그를 사용하여 빈을 정의할 수 있습니다.
<bean id="engine" class="com.example.Engine"/>
3. Bean의 라이프사이클
스프링 빈의 라이프사이클은 빈의 생성부터 소멸까지의 과정을 포함합니다. 스프링 컨테이너는 이 빈의 생성과 초기화, 의존성 주입, 사용, 그리고 소멸까지 모든 과정을 관리합니다.
라이프사이클 주요 단계:
1. 빈 생성: 스프링 컨테이너가 빈을 인스턴스화(객체 생성)합니다.
2. 의존성 주입: 스프링 컨테이너는 빈에 필요한 의존성을 주입합니다.
3. 초기화 콜백: 빈이 모두 초기화된 후, 초기화 작업이 필요한 경우 @PostConstruct와 같은 메서드를 호출하여 초기화합니다.
4. 빈 사용: 빈이 준비되면 애플리케이션에서 빈이 사용됩니다.
5. 소멸 콜백: 빈이 더 이상 사용되지 않을 때 스프링 컨테이너는 소멸 작업을 수행합니다. 이 과정에서 @PreDestroy와 같은 메서드를 호출할 수 있습니다.
초기화 및 소멸 메서드 예시:
@Component
public class Car {
@PostConstruct // 초기화 시점에 호출
public void init() {
System.out.println("Car bean is initialized");
}
@PreDestroy // 소멸 시점에 호출
public void destroy() {
System.out.println("Car bean is destroyed");
}
}
4. Bean의 스코프(Scope)
스프링에서는 빈의 스코프를 설정하여 빈이 어떻게 관리되는지를 결정할 수 있습니다. 기본적으로 빈은 싱글톤(Singleton) 스코프로 생성되지만, 필요에 따라 다른 스코프를 사용할 수 있습니다.
빈 스코프 종류:
1. Singleton (기본값): 애플리케이션이 실행되는 동안 하나의 빈 인스턴스만 생성됩니다. 모든 요청에 대해 동일한 인스턴스를 사용합니다.
@Scope("singleton") // 기본값으로 생략 가능
2. Prototype: 요청마다 새로운 빈 인스턴스가 생성됩니다.
@Scope("prototype")
3. Request: HTTP 요청마다 하나의 빈 인스턴스가 생성되고, 요청이 끝나면 소멸됩니다. 주로 웹 애플리케이션에서 사용됩니다.
@Scope("request")
4. Session: HTTP 세션마다 하나의 빈 인스턴스가 생성됩니다. 세션이 유지되는 동안 동일한 빈 인스턴스가 사용됩니다.
@Scope("session")
5. Application: 하나의 서블릿 컨텍스트 내에서 하나의 빈 인스턴스가 생성됩니다.
5. 의존성 주입(Dependency Injection)과 Bean
스프링 컨테이너는 스프링 빈 간의 의존성을 관리합니다. 빈은 다른 빈을 의존성 주입받아 사용할 수 있으며, 이는 보통 필드 주입, 생성자 주입, 세터 주입으로 이루어집니다.
예시: 생성자 주입:
@Component
public class Car {
private final Engine engine;
@Autowired
public Car(Engine engine) { // 의존성 주입
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is driving");
}
}
위 코드에서 Car 클래스는 Engine 클래스를 의존성 주입받아 사용합니다. @Autowired 애노테이션은 스프링 컨테이너가 Engine 빈을 자동으로 주입해 주도록 합니다.
Engine 클래스도 스프링 빈으로 등록되었기 때문에 싱글톤(Singleton) 스코프로 관리됩니다. 즉, 하나의 Engine 인스턴스만 스프링 컨테이너에 의해 생성되고, 이 인스턴스가 Car 클래스의 생성자에 의존성 주입될 때 사용됩니다.
6. 빈의 등록과 관리 방법
스프링 컨테이너는 스프링 애플리케이션 컨텍스트를 통해 빈을 생성하고 관리합니다. 이 컨텍스트는 애플리케이션의 모든 빈 정보를 저장하고 있으며, 이 빈들을 어떻게 생성하고 관리할지 정의하는 메타데이터를 기반으로 동작합니다.
빈 등록 방법:
1. @Component 애노테이션: 컴포넌트 스캔에 의해 자동으로 빈으로 등록됩니다.
@Component
public class Engine { ... }
2. @Configuration 클래스와 @Bean 애노테이션: 프로그래밍 방식으로 빈을 등록할 수 있습니다.
@Configuration
public class AppConfig {
@Bean
public Engine engine() {
return new Engine(); // 수동으로 빈 등록
}
}
3. XML 설정: XML 설정 파일을 통해 <bean> 태그로 빈을 등록할 수 있습니다.
<bean id="engine" class="com.example.Engine"/>
7. 빈의 의존성 순환 문제 (Circular Dependency)
스프링에서는 두 개 이상의 빈이 서로를 필요로 하는 경우 순환 의존성 문제가 발생할 수 있습니다. 예를 들어, A 클래스가 B 클래스를 의존성 주입받고, B 클래스도 A 클래스를 의존성 주입받으면 순환 의존성이 발생합니다.
해결 방법:
1. 필드 주입 대신 생성자 주입을 피하는 방법: 생성자 주입이 순환 의존성을 만들 수 있으므로, 필드 주입이나 세터 주입을 사용하는 방법도 있습니다.
2. @Lazy 사용: 스프링에서는 @Lazy 애노테이션을 사용하여 순환 의존성을 해결할 수 있습니다. 이 애노테이션은 해당 빈이 실제로 필요할 때까지 생성되지 않도록 합니다.
8. 빈 팩토리와 애플리케이션 컨텍스트
스프링 컨테이너는 BeanFactory와 ApplicationContext를 사용하여 빈을 관리합니다.
• BeanFactory: 가장 기본적인 스프링 컨테이너로, 빈의 생성과 주입만을 담당합니다.
• ApplicationContext: BeanFactory의 확장판으로, 트랜잭션 관리, 메시지 리소스 처리, 이벤트 전달 등의 추가 기능을 제공합니다.
주요 차이점:
• ApplicationContext는 애플리케이션 전반에 걸친 여러 기능을 지원하며, 더 많이 사용됩니다.
• BeanFactory는 더 가벼운 컨테이너이지만, 실제로는 잘 사용되지 않습니다.
결론
스프링의 Bean은 스프링 컨테이너에서 생성하고 관리하는 객체로, 애플리케이션의 모든 동작과 관련된 객체 간의 의존성 주입, 라이프사이클 관리, 스코프 설정 등의 다양한 기능을 제공합니다. Bean은 스프링의 IoC 컨테이너를 통해 관리되며, 스프링 애플리케이션의 모든 핵심 로직을 담당하는 객체입니다.
'spring' 카테고리의 다른 글
[Spring] CustomError 작성법 (0) | 2024.10.20 |
---|---|
[Spring] 주요 Annotation (3) | 2024.10.19 |
[Spring] Spring과 Tomcat (0) | 2024.10.12 |
[Spring] DTO (0) | 2024.10.04 |
[Spring] Lombok (2) | 2024.09.28 |