Ian's Archive 🏃🏻

Profile

Ian

Ian's Archive

Developer / React, SpringBoot ...

📍 Korea
Github Profile →
Categories
All PostsAlgorithm19Book1C1CI/CD2Cloud3DB1DesignPattern9ELK4Engineering1Front3Gatsby2Git2IDE1JAVA7JPA5Java1Linux8Nginx1PHP2Python1React9Security4SpatialData1Spring26
thumbnail

의존성 주입 4가지 방법 정리

Spring
2024.12.13.

스프링 핵심 원리 - 기본편 보면서 의존성 주입하는 방법에 대해 알게 되었고

생성자 주입이 좋으니까 생성자 주입 사용하고, 깔끔하게 @RequiredArgsConstructor사용하면 된다.

라고만 정리해서 조금 더 상세히 정리한다.


의존성 주입은 크게 4가지 방법이 있다.

  1. 필드 주입
복사
@Component
public class OrderServiceImpl implements OrderService {
    @Autowired
    private MemberRepository memberRepository;
    @Autowired
    private DiscountPolicy discountPolicy;

    ...
}
  • 가장 단순한 방법
  • 외부에서 변경이 불가능해서 테스트하기 힘들다는 치명적인 단점
  • DI프레임 워크가 없으면 아무것도 할 수 없다
  • 스프링 설정을 목적으로 하는 @Configuration같은 곳에서만 특별한 용도로 사용
  1. Setter주입, 일반 메소드 주입
복사
@Component
public class OrderServiceImpl implements OrderService {
    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    @Autowired
    public void setMemberRepository(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
    @Autowired
    public void setDiscountPolicy(DiscountPolicy discountPolicy) {
        this.discountPolicy = discountPolicy;
    }
    // @Autowired
    // public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
    //     this.memberRepository = memberRepository;
    //     this.discountPolicy = discountPolicy;
    // }
}
  • 꼭 setter메서드일 필요가 없다.
  • 네이밍 패턴이(setXXX)가 아니여도 동일한 기능만 하면 된다.
  1. 생성자 주입
복사
@Component
public class OrderServiceImpl implements OrderService {
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
}
  • 스프링을 포함한 DI프레임워크 대부분이 생성자 주입을 권장한다.

  • 불변

    • 대부분의 의존관계 주입은 한번 일어나면 어플리케이션 종료시점까지 의존관계를 변경할 일이 없다. 대부분 의존관계는 어플리케이션 종료 전까지 변하면 안된다.
    • 나머지 주입 방식은 모두 생성자 이후에 호출이 되므로, 필드에 final 키워드를 사용할 수 없다. 오직 생성자 주입 방식만 final 키워드 사용 가능 => 불변하게 설계 가능
  • 누락

    • 순수한 자바 코드를 단위 테스트 하는 경우에 의존관계 주입이 누락
    • final키워드를 사용해 생성자에서 혹시라도 값이 설정되지 않은 오류를 컴파일 시점에서 막아준다.

정리

  • 생성자 주입 방식을 선택하는 이유는 여러가지가 있지만, 프레임 워크에 의존하지 않고, 순수한 자바 언어의 특징을 잘 살리는 방법
  • 기본으로 생성자 주입을 사용하고, 필수 값이 아닌 경우에는 수정자 주입 방식을 옵션으로 부여
    • 생성자 주입과 수정자 주입을 동시에 사용 가능

@RequiredArgsConstructor어노테이션을 사용하면 더 깔끔하게 의존성 주입이 가능하다.

복사
@Component
public class OrderServiceImpl implements OrderService {
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
}

이 형태의 코드를

복사
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
}

이렇게 사용이 가능하다.

Reference

스프링 핵심 원리 - 기본편
생성자 주입을 @Autowired를 사용하는 필드 주입보다 권장하는 하는 이유

Previous Post
PostgreSQL 공간 데이터를 저장해보자
Next Post
파이썬 가상환경 이해
Thank You for Visiting My Blog, I hope you have an amazing day 😆
© 2023 Ian, Powered By Gatsby.