ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • IoC그리고 DL/DI
    백수의 개발/스프링 2019. 11. 3. 22:02

    IoC(Inversion of Control)

    IoC란 말 그대로 제어의 역전, 즉 제어권이 바뀌었다는 것이다.

    이는 객체의 생성부터 소멸까지 생명 주기의 관리를 개발자가 아닌 컨테이너가 대신 해준다는 것이다.

     

    그 덕분에 개발자가 직접 객체를 주입하며 신경써야했던 코드들을 줄일 수 있다.

     

    IoC에는 아래 그림과 같이 크게 DL(Dependency Lookup)과 DI(Dependency Injection)이 있다.

     

    이에 대해 조금 더 내용을 살펴보자.

     

    DL(Dependency Lookup)

    DL은 의존성 검색이다. 이는 Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 Lookup하는 것이다.

     

    아래와 같이 Bean에 대한 정보가 있는 xml파일이 있다고 생각해보자.

    <beans>
        <bean id="myObject" class="com.example.MyObject"/>
    </beans>

    java에서는 해당 xml의 Bean 정보들을 보고 어떤 클래스를 사용할지 검색하여 주입하게 된다.

     

    아래 자바코드를 살펴보자.

    String myConfigLocation = "classpath:myApplicationCTX.xml";
    AbstractApplicationContext ctx = new GenericXmlApplicationContext(myConfigLocation);
    MyObject myObject = ctx.getBean("myObject", MyObject.class);

    그 결과 위와 같은 코드를 통해 적절한 MyObject클래스를 가져올 수 있는 것이다.

     

    DI(Dependency Injection)

    DI는 의존성 주입이다. 이는 각 클래스간의 의존성을 자신이 아닌 외부(컨테이너)에서 주입하는 개념이다.

     

    일반적으로 Bean 설정 파일을 바탕으로 의존관계를 확인하여 주입하게 된다.

    이는 객체 레퍼런스를 컨테이너로 부터 주입 받아서, 실행 시에 동적으로 의존관계가 생성된다.

    따라서 컨테이너가 흐름의 주체가 되어 어플리케이션 코드에 의존 관계를 주입하게 되는 것이다.

     

    의존관계 주입에는 크게 3가지가 있는데 이에 대해 알아보자.

     

    1. Setter Injection

    이는 Setter 메소드를 통한 의존성 주입이다.

    ex)

    <beans>
        <bean id="myObject" class="com.example.MyObject">
            <property name="myBean">
                <ref bean="ownerBean" />
            </property>
            <property name="yourBean">
                <ref bean="customBean" />
            </property>
        </bean>
        
        <bean id="ownerBean" class="com.example.BeanObject">
            <property name="owner" value="admin"/>
        </bean>
        <bean id="customBean" class="com.example.BeanObject">
            <property name="owner" value="customer"/>
        </bean>
    </beans>
    public class BeanObject{
        String owner;
        
        public void setOwner(String owner){
            this.owner = owner;
        }
    }
    public class MyObject{
        private BeanObject myBean;
        private BeanObject yourBean; 
        
        public void setMyBean(BeanObject myBean){
            this.mybean = mybean;
        }
        
        public void setYourBean(BeanObject yourBean){
            this.yourBean = yourBean;
        }
    }
    String myConfigLocation = "classpath:myApplicationCTX.xml";
    AbstractApplicationContext ctx = new GenericXmlApplicationContext(myConfigLocation);
    MyObject myObject = ctx.getBean("myObject", MyObject.class);
    System.out.println(myObject.myBean.owner); // admin
    System.out.println(myObject.yourBean.owner); // customer

     

    2. Constructor Injection

    이는 Constructor(생성자)를 통한 의존성 주입이다.

    ex)

    <beans>
        <bean id="myObject" class="com.example.MyObject">
            <constructor-arg name="myBean">
                <ref bean="ownerBean" />
            </constructor-arg>
            <constructor-arg name="yourBean">
                <ref bean="customBean" />
            </constructor-arg>
        </bean>
        
        <bean id="ownerBean" class="com.example.BeanObject">
            <property name="owner" value="admin"/>
        </bean>
        <bean id="customBean" class="com.example.BeanObject">
            <property name="owner" value="customer"/>
        </bean>
    </beans>
    public class BeanObject{
        String owner;
        
        public void setOwner(String owner){
            this.owner = owner;
        }
    }
    public class MyObject{
        private BeanObject myBean;
        private BeanObject yourBean; 
        
        public MyObject(BeanObject myBean, BeanObject yourBean){
            this.mybean = mybean;    
            this.yourBean = yourBean;
        }
    }
    String myConfigLocation = "classpath:myApplicationCTX.xml";
    AbstractApplicationContext ctx = new GenericXmlApplicationContext(myConfigLocation);
    MyObject myObject = ctx.getBean("myObject", MyObject.class);
    System.out.println(myObject.myBean.owner); // admin
    System.out.println(myObject.yourBean.owner); // customer

    3. Method Injection

    이는 일반 메서드를 통한 의존성 주입이다.

    <beans>
        <bean id="myObject" class="com.example.MyObject">
            <property name="myBean">
                <ref bean="ownerBean" />
            </property>
            <lookup-method name="getCustomBeanObject" bean="customBean">
        </bean>
        
        <bean id="ownerBean" class="com.example.BeanObject">
            <property name="owner" value="admin"/>
        </bean>
        <bean id="customBean" class="com.example.BeanObject">
            <property name="owner" value="customer"/>
        </bean>
    </beans>
    public class BeanObject{
        String owner;
        
        public void setOwner(String owner){
            this.owner = owner;
        }
    }
    public abstract class MyObject{
        private BeanObject myBean;
        
        public void setCustomBeanObject(BeanObject myBean){
            this.myBean = myBean;
        }
        
        public abstract BeanObject getCustomBeanObject();
    }
    String myConfigLocation = "classpath:myApplicationCTX.xml";
    AbstractApplicationContext ctx = new GenericXmlApplicationContext(myConfigLocation);
    MyObject myObject = ctx.getBean("myObject", MyObject.class);
    System.out.println(myObject.myBean.owner); // admin
    System.out.println(myObject.getCustomBeanObject().owner); // customer

     

    '백수의 개발 > 스프링' 카테고리의 다른 글

    Spring AOP(Aspect Oriented Programming)이란?  (0) 2019.12.31

    댓글

Designed by Tistory.