본문 바로가기

SpringFramework Core - I. IoC 컨테이너/4. 의존성

4.6. 메서드 주입

원문: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-method-injection

 

 

대부분의 애플리케이션에서 대부분의 bean들은 싱글턴이다. 싱글턴 bean이 다른 싱글턴 bean과 협력해야하거나 싱글턴이 아닌 bean이 다른 싱글턴이 아닌 bean과 협력해야할 때, 여러분은 그 중 한 쪽을 다른 쪽의 프로퍼티로 세팅할 것이다. 문제는 bean들의 라이프사이클이 다를 때다. 싱글턴 bean A가 메서드를 호출할 때마다 프로토타입 bean B에 의존한다고 가정해보자. 컨테이너는 싱글턴 bean A를 딱 한번만 만든다. 그리고 프로퍼티를 세팅할 기회를 딱 한번만 준다. 컨테이너는 bean A가 bean B의 새로운 인스턴스를 필요로할 때마다 제공해주지 않는다.

 

해결책은 제어 역전을 선행하는 것이다. ApplicationContextAware 인터페이스를 구현하여 bean A가 컨테이너를 알아볼 수 있게 한 후, bean A가 필요로 할 때마다 getBean("B") 호출을 통해 컨테이너에게 새로운 bean B 인스턴스를 달라고 요청할 수 있다. 다음 예시는 이러한 접근을 보여준다.

// 몇몇 프로세스를 처리하기 위해 Command 스타일의 정적인 클래스를 사용한다.
package fiona.apple;

// 스프링 API imports
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class CommandManager implements ApplicationContextAware {

    private ApplicationContext applicationContext;
    
    public Object process(Map commandState) {
        // 적절한 커맨드의 인스턴스 생성
        Command command = createCommand();
        
        // 커맨드 인스턴스에 상태를 세팅
        command.setState(commandState);
        
        return command.execute();
    }
    
    protected Command createCommand() {
        // 스프링 API에게 의존성 알리기
        return this.applicationContext.getBean("command", Command.class);
    }
    
    public void setApplicationContext(ApplicationContext applicationContext)
    		throws BeansException {
        this.applicationContext = applicationContext;
    }
}

위의 예시는 바람직하지 않다. 비즈니스 코드가 노출되고 스프링 프레임워크와의 결합이 생기기 때문이다. 스프링 IoC 컨테이너의 진화된 기능인 메서드 주입은 이러한 경우를 깔끔하게 해결하게 해준다. 

 

메서드 주입의 동기에 대해서는 이 블로그를 통해 자세히 알 수 있다.