이펙티브 자바 책을 읽으면서, 동시에 Spring을 배우면서
새로 접하게 되는 개념 중 하나인
제어의 역전(IoC, Inversion of Control)
용어 자체만 보면 어렵게 느껴질 수 있지만,
코드에서 객체를 누가 생성하고, 누가 관리하는지에 관한 용어이다!
제어의 역전과 더불어서Spring하면 빠질 수 없는 핵심 개념인
Bean
에 관해 이야기해보고자 한다
1. 제어의 역전(IoC)란?
이해하기 쉽게 저녁 식사를 예시로 들어보자!
Pasta 클래스와, Food 인터페이스가 있을 때
// Food interface
public interface Food {
void eat();
}
// Pasta class
public class Pasta implements Food {
public void prepare() {
System.out.println("prepare...");
}
@Override
public void eat() {
System.out.println("pasta");
}
}
기존의 방식으로 저녁 식사를 구현하면
public class Dinner {
private Pasta meal = new Pasta();
public void eatDinner() {
meal.prepare();
meal.eat();
}
}
재료를 준비하고 구매하고 직접 요리하고 먹는 것까지!
저녁 식사의 모든 과정을 우리가 제어하고 책임을 진다
IoC 방식을 사용하면?
public class Dinner {
private Food meal;
public Dinner(Food meal) { // 외부에서 음식 주입(DI)
this.meal = meal;
}
public void eatDinner() {
meal.eat(); // 음식을 먹기만 함
}
}
음식을 먹기만 하면 된다!
객체 생성과 의존성 주입을 프레임워크나 외부 컨테이너가 담당하고
개발자는 사용만 하는 것이 바로 제어의 역전
Spring에서 이 "제어"를 담당하는 것이 바로 IoC Container이다.
Spring IoC Container는 애플리케이션의 객체 생성, 설정, 생명주기 관리를 담당한다
2. 의존성 주입이란?
의존성 주입과 관련해서는 지난 글로 발행했다!
[Spring] 의존성 주입(DI)
🔌 의존성 주입(Dependency Injection) 1. '의존성 주입(DI)'이란? 객체가 사용할 객체를 스스로 만들지 않고,필요한 객체를 외부에서 받아오는 외부에서 주입 받는 디자인 패턴! 우리가 택배 기사라
izzm2.tistory.com
3. Spring Bean이란?
Spring Container가 관리하는 객체를 'Bean'이라고 부른다.
Spring에서는 객체를 자동으로 관리해준다고 했으니까,
스프링 컨테이너에 의해 인스턴스화, 조립, 관리되는 모든 객체는 Bean이다.
Bean을 등록하는 방법엔 크게 3가지가 있다.
1. XML 설정(레거시)
<beans>
<bean id="carService" class="com.example.carService"/>
</beans>
2. Java 설정 클래스 Config 사용
@Configuration
public class AppConfig {
@Bean
public CarService carService() {
return new CarService();
}
}
3. 어노테이션 기반 💥
- 가장 일반적인 방법
@Component
public class CarService {
// 코드
}
4. Spring Bean의 생명주기 💥💥
Bean은 생성되고 소멸될 때까지 여러 과정을 거치며,
이 과정을 이해하면 어플리케이션의 제어력이 향상되기에 중요한 개념이다
객체 생성 > 의존성 주입 > 초기화 콜백 > Bean 사용 > 소멸 콜백 > 종료
1. 객체 생성(Instantiation)
- Spring 이 new, 팩토리 메서드로 Bean 인스턴스를 생성
2. 의존성 주입(프로퍼티 설정)
- 생성된 객체에 필요한 의존성(Bean 등)을 주입
- @Autowired, @Value가 적용되는 시점
3. 초기화 콜백(Initialization)
- Bean이 초기화 작업을 수행할 수 있는 시점
[초기화 로직 정의 방법]
- InitializingBean 인터페이스의 afterPropertiesSet()
- @PostConstruct 어노테이션 메서드 (권장)
- XML에서 init-method 설정
4. Bean 사용
- 의존성이 주입되고, 초기화가 완료된 Bean이 비즈니스 로직 수행에 사용됨
5. 소멸 콜백(Destruction)
- 스프링 컨테이너가 종료될 때 Bean이 정리 작업을 수행할 수 있는 시점
[소 로직 정의 방법]
- DisposableBean의 destroy()
- @PreDestroy 어노테이션 메서드 (권장)
- XML에서 destroy-method 속성 지정
Spring에서는 Bean의 생명주기 중 초기화 직후와 소멸 직전에 직접 개입할 수 있는 매커니즘을 제공한다.
가장 권장하는 방식이자 Java 표준 어노테이션인 @PostConstruct와 @PreDestroy를 사용하면
객체 생성 및 의존성 주입 이후 초기화 시점, 컨테이너 종료 직전 시점에 초기화 및 정리 로직을 실행할 수 있다
[ 초기화 콜백 ]
// 어노테이션을 사용한 개입 (권장)
@PostConstruct
public void init() {
System.out.println("Bean 초기화");
}
[ 소멸 콜백 ]
@PreDestroy
public void cleanup() {
System.out.println("Bean이 소멸됩니다.");
}
5. Bean의 스코프(Scope)
Bean은 다양한 생명주기 스코프를 가질 수 있다.
- Singleton : 기본값. 스프링 컨테이너당 1개의 인스턴스만 생성되어 공유
- Prototype : Bean을 요청할 때마다 항상 새로운 인스턴스가 생성
- request : 웹 환경에서 HTTP 요청마다 새로운 인스턴스가 생성
- session : 웹 환경에서 HTTP 세션마다 하나의 인스턴스가 생성
- application : 웹 환경에서 ServletContext 생명주기와 동일하게 유지
- websocket : 웹 환경에서 WebSocket 세션 생명주기 동안 유지
Spring을 이해하기 위해서는 객체를 누가 만들고, 책임지는지에 대한 개념이 중요하다!
이러한 개념이 Spring에서는 제어의 역전(IoC)!
또, Spring의 Bean과, Bean의 생명주기에 대한 개념을 제대로 이해해두면
향후에 AOP, 트랜잭션 등에 심화 기능에 대해서도 훨씬 수월하게 이해가 가능할 것 같다!
(학습 중 발행한 글로, 오류가 있을 수 있으며 피드백 및 수정은 환영입니다!)
'프로그래밍 > Spring' 카테고리의 다른 글
[Spring] 의존성 주입(DI) (0) | 2025.03.24 |
---|