Spring의 DI/IoC

newVelog·2024년 4월 20일
0

CS

목록 보기
17/31

이전의 IoC & DI 게시글에 이어서 Spring에서 사용되는 의존성 주입에 대해 이야기 해보려한다.

Spring 이란?

자바의 오픈소스 애플리케이션 프레임워크 중 하나로 스프링의 기본철학은 특정 기술에 종속되지 않고 객체를 관리할 수 있는 프레임워크를 제공하는 것이다.
컨테이너로 자바 객체를 관리하면서 의존성 주입제어의 역전을 통해 결합도를 낮추게 된다.

IoC (Inversion of Control)

제어의 역전
제어권이 사용자에게 있지 않고, 프레임워크에 있음

제어권이 사용자에게 있지 않고, 프레임워크에 있어서 필요에 따라서 사용자의 코드를 호출하게 된다.
스프링에서는 인스턴스의 생성부터 소멸까지 개발자가 아닌 컨테이너에서 대신 관리하게 된다.

DI (Dependency Injection)

의존성 주입
컨테이너가 의존관계를 자동으로 연결

객체간의 의존관계를 미리 설정해두면 스프링 컨테이너가 의존관계를 자동으로 연결해준다.
이렇게 되면 직접 의존하는 객체를 생성하거나 검색해서 가져올 필요가 없어서 결합도가 낮아지는 장점이 있다.

Spring 에서의 DI/IoC

스프링은 스프링 빈으로 등록된 객체에 대해 자동으로 인스턴스를 생성해주고 이 때 필요한 의존성이 있으면 자동으로 주입해준다.

예제

@RestController
@RequestMapping("/members")
public class MemberController {
    private final MemberService memberService;
    
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
    
    ...
}

위 코드에서 생성자를 통해 의존성을 주입받고 있는데 특정한 MemberSercice를 받는 생성자가 어딘가에서 호출이 되어야한다.

@SpringBootApplication
public class DiApplication {

	public static void main(String[] args) {
		SpringApplication.run(DiApplication.class, args);
	}

}

하지만 MemberController보다 더 상위의 어떤 코드를 살펴봐도 MemberController 생성 시 MemberService 인스턴스를 주입하는 코드가 없다. 심지어 MemberController도 생성하고 있지 않다.
이는 MemberController 클래스가 @Component 어노테이션(@RestController 어노테이션이 @Component를 포함)을 포함하고 있어 스프링 빈으로 등록되어 자동으로 의존성을 주입해주기 때문이다.

@Service // @Component 어노테이션을 포함하고 있어 MemberService를 자동으로 빈 등록
public class MemberService {
    ...
}

MemberService 클래스도 빈으로 등록되어 있다면 스프링에 의해 자동으로 생성된다.

@Autowired

스프링에는 여러가지 의존성 주입 방법이 있지만 가장 간편하게 쓰이는 방법으로는 @Autowired 어노테이션을 활용한 방법이 있다.
"여기에 의존성을 주입해줘" 라는 뜻을 가진 @Autowired 를 붙이게 되면 스프링이 자동으로 적절한 의존성을 주입해주게 된다.

@RestController
@RequestMapping("/members")
public class MemberController {
    @Autowired
    private MemberService memberService;
    ...
}

위 코드처럼 의존성을 주입해 줄 수 있으며, 다만 여기서 주입받을 MemberService도 스프링 빈이어야 한다.

생성자 주입

@Autowired 를 통해 의존성을 주입받는 방법에는 필드, setter, 생성자 주입으로 세가지 주요 스타일이 있다.
이 중 스프링에서 공식적으로 권장하는 방법은 생성자 주입이다.

@RestController
@RequestMapping("/members")
public class MemberController {
    private final MemberService memberService;
    
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
    ...
}

생성자 주입을 사용하면 필드를 final로 만들어줄 수 있고 의존성 주입이 생성자 호출 시 최초 1회만 이루어져 의존관계를 불변으로 만들어 줄 수 있다. (애초에 생성자는 1회만 호출되니까)

출처 : https://www.youtube.com/watch?v=VHZ2i4cuwb8&list=PLi-xJrVzQaxU-xK2ao8utngQJqAX4DQty&index=8
https://www.youtube.com/watch?v=8lp_nHicYd4
https://velog.io/@ohzzi/Spring-DIIoC-%EC%8A%A4%ED%94%84%EB%A7%81%EC%9D%98-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85

0개의 댓글