IoC/DI(제어의 역전/의존성 주입)

hamonjamon·2022년 10월 10일
0

의존성을 간단하게 정의내리면 다음과 같다.


의사 코드

운전자가 자동차를 생산한다.
자동차는 내부적으로 타이어를 생산한다.

자바 코드

new Car();
Car 객체 생성자에서 new Tire();

설명

의존성은 new로, new를 실행하는 Car가 Tire에 의존한다.


1. 스프링없이 의존성 주입하기 1 - 생성자를 통해 의존성을 주입

의사 코드

운전자가 타이어를 생산한다.
운전자가 자동차를 생산하면서 타이어를 장착한다.

자바 코드 - 생성자 인자 이용

Tire tire = new koreaTire();
Car car = new Car(tire);

➜ 전략 패턴 사용 (전략 패턴의 3요소 : 클라이언트, 전략, 컨텍스트)
1. 전략 : Tire를 구현한 koreaTire, americaTire (전략 메서드를 가진 전략 객체)
2. 컨텍스트 : Car의 getTireBrand() 메서드 (전략 객체를 사용하는 컨텍스트)
3. 클라이언트 : Driver의 main() 메서드 (전략 객체를 생성해 컨텍스트에 주입하는 제3자)



2. 스프링없이 의존성 주입하기 2 - 속성을 통해 의존성을 주입

의사 코드

운전자가 타이어를 생산한다.
운전자가 자동차를 생산한다.
운전자가 자동차에 타이어를 장착한다.

자바 코드 - 생성자 인자 이용

Tire tire = new koreaTire();
Car car = new Car();
car.setTire(tire);


3. 스프링을 통한 의존성 주입 - XML 파일 사용

의사 코드

운전자가 종합 쇼핑몰에서 타이어를 구매한다.
운전자가 종합 쇼핑몰에서 자동차를 구매한다.
운전자가 자동차에 타이어를 장착한다.

자바 코드 - 생성자 인자 이용

ApplicationContext context = new ClassPathXmlApplicationContext("main/java/expert002_01/expert002.xml");

// 종합 쇼핑몰에서 상품에 해당하는 Car, Tire 구매하는 코드
Car car = context.getBean("car", Car.class);
Tire tire = context.getBean("tire", Tire.class);
car.setTire(tire);
    <bean id="tire" class="main.java.expert002.koreaTire"/>

    <bean id="americaTire" class="main.java.expert002.AmericaTire"/>

    <bean id="car" class="main.java.expert002.Car"/>


4. 스프링을 통한 의존성 주입 - 스프링 설정 파일(XML)에서 속성 주입

의사 코드

운전자가 종합 쇼핑몰에서 자동차를 구매 요청한다.
종합 쇼핑몰은 자동차를 생산한다.
종합 쇼핑몰은 타이어를 생산한다.
종합 쇼핑몰은 자동차에 타이어를 장착한다.
종합 쇼핑몰은 운전자에게 자동차를 전달한다.

자바 코드 - 생성자 인자 이용

ApplicationContext context = new ClassPathXmlApplicationContext("expert003/expert003.xml");
Car car = context.getBean("car", Car.class);
    <bean id="koreaTire" class="main.java.expert003.koreaTire"/>

    <bean id="americaTire" class="main.java.expert003.AmericaTire"/>

    <bean id="car" class="main.java.expert003.Car">
        <property name="tire" ref="koreaTire"/>
    </bean>


5. 스프링을 통한 의존성 주입 - @Autowired를 통한 속성 주입

의사 코드

운전자가 종합 쇼핑몰에서 자동차를 구매 요청한다.
종합 쇼핑몰은 자동차를 생산한다.
종합 쇼핑몰은 타이어를 생산한다.
종합 쇼핑몰은 자동차에 타이어를 장착한다.
종합 쇼핑몰은 운전자에게 자동차를 전달한다.

자바 코드 - 생성자 인자 이용

ApplicationContext context = new ClassPathXmlApplicationContext("main/java/expert004/expert004.xml");

Car car = context.getBean("car", Car.class);

 	<context:annotation-config />

    <bean id="tire" class="main.java.expert004.koreaTire"/>

    <bean id="americaTire" class="main.java.expert004.AmericaTire"/>

    <bean id="car" class="main.java.expert004.Car" />


public class Car {
    @Autowired
    Tire tire;

    public String getTireBrand() {
        return "장착된 타이어 : " + tire.getBrand();
    }

}


@Autowired를 통한 속성 매칭 규칙(feat.@Resource)

  1. 타입(인터페이스)을 구현한 Bean이 존재하고, 빈이 한 개 인가
    (예 => 유일한 빈 객체 할당, 아니오 => No Matching bean 에러)
  1. 아니오 => id가 일치하는 하나의 빈이 있는가
    (예 => 유일한 빈 객체 할당, 아니오 => No Unique 에러)

스프링의 @Autowired는 id 매칭보다 type 매칭이 우선이기에 스프링 설정 파일 내
id가 존재하지 않더라도 클라이언트 측에서 클래스로 호출하여 의존성 주입 시
정상적으로 구동된다.



@Resource : 자바 표준 어노테이션
-> type과 id 가운데, 매칭 순위는 id가 더 높다. 고로 id로 매칭한 빈을 못찾을 경우 type으로 매칭할 빈을 찾게 된다.

@Autowired : 스프링 어노테이션
-> type과 id 가운데, 매칭 순위는 type이 더 높다.

스프링을 사용하지 않는다면 @Resource만을 사용해야 한다.


0개의 댓글