개발 무지렁이

[Spring] Spring Container에 의한 제어의 역행(Inversion Of Control)과 DI 본문

Backend/스프링

[Spring] Spring Container에 의한 제어의 역행(Inversion Of Control)과 DI

Gaejirang-e 2023. 4. 30. 15:47

제어의 역행 (Inversion of Control)


흐름이 뒤바뀌다.
내부에서 객체를 생성(new)하는 것이 아니라,
외부의 Spring Container(IoC 컨테이너)가 객체를 생성해서 안으로 주입해준다. (DI)

DI 유형 (의존성 주입)


📌. 객체의 의존관계를 파악해서 객체의 LifeCycle을 관리
  - Construction Injection ('생성자를 통한 주입')
      <constructor-arg />

  - Setter Injection ('Setter를 통한 주입')
      <property />
          - value 키워드
          - ref 키워드

⚠️ 생성 및 주입Spring Container가 주관.
=> 이를 위해 configuration meta 정보를 입력하자

[beans.xml]

  <?xml version="1.0" encoding="UTF-8"?>
  <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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 객체생성 및 주입 -->
    <bean class="sample01.MessageBeanKoImpl" id="ko" scope="prototype" /> <!-- 인자없는 생성자, 지연초기화 (싱글톤x) -->
    <bean class="sample01.MessageBeanEnImpl" id="en" /> <!-- 인자없는 생성자 -->

    <bean class="sample02.Member" id="member"> <!-- 인수 1개 받는 생성자 -->
      <constructor-arg value="woo" /> <!-- 태그 1, 인수 1 --> <!-- String 한개 받는 생성자 -->
    </bean>  

    <bean class="sample02.Member" id="member2"> <!-- 인수 2개받는 생성자 -->
        <constructor-arg value="woo" /> <!-- 태그 1, 인수 1 -->
        <constructor-arg value="20" type="int" /> <!-- 태그 1, 인수 1 -->
    </bean>  

    <bean class="sample02.Member" id="member3"> <!-- 인수(parameter) 순서를 뒤바꿀 수 있다. -->
      <constructor-arg value="woo" index="0" />
      <constructor-arg value="20" type="int" index="2" />
      <constructor-arg value="서울" index="3" />
      <constructor-arg value="1234" index="1" />
    </bean>

    <bean class="sample02.MemberService" id="service"> <!-- 인수(parameter)가 참조형일 때, ref -->
      <constructor-arg ref="dao" />
      <constructor-arg ref="member3" />
    </bean>  
  </beans>

[MainApp.java]

  public class MainApp {
      public static void main(String[] args) {
          // 기존 방식
          /*
          MesageBean bean = new MessageBeanKoImpl();
          bean.sayHello("Gildong");

          bean = new MessageBeanEnImpl();
          bean.sayHello("Gildong");
          */
          // Spring Container
          ApplicationContext context = new ClassPathXmlApplicationContext("sample01/applicationContext.xml");
          MessageBean bean = context.getBean("en", MessageBean.class);
          bean.sayHello("Gildong");
          bean = context.getBean("ko", MessageBean.class);
          bean.sayHello("Gildong");
          System.out.println("bean: " + bean);

          MessageBean bean2 = context.getBean("ko", MessageBean.class);
          System.out.println("bean2: " + bean2);
           // bean과 bean2의 주소가 다르다, 지연초기화(scope="prototype")
      }
  }

🚀. SpringContainer(ApplicationContext)는 객체를 '싱글톤'으로 생성, 사전초기화한다. (scope='singleton')
  (vs 지연초기화: 필요할 때마다 객체를 새로 만들어준다.)
Comments