새소식

반응형
Spring/etc

[Spring] DI(의존성주입)시 생성자주입과 @Autowired

  • -
반응형

Spring에서 제공하는 의존성 주입 방식은 크게 3가지이다.

  • 필드 주입 ( Field Injection )
  • 수정자 주입 ( Setter or Method Injection )
  • 생성자 주입 ( Constructor Injection )

이러한 종류들 중에서 Spring에서는 생성자 주입 방식을 권장하고 있다.

그러면 이러한 방식을 권장하는 이유를 살펴보자.

 

필드, 수정자 주입

우선 필드, 수정자 주입의 경우에는 @Autowired라는 어노테이션을 사용한다.

public class PostsService {
    @Autowired
    private PostsRepository postsRepository;
    
    // or 
    @Autowired
    public void setPostsRepository(PostsRepository postsRepository) {
        this.postsRepository = postsRepository;
    }
}

 

생성자 주입

생성자 주입의 경우에는 Spring 4.3 버전 이후부터는 단일 생성자인 경우에는 @Autowired 어노테이션조차 붙이지 않고 의존성 주입이 가능하다.

@Service
public class PostsService {
    private final PostsRepository postsRepository;
    
    public PostsService(PostsRepository postsRepository) {
        this.postsRepository = postsRepository;
    }
}

 

생성자 주입의 장점

생성자 주입을 사용시 누릴 수 있는 장점을 알아보자.

 

순환 참조를 통해 발생하는 문제를 미리 방지할 수 있다.

필드, 수정자 주입을 사용하는 경우에는 프로그램을 실행하고, 실제 해당 코드를 수행되는 시점에 순환 참조로 인한 StackOverFlowError가 발생하게 된다.

하지만, 생성자 주입을 사용하는 경우에는 프로그램이 실행조차 되지 않는다. 

생성자 주입의 경우에는 프로그램이 구동 시 빈을 생성하게 되는데 그때 순환 참조를 탐지할 수 있게 된다. 

 

테스트 코드 작성이 수월하다.

DI의 핵심은 관리되는 클래스가 DI 컨테이너에 의존성이 없어야 한다.

즉, 독립적으로 인스턴스화가 가능한 POJO여야 한다.

필드 주입을 하는 경우에는 해당 클래스는 무조건 DI 컨테이너에 의존하게 된다.

( 객체를 생성 시 필드에 해당하는 의존성을 주입해 줄 수 없다)

하지만 생성자 주입을 하는 경우에는 명시적으로 테스트에 사용할 객체를 생성 시 생성자에 넘겨주면 된다.

 

불변성 ( Immutability )을 만족할 수 있다.

필드, 수정자 주입은 해당 필드를 final로 선언할 수 없다.

하지만, 생성자 주입의 경우에는 final로 선언할 수 있다.

 

단일 책임의 원칙을 준수하기 용이하다.

생성자에 인자가 많아지면 해당 클래스는 많은 책임을 가지고 있다고 유추할 수 있다.

이러한 징조를 생성자를 통해서 파악하고 원칙을 준수하기 위해 리팩터링을 도달하기 쉽다.

( 또한 의존성을 파악하기 쉽다)

 

+ Lombok && 생성자 주입

추가적으로 Lombok을 이용하여 간단하게 생성자 주입을 수행할 수 있다.

@RequiredArgsConstructor
@Service
public class PostsService {
    private final PostsRepository postsRepository;
    
}

@RequiredArgsConstructor를 통해서 final인 필드를 포함한 생성자를 코드 Generate 해준다.

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.