본문으로 바로가기

스프링 기초 이론 1장

category Spring 2020. 8. 22. 00:34

스프링 IoC컨테이너

자바 애플리케이션은 애플리케이션의 행동방식을 제공하기 위해 상호 작용하는 객체로 이뤄진다.

객체가 다른 객체와 상호 작용하는 경우를 객체의 의존관계라고 한다.

DI는 객체 간의 의존 관계를 생상자 인수나 세터 메서드 인수로 명시하고 객체를 생성할 때 생성자나 세터를 통해 의존 관계를 주입하는 방식을 따르는 디자인 패턴이다.

  • IoC 컨테이너는 스프링 애플리케이션에서 애플리케이션에 존재하는 객체를 생성하고 의존 관계를 주입하는 일을 담당한다.

  • 스프링 컨테이너가 생성하고 관리하는 애플리케이션 객체들을 **** 이라고 부른다.

  • DI를 제어의 역전이라고도 부른다.

예를 들어 MyBank 애플리케이션에는 FixedDeposiController 가 FixedDeposiService에 의존하고 있다.

 

public class FixedDepositController{
    private FixedDepositService fixedDepositService;
    
    public FixedDepositController(){
        fixedDepositService = new FixedDepositService();
    }
    
    public boolean submit(){
        //-- 정기 예금의 상세 정보 저장
        fixedDepositService.save(...);
    }
}

이 예제에서 Controller의 생성자는 나중에 자신의 submit 메서드에서 사용할 Service의 인스턴스를 만든다. Controller와 Service가 서로 상호 작용하므로 둘의 의존관계를 나타낸다.

Controller를 스프링 빈으로 설정하려면 FixedDepositController 클래스가 FixedDepositService에 대한 의존관계를 생성자 인수로 받거나 세터 메서드 인수로 받게 수정해야 된다.

 

public class FixedDepositController {
    private FixedDepositService fixedDepositService;
    
    public FixedDepositController(FixedDepositService fixedDepositService){
        this.fixedDepositService = fixedDepositService;
    }
    
    public boolean submit(){
        //-- 정기 예금의 상세 정보 저장
        fixedDepositService.save(.....);
    }
}

이 예제에서 Service 인스턴스는 Controller 인스턴스의 생성자 인수로 전달된다. 이제 Controller 클래스를 스프링 빈으로 설정 할 수 있다. 이때 Controller 가 스프링의 어떤 인터페이스나 클래스를 구현하거나 확장하지 않는다는 점에 유의하자.

스프링 기반 애플리케이션에서 애플리케이션 객체와 그들의 의존 관계의 정보는 설정 메타데이터를 사용해 지정한다. 다음은 XML 형식으로 메타데이터를 작성하였다.

 

<bean ...>
	<bean id ="fdController" class="sample.spring.controller.FixedDepositController">
    	<contructor-arg ref="fdService" />
    </bean>
    
    <bean id = "fdService" class="sample.spring.service.FixedDepositService" />
</bean>

이 예제에서 각 <bean> 엘리먼트는 스프링 컨테이너가 관리하는 애플리케이션 객체를 정의하고, <constructor-arg> 엘리먼트는 Service의 인스턴스를 Controller의 생성자 인수로 전달한다.

스프링 컨테이너는 애플리케이션의 설정 메타데이터를 읽어서 <bean> 엘리먼트로 정의된 애플리케이션 객체를 생성하며 의존 관계를 주입한다.

 

<bean id="controller" class="sample.spring.chapter01.bankapp.FixedDepositController">
	<property name = "fixedDepositService" ref = "service" />
</bean>

다음 코드의 빈 정의는 FixedDepositController 빈이 <property> 엘리먼트를 통해 FixedDepositService 빈에 의존 관계를 정의하는 모습을 보여준다. <property> 엘리먼트의 name 속성의 경우 빈 클래스에는 자바 빈 스타일 세터메서드 이름과 대응하며, 스프링 컨테이너는 빈 생성 시 이 세터 메서드를 호출한다.<property>의 ref 속성은 인스턴스를 생성한 다음 자바빈 스타일 세터 메서드에 전달한 빈을 가리킨다. 이 ref 속상 값은 설정 메타데이터에 있는 <bean> 엘리먼트 중 하나의 id 속성값(또는 name에 지정된 이름 중 하나)과 일치해야 한다.

 

스프링 컨테이너 인스턴스 만들기

 

BankApp 클래스

package sample.spring.chapter01.bankapp;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BankApp{
    ...
    public static void main(String args []){
        ApplicationContext context = new ClassPathXmlApplicationContext(
        "classpath:META-INF/spring/applicationContext.xml");
    ...
    }
}

이 메서드는 스프링 컨테이너를 부트스트랩한다. XML 파일의 클래스 파일 경로가 ClassPathXmlApplicationContext에 전달된다. ClassPathXmlApplicationContext 인스턴스가 생성되는 과정에서 XML 파일에 싱글턴 스코프로 정의된 빈들이 생성되며, 사전- 인스턴스화 상태로 설정된다. 사전 - 인스턴스화라는 건 applicationContext.xml 에 정의 도니 빈이 ClassPathXmlApplicationContext가 인스턴스화 될 때 생성된다는 뜻이다.

 

스프링 컨테이너에 있는 빈에 접근하기

 

BankApp 클래스

 

package sample.spring.chapter01.bankapp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BankApp{
    private static Logger logger = LogManager.getLogger(BankApp.class);
    
    public static void main(String args[]){
        ApplicationContext context = new ClassPathXmlApplicationContext(
        "classpath:META-INF/spring/applicationContext.xml");
        
        FixedDepositController fixedDepositController = 
            (FixedDepositController) context.getBean("controller");
        logger.info("Submission status of fixed deposit : "
                   + fixedDepositController.submit());
        logger.info("Returned fixed deposit info : " + fixedDepositController.get());
    }
}
  1. ApplicationContext의 getBean 메서드를 호출해 스프링 컨테이너에서 FixedDepositController 빈의 인스턴스를 가져온다.

  2. 그 후 FixedDepositController 빈의 submit과 get 메서드를 호출한다. getBean에 넘기는 인수는 스프링 컨테이너에서 가져오려는 빈의 이름이다. getBean 메서드에 전달하는 빈 이름은 반드시 가져오려는 빈의 id나 name속성과 같아야 한다.

  3. 스프링 컨테이너에 등록된 이름과 지정한 이름이 일치하는 빈을 찾을 수 없으면 getBean 메서드가 예외를 발생시킨다.

'Spring' 카테고리의 다른 글

DI란 무엇인가?  (0) 2021.04.01