Spring Context의 핵심: IOC와 DI 패러다임

필수 의존성

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.7.RELEASE</version>
</dependency>

IOC(Inversion of Control)의 본질

객체 생성의 주도권을 개발자에서 프레임워크로 이전하는 설계 원칙이다. Spring 컨테이너가 객체를 생성·관리하며, 필요 시점에 컨테이너에서 주입받아 사용한다.

Bean 생성 전략 3가지

방식설명적용 상황
기본 생성자파라미터 없는 생성자로 인스턴스화일반적인 POJO
정적 팩토리 메서드클래스의 static 메서드로 객체 생성외부 라이브러리 통합
인스턴스 팩토리 메서드별도 팩토리 객체의 메서드로 생성복잡한 초기화 로직

Bean 스코프와 생명주기

scope 속성으로 Bean의 존재 범위를 제어한다.

<bean id="orderRepository" class="com.example.infra.OrderRepositoryImpl" scope="prototype"/>
특성singleton (기본값)prototype
인스턴스 수컨테이너당 1개요청 시마다 새로 생성
생성 시점컨텍스트 로딩 시getBean() 호출 시
소멸 시점컨테이너 종료 시가비지 컬렉션 대상

생명주기 콜백은 init-methoddestroy-method로 지정한다.

<bean id="cacheManager" class="com.example.cache.RedisManager" 
      init-method="warmUp" 
      destroy-method="flushAll"/>

DI(Dependency Injection) 구현 방식

IOC의 구체적 구현체로, 실행 시점에 의존 관계를 외부에서 설정한다.

생성자 주입

public class PaymentService {
    private final TransactionLogger txLogger;
    
    public PaymentService(TransactionLogger txLogger) {
        this.txLogger = txLogger;
    }
}

Setter 주입

public class NotificationService {
    private MessageSender sender;
    
    public void setMessageSender(MessageSender sender) {
        this.sender = sender;
    }
}

다양한 타입 주입

<!-- 기본형 데이터 -->
<property name="maxRetry" value="3"/>

<!-- 컬렉션 -->
<property name="excludedHosts">
    <list>
        <value>localhost</value>
        <value>127.0.0.1</value>
    </list>
</property>

설정 분리와 모듈화

대규모 프로젝트에서는 설정을 기능별로 분리하여 관리한다.

<!-- applicationContext.xml -->
<import resource="classpath:datasource-config.xml"/>
<import resource="classpath:security-context.xml"/>
<import resource="classpath:messaging-beans.xml"/>

컨테이너 API 활용

구현체용도
ClassPathXmlApplicationContext클래스패스 기반 XML 로딩
FileSystemXmlApplicationContext파일 시스템 경로 로딩
AnnotationConfigApplicationContext자바 어노테이션 기반 설정
// 타입 기반 조회 (단일 Bean)
PaymentProcessor processor = context.getBean(PaymentProcessor.class);

// 이름 기반 조회
PaymentProcessor processor = (PaymentProcessor) context.getBean("paypalProcessor");

외부 리소스 연동: DataSource 예시

<!-- 네임스페이스 선언 -->
<beans xmlns:context="http://www.springframework.org/schema/context"
       ...>

<!-- 프로티 파일 외부화 -->
<context:property-placeholder location="classpath:db.properties"/>

<bean id="dataPool" class="com.zaxxer.hikari.HikariDataSource">
    <property name="jdbcUrl" value="${database.url}"/>
    <property name="username" value="${database.user}"/>
    <property name="password" value="${database.password}"/>
</bean>

어노테이션 기반 설정

레거시 어노테이션 (Bean 정의 대체)

@Component
public class InventoryRepository {
    
    @Autowired
    public InventoryRepository(@Qualifier("master") DataSource ds) { }
}

자바 기반 설정 (XML 완전 대체)

@Configuration
public class AppConfig {
    
    @Bean
    @Profile("production")
    public CacheManager redisCacheManager() {
        return new RedisCacheManager();
    }
}

태그: Spring Framework IOC DI Dependency Injection Bean Lifecycle

7월 16일 21:19에 게시됨