스프링 빈(Spring Bean)은 스프링 IoC(Inversion of Control) 컨테이너가 관리하는 자바 객체를 의미합니다. 간단히 말하면, 스프링 애플리케이션 컨텍스트(ApplicationContext) 내에서 생명주기(생성부터 소멸까지)를 관리 받는 객체를 가리킵니다.
스프링 빈을 등록하는 방법은 여러 가지가 있지만, 주로 다음과 같이 크게 세 가지로 분류할 수 있습니다.
아래에서 각 방식을 간단한 예시와 함께 살펴보겠습니다.
<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="exampleBean" class="com.example.ExampleBean">
<!-- 생성자 주입, setter 주입 등 의존관계 설정 -->
</bean>
</beans>
XML@Configuration
public class AppConfig {
@Bean
public ExampleBean exampleBean() {
return new ExampleBean();
}
}
Java@Component
public class ExampleBean {
// ...
}
Java@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
// ...
}
Java스프링 빈은 생성부터 소멸까지의 모든 과정을 스프링 컨테이너가 제어합니다. 이를 빈 생명주기(Bean Lifecycle)라고 하는데, 주된 과정은 아래와 같습니다.
스프링 프레임워크는 위 과정을 자동으로 처리하며, 사용자가 초기화나 소멸 과정을 커스터마이징하고 싶으면 다양한 방법을 제공합니다.
1. @PostConstruct / @PreDestroy
@Component
public class ExampleBean {
@PostConstruct
public void init() {
// 초기화 로직
}
@PreDestroy
public void destroy() {
// 자원 정리 로직
}
}
Java2. InitializingBean / DisposableBean 인터페이스
3. XML / Java Config에서 메서드 직접 지정
스프링은 빈이 어떻게 생성되고 공유될지 결정하는 스코프(scope) 개념을 제공합니다. 대표적인 스코프는 다음과 같습니다.
스코프 설정은 @Scope 어노테이션으로 지정하며, XML 설정에서도 <bean scope=”singleton”>, <bean scope=”prototype”>와 같이 선언할 수 있습니다.
스프링 빈 간의 의존 관계를 설정하는 대표적인 방법은 아래와 같습니다.
@Service
public class OrderService {
private final ProductRepository productRepository;
@Autowired
public OrderService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
Java@Service
public class OrderService {
private ProductRepository productRepository;
@Autowired
public void setProductRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
Java다음 코드는 Java Config와 컴포넌트 스캔 방식을 섞어 사용하는 예시입니다.
package com.example.service;
import org.springframework.stereotype.Service;
@Service
public class PaymentService {
public void pay() {
System.out.println("[PaymentService] 결제가 정상 처리되었습니다.");
}
}
Javapackage com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final PaymentService paymentService;
// 생성자 주입 방식 사용
@Autowired
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void order() {
System.out.println("[OrderService] 주문 요청을 받았습니다.");
paymentService.pay();
System.out.println("[OrderService] 주문 처리가 완료되었습니다.");
}
}
Javapackage com.example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
// 컴포넌트 스캔을 통해 @Service, @Component 등을 자동 등록
}
Javapackage com.example;
import com.example.config.AppConfig;
import com.example.service.OrderService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringBeanExample {
public static void main(String[] args) {
// 스프링 컨테이너 생성
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
// 필요한 빈을 가져와서 메서드 호출
OrderService orderService = context.getBean(OrderService.class);
orderService.order();
// 컨테이너 종료
context.close();
}
}
Java[OrderService] 주문 요청을 받았습니다.
[PaymentService] 결제가 정상 처리되었습니다.
[OrderService] 주문 처리가 완료되었습니다.
Markdown스프링 빈은 스프링 프레임워크의 근간이라 할 수 있는 개념입니다.
스프링 애플리케이션을 개발할 때, 빈을 어떻게 관리하고 의존성을 어떻게 주입할지 설계하는 것은 매우 중요한 일입니다. 설계 단계에서부터 어떤 로직이 Singleton으로 관리될지, Prototype으로 새로 생성돼야 하는지 등을 잘 따져봐야 합니다. 또한, 생성자 주입, 필드 주입, Setter 주입의 특성을 잘 이해하고 상황에 맞게 사용하는 것도 중요합니다.
정리하자면, 올바르게 설계된 스프링 빈 구조는 애플리케이션의 확장성과 유지보수성을 높이고, 단위 테스트나 통합 테스트를 수행할 때 훨씬 편리한 환경을 제공해줍니다.
스프링 빈에 대한 정확하고 확실한 이해가 곧 스프링 프레임워크를 능숙하게 다루는 지름길이며, 더 나아가서는 마이크로서비스 아키텍처(MSA)나 클라우드 환경에서도 안정적으로 확장 가능한 애플리케이션을 만드는 발판이 됩니다.
스프링 컨테이너(Spring Container)란? 스프링 컨테이너는 스프링 프레임워크에서 가장 핵심적인 부분으로, IoC(Inversion of Control) 개념을 기반으로…
Queue란 무엇인가? Java에서 Queue는 데이터 구조의 일종으로, 데이터를 선입선출(FIFO, First-In-First-Out) 방식으로 처리합니다. 이 글에서는 Queue의…
Stack이란 무엇인가? Java에서 Stack은 자료구조의 한 종류로, 데이터를 순서대로 쌓아 올리는 형태로 운영됩니다. 컴퓨터 과학에서…
소개 자바에서 Map 인터페이스는 키(Key)와 값(Value)의 쌍을 저장하는 자료구조입니다. 이는 연관 배열이라고도 불리며, 각 키는…
소개 자바에서 Set은 중복을 허용하지 않는 데이터 집합을 의미합니다. List와 달리 동일한 요소를 여러 번…
해시(Hash)란 무엇인가? 해시(Hash)는 자바 프로그래밍에서 빠르고 효율적인 데이터 저장 및 검색을 위한 핵심적인 개념입니다. 이…