728x90
▶의존성주입(DI)이란?
사용자가 new키워드를 통해 객체를 생성하고 소멸시키는 과정 필요 없이
의존성주입을 해서 Spring Container가 Bean들의 생명 주기를 관리해주는 기능을 IoC , 제어의 역전이라고 한다.
이 기능을 사용하기 위해서는 우선 객체를 빈으로 등록해야한다.
Bean 등록은 XML 설정 파일을 통해서도 할 수 있고,
Annotation을 이용한 자바 코드를 통해서 등록할 수도 있다.
이전 글 참고하세용~~
이렇게 의존성주입(DI)를 통해
Bean 컨테이너에서 특정 Bean을 필요로 하는 클래스에
Bean과 클래스 간의 의존성주입을 할 수 있다.
의존성 주입의 방법에는 4가지 방법이 존재한다.
▶1. 생성자 주입
- 생성자 주입은 생성자를 통해서 의존관계를 주입받는 방법이다.
- 생성자에 @Autowired를 붙이면 스프링 컨테이너에 @Component로 등록된 빈에서 생성자에 필요한 빈들을 주입한다.
@Component
public class Service {
private final MemberRepository memberRepository;
@Autowired
public Servicelmpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
생성자 주입의 특징
- 생성자 호출 시점에 1번만 호출되는것을 보장한다.
- NPE(NullPointerException)을 방지할 수 있다.
- 주입받을 필드를 final로 선언 가능하다.
▷생성자주입을 사용해야 하는 이유
1. 불변
- 의존관계 주입은 처음 애플리케이션이 실행될 때 대부분 정해지고 종료 전까지 변경되지 않아야한다.
- 만약, 변경가능성이 있다면?
- 실수로 변경할 수 있음
- 애초에, 변경하면 안되는 메소드가 변경될 수 있게 설계하는건 좋지 않다.
- 생성자 주입은 객체를 생성할 때 최초로 한번만 호출되고,
- 그 이후에는 다시 호출되는 일이 없다.
- 따라서 생성자 주입을 사용하면 불변하게 설계할 수 있다.
2. 누락
- 호출했을 때 NPE(NullPointerException)이 발생한다면, 의존관계 주입이 누락되었기 때문이다.
- 생성자 주입을 사용하면 주입 데이터 누락 시 컴파일 오류가 발생
- 따라서, 누락이 발생하더라도 실행되는 일이 없어진다.
3. final키워드 사용 가능
- 생성자 주입을 사용하면 필드에 final키워드를 사용할 수 있다.
- 따라서, 생성자에서 값이 설정되지 않으면 컴파일시점에 오류를 확인 가능하다.
- 생성자 주입을 제외한 나머지 주입 방식은 생성자 이후에 호출되는 형태로 final 키워드를 사용할 수 없다.
4. 순환참조
- 생성자주입은 순환참조를 방지할 수 있다.
- 순환참조란?
- 서로가 서로의 객체를 참조하며 실행되는 메소드가 실행되면 무한루프가 되어 Stack에 메소드를 쌓다가 Stack 메모리가 터져버리고 마는 것..(아주 무서운..)
- 생성자주입을 사용하면 애플리케이션 구동시점(객체의 생성 시점)에 순환 참조 에러를 예방할 수 있다.(애플리케이션 구동 시점에 에러가 발생하기 때문)
- 하지만, 필드 주입이나 수정자 주입에서는 이러한 문제가 런타임시에 발견된다.
▷+Lombok의 @RequiredArgsConstructor
@RequiredArgsConstructor 어노테이션은 class에 선언 된 final 변수, 필드들을
매개변수로 하는 생성자를 자동으로 생성해주는 Lombok 어노테이션이다.
@RestController
@RequiredArgsConstructor
public class Controller{
private final Service service;
}
의존성을 주입받고 싶은 Service 필드를 final로 선언해주고
@RequiredArgsConstructor을 붙여주면,
Lombok에 의해 자동으로 생성자가 생성되어
생성자를 통한 주입방식을 사용할 수 있다.
▶2. 수정자 주입
- 수정자 주입은 필드 값을 변경하는 Setter를 통해서 의존 관계를 주입하는 방법이다.
- 선택과 변경 가능성이 있는 의존관계에 사용한다.
@Component
public class Service {
private final MemberRepository memberRepository;
@Autowired
public void setMemberRepository(MemberRepository memberRepository){
this.memberRepository = memberRepository;
}
}
▶3. 필드 주입
- 필드에 @Autowired를 붙여서 바로 주입하는 방법
- 코드가 간결해진다.
- 외부에서 변경이 불가능하여 테스트하기 어렵다.
- DI프레임워크가 없으면 아무것도 못한다.
@Component
public class Service {
@Autowired
private final MemberRepository memberRepository;
}
▷필드 주입을 사용하지 않는 이유
- 필드주입을 하게되면 DI 컨테이너 안에서만 작동한다.
- final 키워드를 통해 불변속성이라 볼 수도 없고, Setter로 가변 속성이라고 볼 수도 없는 애매한 상황이 발생.
▶4. 일반 메서드 주입
- 일반 메서드를 통해서 의존관계를 주입하는 방법이다.
- 한번에 여러 필드를 주입받을 수 있다.
- 일반적으로 잘 사용 안함.
@Component
public class Service {
private final MemberRepository memberRepository;
@Autowired
public void method(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
▣Reference.
https://mangkyu.tistory.com/125
https://frogand.tistory.com/216
728x90
'BackEnd > Spring Boot🍃' 카테고리의 다른 글
[Spring] Builder 패턴과 Lombok의 @Builder (0) | 2024.04.13 |
---|---|
[Spring] @AllArgsConstructor과 @RequiredArgsConstructor 사용을 "지양"하는 이유, 생성자에관한 어노테이션 알아보기 (0) | 2024.04.13 |
[Spring] ApplicationContext란? ApplicationContext Interface를 구현하고 있는 대표적인 클래스들, Bean 등록 방식 (0) | 2024.04.06 |
[Spring]Spring MVC 요청에서 응답까지의 흐름, @Controller와 @RequestMapping 원리 (0) | 2024.03.24 |
[Spring] Servlet과 Spring Web MVC(2) (0) | 2024.03.23 |