개발 인생/자바

[Spring] IoC/DI 제어의 역전/의존성 주입

견과류아몬드 2022. 3. 12. 17:25

IoC(Inversion Of Control)

스프링에서는 일반적인 Java 객체를 new로 생성하여 관리하는 것이 아닌 Spring Container에 모두 맡긴다.
즉, 개발자 -> 프레임워크로 제어의 객체 관리 권한이 넘어 갔음으로 "제어의 역전"이라고 합니다.
 

DI(Dependency Injection)

DI의 장점
- 의존성으로부터 격리시켜 코드 테스트에 용이하다.
- DI를 통하여, 불가느한 상황을 Mock와 같은 기술을 통하여, 안정적으로 테스트 가능하다.
- 코드를 확장하거나 변경 할 때 영향을 최소화 한다. (추상화)
- 순환 참조를 막을 수 있다.
 

Annotation

@Component

해당 어노테이션을 붙이게 될 경우 ApplicationContext/ApplicationContextAware 구현체에 의한 빈 생성 가능하게 해줌.
-> 이때 빈은 싱글톤으로 관리된다.
 

@Componenet어노테이션을 붙인 후 Constructor 생성 시 주의 사항

@Component
public class Base64Encoder implements IEncoder{

    public String encode(String message){
        return Base64.getEncoder().encodeToString(message.getBytes());
    }
}
@Component      //component는 springbootapplication이 싱글톤으로 관리
public class UrlEncoder implements IEncoder{

    public String encode(String message){
        try {
            return URLEncoder.encode(message, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }

    }
}

위 2개 Class는 IEncoder를 상속 받는다.
 
이 때

@Component
public class Encoder {

    private IEncoder iEncoder;

    //constructor를 만들 때 오류 발생
    public Encoder(IEncoder iEncoder){
        this.iEncoder = iEncoder;
    }

	//set 메소드를 이용하여 의존성 주입
    public void setIEncoder(IEncoder iEncoder){
        this.iEncoder = iEncoder;
    }

    public String encode(String message){
        return iEncoder.encode(message);
    }
}

위는 @Component 어노테이션이 붙은 클래스의 생성자를 갖고 있다.
IEncoder 인스턴스를 매개변수로 받으려고 하는 경우 @Component에 의해 스프링 컨테이너에 의해 관리된다.
스프링 컨테이너에 관리되는 경우 2개 이상의 클래스가  IEncoder를 상속 받는 경우 오류가 난다.

 

그러므로 생성자가 아닌 set메소드를 이용하여 의존성을 주입할 수 있게 하도록 한다.