Consturctor DI Lombok

반영환·2023년 5월 28일
0

스프링 이모저모

목록 보기
7/12
post-thumbnail

Consturctor DI Lombok

DI 종류

Field Injection

@Component
public class SampleController {
    @Autowired
    private SampleService sampleService;
}

사용하지마!

  • 단일 책임(SRP)의 원칙 위반

  • 의존성이 숨는다.

DI Container를 사용한다는 것은 Class가 자신의 의존성만 책임진다는게 아니라 제공된 의존성 또한 책임진다.

그래서 Class가 어떤 의존성을 책임지지 않을 때, 메서드나 생성자를 통해(Setter나 Constructor) 확실히 커뮤니케이션이 되어야한다.

하지만 Field Injection은 숨은 의존성만 제공해준다.

  • DI Container의 결합성과 테스트 용이성

DI Framework의 핵심 아이디어는 관리되는 Class가 DI Container에 의존성이 없어야 한다.

즉, 필요한 의존성을 전달하면 독립적으로 Instance화 할 수 있는 단순 POJO여야한다.

DI Container 없이도 Unit Test에서 Instance화 시킬 수 있고, 각각 나누어서 테스트도 할 수 있다.

Container의 결합성이 없다면 관리하거나 관리하지 않는 Class를 사용할 수 있고, 심지어 다른 DI Container로 전환할 수 있다.

하지만, Field Injection을 사용하면 필요한 의존성을 가진 Class를 곧바로 Instance화 시킬 수 없다.

  • 불변성(Immutability)

Constructor Injection과 다르게 Field Injection은 final을 선언할 수 없다.
그래서 객체가 변할 수 있다.

  • 순환 의존성

Constructor Injection에서 순환 의존성을 가질 경우 BeanCurrentlyCreationExeption을 발생시킴으로써 순환 의존성을 알 수 있다.

순환 의존성?
A Class가 B Class를 참조하는데 B Class가 다시 A Class를 참조할 경우,
A Class가 B Class를 참조하고, B Class가 C Class를 참조하고 C Class가 A Class를 참조하는 경우 이를 순환 의존성(Circular Dependency)이라고 부른다.

Field Injection은 스프링 컨테이너 말고는 외부에서 주입할 수 있는 방법이 없다.

Field Injection은 읽기 쉽고, 사용하기 편하다는 것 말고는 장점이 없다

Setter Injection

@Component
public class SampleController {
    private SampleService sampleService;
 
    @Autowired
    public void setSampleService(SampleService sampleService) {
        this.sampleService = sampleService;
    }
}

Setter Injection은 선택적인 의존성을 사용할 때 유용하다. 즉, 상황에 따라 의존성 주입이 가능하다.

하지만 Setter Injection을 통해서 Service의 구현체를 주입하지 않아도 Controller 객체의 생성은 가능하다.

즉 set 되지 않은 method들의 호출이 가능해지고 이는 NullPointException이 발생하게 된다.

쓰지마!

Constructor Injection

@Controller
@RequiredArgsConstructor
@RequestMapping(path = "/board")
public class BoardController {
    private final BoardService boardService;
    ...
}

@RequiredArgsConstructor 를 통해 final 필드만 초기화하는 생성자를 만들 수 있기에 필드를 final로 선언만 해주면 자동으로 생성자에서 주입이 된다.

이거 써!

  • 의존성 없이 필수적으로 사용해야 하는 Instance를 만들지 못하도록 강제할 수 있다.

  • 단일 생성자에 한해 @Autowired를 붙이지 않아도 된다.

  • null 주입을 하지 않는 이상 NullPointException을 발생시키지 않는다.

  • final을 사용할 수 있다.

  • 순환 의존성을 알 수 있다.

출처

출처 : [Spring] DI(Dependency Injection) 세 가지 방법

profile
최고의 오늘을 꿈꾸는 개발자

0개의 댓글