본문 바로가기
Develop/Spring

[Spring] IoC/Di? 객체 주입 방법

by dev_m.w 2024. 8. 29.

⭐IoC란 (제어의 역전)?

프로그램 제어 흐름이  전통적인 방식과 다른 즉 개발자가 제어 하는것이 아닌, 프레임워크가 프로그램 제어 (객체 생성,호출,소멸) 하는 방식.

 

⭐IoC가 필요한 이유는?

객체를 관리해주는 프레임워크와 내가 구현 하고자 하는 부분으로 역할과 관심을 분리해 응집도를 높이고 결합도를 낮추며, 이에 따라 변경에 유연한 코드를 작성 할 수 있는 구조가 될 수 있기 때문에 제어를 역전한 것이다.

 

⭐DI란(의존성 주입)이란?

스프링 컨테이너에서 객체를 주입해주는 방식이다.

 

의존 관계 주입 방법은 3가지가있다.

1.필드 주입

2.setter 주입

3.생성자 주입 ⭐ (생성자 주입을 선호한다)

 

1. 필드주입

@Component
class Door {}

@Component class Engine {}
 @Component class TurboEngine extends Engine {}
 @Component class SuperEngine extends Engine {}

@Component class Car {
    @Value("red") String color;
    @Value("100") int oil;
    @Autowired Engine engine;
    @Autowired Door[] doors;

 

필드에 @Autowired 라는 어노테이션을 붙이면, 스프링 컨테이너 에서 타입으로 빈을 검색해서 참조 변수에 자동 주입해준다.

검색된 빈이 n 개이면, 그중에 참조 변수와 이름이 일치하는 것을 주입한다.


만약 클래스 Engine을 bean 등록을 주석처리하고,  해당 빈에 engine 타입이 superEngine과 TurboEngine 만 있다면 이런 상황에는 어떤것을 주입해줄까? 

https://devminwoo.tistory.com/32

 

[Spring] @Autowired @Resource @Qualifire 차이

@Autowired 라는 어노테이션을 붙이면, 스프링 컨테이너 에서 타입으로 빈을 검색해서 참조 변수에 자동 주입해준다.검색된 빈이 n 개이면, 그중에 참조 변수와 이름이 일치하는 것을 주입한다.  @

devminwoo.tistory.com

 

 

 

2. setter 주입

 

car.class

 class Car {
   String color;
    int oil;

   Engine engine;
   Door[] doors;

    

     public void setColor(String color) {
         this.color = color;
     }


     public void setOil(int oil) {
         this.oil = oil;
     }

  
     public void setEngine(Engine engine) {
         this.engine = engine;
     }

   

     public void setDoors(Door[] doors) {
         this.doors = doors;
     }

 

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 id="car" class="com.fastcampus.ch3.Car">
                <property name="color" value="red"/>
                <property name="oil" value="100"/>
                <property name="engine" ref="engine"/>
                <property name="doors">
                        <array value-type="com.fastcampus.ch3.Door">
                                <ref bean="door"/>
                                <ref bean="door"/>
                        </array>
                </property>
        </bean>

 

xml 파일에 해당 클래스를 bean 으로 등록해주고 <property> 태그로 주입을 시켜준다, 단 클래스에 반드시 setter 메서드가 있어야한다.

 

3. 생성자 주입

@Component class Car {
   String color;
   int oil;
   Engine engine;
   Door[] doors;



   @Autowired  // @Autowired 생략가능
    public Car(@Value("red") String color, @Value("100") int oil, Engine engine, Door[] doors) {
        this.color = color;
        this.oil = oil;
        this.engine = engine;
        this.doors = doors;
    }

 

@Autowired가 생략가능하다, 단 기본 생성자가 있을경우는 생략이 불가능하다.

 setter 주입이나 필드주입은 @Autowire 주입을 빼먹을수도 있고, 주입받을 빈들에 하나하나 어노테이션을 붙이는 것보단 한번에 생성자로 주입받는게 좋다. 또 필드 주입받을경우  해당 빈이 없으면 null값이 나오지만, 생성자 주입은 컴파일 타입에서 빈이 없다는것을 체크해주기떄문에 생성자 주입으로 초기화 하는것을 추천한다.