티스토리 뷰

IoC (Inversion of Control)

IoC는 "제어의 역전"이라는 의미로, 애플리케이션의 흐름 제어를 개발자가 아닌 프레임워크나 컨테이너가 담당하게 되는 디자인 원칙이다.

전통적인 프로그래밍에서는 개발자가 직접 객체를 생성하고, 해당 객체의 생명 주기를 관리했지만,

IoC를 적용하면, 제어와 관리의 책임이 프레임워크나 컨테이너로 이동하게 됩니다.

 

Spring에서는 IoC 컨테이너가 객체의 생명 주기 및 의존성 관리한다.

 

이처럼  IoC 는 클래스 내부가 아니라, 클래스 외부에서 제어권을 갖도록 하는 것을 말한다.

클래스 내부에서 객체를 생성하기 때문에 변경이 자유롭지 못하던 객체가, IoC 를 적용함으로써 외부에서 인자를 받아 변경이 자유로워졌음을 알 수 있다.

객체지향적 관점에서 보자면, IoC 를 통해 역할과 책임을 분리하여 결합도를 낮추고, 변경에 유연한 코드가 될 수 있도록 한 것이다.

 

IoC 와 DIP 의 목적

IoC 와 DIP 모두 객체지향적 관점에서 

한 클래스의 변경이 다른 클래스에 대해 미치는 영향이 최소가 되도록, 변경에 유연한 코드가 되도록 하는 것에 같은 목적을 둔다.

 

IoC 와 DIP 를 적용한 코드와, 그렇지 않은 코드의 차이

IoC, DIP 적용에 따른 차이를 샌드위치 만들기로 예시를 만들어보면

 

IoC 적용 X 샌드위치: 손님이 샌드위치의 재료를 커스텀할 수 없다. (클래스 내에서 객체를 제어하기 때문)

IoC 적용된 샌드위치: 손님이 재료를 요청하여 샌드위치의 재료를 커스텀할 수 있다. (외부에서 인자를 받아 객체를 제어하기 때문)

 

DIP 적용 X 샌드위치: 샌드위치는 '어떤 특정한 빵'을 의존하며, 다른 빵으로 바꾸고 싶다면 샌드위치의 코드도 바꿔야 한다.

DIP 적용된 샌드위치: 샌드위치는 무엇인지 모를 그냥 '빵' 을 의존하며, 어떤 빵이 올지 샌드위치는 관심이 없다. 때문에 다른 빵으로 바꾸고 싶을 때 샌드위치의 코드는 신경쓰지 않아도 된다.

 

 

DI (Dependency Injection)

DI는 IoC의 구체적인 형태 중 하나로, 객체 간의 의존성을 Spring 컨테이너가 관리하도록 한다.

이는 개발자가 객체를 직접 생성하지 않고, 외부(주로 IoC 컨테이너)에서 객체를 생성하고 주입시켜 주는 것이다.

Spring에서는 필드 주입(@Autowired), 생성자 주입, 설정 메서드(setter)를 통해 의존성 주입 받을 수 있다.

 

 

생성자 주입

의존성 주입 방식 중에 생성자 주입을 가장 권장한다.

객체가 생성될 때 의존성이 주어지기 때문에 객체가 항상 올바른 상태로 초기화되기 때문이다.

@RestController
public class MemberController {

    private final MemberService memberService;

    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

1. 생성자의 파라미터에 사용되는 빈이 컨테이너에 존재하는지 찾고 존재하지 않는다면 빈 팩토리에서 만든다.

2. 찾은 파라미터 빈으로 주입하려는 객체의 생성자를 호출한다.

 

생성자 주입을 사용해야 하는 이유

1. 빈이 생성되는 시점에 모든 의존성이 준비되어야 하므로, 빈이 제대로 초기화되지 않는 상황을 방지할 수 있다.

기존의 Setter 생성 메서드 주입 방식의 단점을 보완한다.

2. 또한, 의존성이 한 번 설정되면 변경할 수 없기 때문에 주입받는 객체가 불변성(Immutability)을 가진다.

 

 

필드 주입 Field Injection : @Autowired 사용

필드에 @Autowired 어노테이션을 붙여주면

@Component와 같은 스프링 스테레오타입 어노테이션들은 클래스를 스프링 빈으로 등록하게 해주며,

이렇게 등록된 빈은 @Autowired를 통해 주입받을 수 있다.

 

Spring 컨테이너에게 관리되고 있는 bean이라면 bean 중에서 해당 타입과 일치하는 bean을 자동으로 찾아 주입한다.

 

@Component는 스프링의 기본 스테레오타입 어노테이션이고

@Service, @Controller, @Repository 등은 @Component가 변형된 어노테이션이다.

 

1. @Service 어노테이션을 사용하여 서비스 클래스를 정의한다. (@Component와 기능적으로 동일하며, 의미적 구분을 위해 사용)

@Service
public class MemberService {
    public Member findMember();
}

2. @Autowired로 MemberService를 필드 주입받는다.

@RestController
public class MemberController {
	
    @Autowired
    private MemberService memberService;
	
}

 

 

세터 주입 Setter Injection (Setter)

setter 메서드에 @Autowired 어노테이션을 붙여서 의존성을 주입한다.

필요에 따라 의존성을 변경할 수 있지만, 객체의 상태가 변경될 수 있다.

@RestController
public class MemberController {

    private MemberService memberService;
	
    @Autowired
    public void MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
	
}

 

필드 주입, 설정 메서드 방식은 런타임에서 의존성을 주입하기 때문에 의존성을 주입하지 않아도 객체가 생성될 수 있다.

 

 

 

 

 

참고링크

https://www.youtube.com/watch?v=8lp_nHicYd4

https://my-codinglog.tistory.com/entry/Spring-IoC-DI-%EC%99%80-DIP-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

 

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함