JUST WRITE

IoC / DI 본문

Programing/Spring

IoC / DI

천재보단범재 2021. 9. 26. 17:09

IoC / DI

IoC

Inversion of Control 제어의 역전

객체, 어떠한 부분의 제어권을 프로그램의 Container나 Framework에게 준다는 컨셉이다.

다르게 이야기하면, 우리가 작성한 코드가 아닌 Framework에서 제어할 수 있다는 말이다.

OOP(Object Oriented Programing)에서 자주 사용되는 원칙이다.

 

IoC를 잘 활용하기 위해서 Framework에서는 추상화(다형성)를 이용한다.

  • Program의 쉬운 Module화
  • 구현한 Component 간의 쉬운 교체

DI

Dependency Injection 의존성 주입

Class에서 필요한 다른 Class의 객체를 직접 생성하는 것이 아닌 외부에서 생성해서 주입받는 방식이다.

아래 코드 중 2번째 코드가 생성자를 통해서 객체를 주입받는 DI 방식 중 하나이다.

// Traditional, DI X
public class Store {
    private Item item;
 
    public Store() {
        item = new ItemImpl1(); // 직접 객체 생성
    }
}
// DI
public class Store {
    private Item item;
    public Store(Item item) {
        this.item = item; // 생성자를 통해 외부 객체 주입
    }
}

Spring IoC / DI

IoC Container

Spring에서는 ApplicationContext Interface가 대표적인 IoC Container이다.

Bean Factory를 확장한 IoC Container이다.(Bean 생성과 제어하는 기능 + Spring 제공 Application 지원 기능)

ApplicationContext의 대표적인 구현체는 아래 3가지이다.

  • ClassPathXmlApplicaionContext (for Standalone Applications)
  • FileSystemXmlApplicationContext (for Standalone Applications)
  • WebApplicationContext (for Web Applications)

이런 IoC Container를 통해서 Bean들을 관리한다.

XML 설정이나 Annotaition으로 작성한 Metadata를 IoC Container가 읽는다.

그럼 IoC Container는 Metadata 기반으로 Runtime에 Bean들을 생성, 관리한다.

DI in Spring

Constructor

Spring에서는 생성자를 이용해서 DI를 구현할 수 있다.

@Configuration
public class AppConfig {

    @Bean // define Bean (기본적으로 Method명이 Bean Name이 됨)
    public Item item1() {
        return new ItemImpl1();
    }

    @Bean
    public Store store() {
        return new Store(item1()); // 생성자를 통해 주입
    }
}
<bean id="item1" class="org.baeldung.store.ItemImpl1" /> 
<bean id="store" class="org.baeldung.store.Store"> 
 	<!-- 생성자를 통해 주입 -->
    <constructor-arg type="ItemImpl1" index="0" name="item" ref="item1" />
</bean>

Setter

Spring에서는 setter-method를 이용해서 DI를 구현할 수 있다.

같은 Bean에 Constructor, Setter 방식 2가지 모두 사용할 수 있다.

Spring에서는 Constructor 방식을 추천한다(필수 Dependency에서  Constructor 방식 사용)

@Bean
public Store store() {
    Store store = new Store();
    store.setItem(item1()); // setter-method 이용
    return store;
}
<bean id="store" class="org.baeldung.store.Store">
    <property name="item" ref="item1" />
</bean>

Autowiring

Field에 @AutoWired라는 Annotation을 사용해서 DI를 구현할 수 있다.

Ioc Container가 자동으로 특정 Rule에 의해 알맞은 Bean을 주입해준다.

  • byName -> 기본적으로 Field명과 Bean Name이 일치하는 Bean 주입
  • byType -> Name보단 Type 일치하는 Bean 주입
  • Constructor -> Constructor Argument Type과 일치하는 Bean 주입
@Bean(autowire = Autowire.BY_TYPE) // Type이 일치하는 Bean 주입
public class Store {
    
    private Item item;

    public setItem(Item item){
        this.item = item;    
    }
}

public class Store {
    @Autowired // default, Name이 일치하는 Bean 주입
    private Item item; 
}

public class Store {
    
    @Autowired
    @Qualifier("item1") // 명시적으로 item1이란 Bean 주입
    private Item item;
}
<bean id="store" class="org.baeldung.store.Store" autowire="byType"> </bean>

<bean id="item" class="org.baeldung.store.ItemImpl1" />

<bean id="store" class="org.baeldung.store.Store" autowire="byName">
</bean>

[주요용어]

Metadata

ApplicationContext가 IoC를 적용하기 위해 사용하는 설정정보
Application 형상정보라고 함

[참고사이트]

728x90
반응형

'Programing > Spring' 카테고리의 다른 글

MappingJackson2JsonView  (0) 2021.10.09
Singleton Registry  (0) 2021.10.02
Bean LifeCycle  (0) 2021.09.29
Spring Bean Scopes  (0) 2021.09.28
Spring Bean  (0) 2021.09.26
Comments