JAVA/Spring

@RequiredArgsConstructor와 @AllArgsConstructor 비교 [spring 의존성 주입]

min민 2025. 1. 17.

Spring Dependency Injection: @RequiredArgsConstructor와 @AllArgsConstructor 비교

 

스프링 프레임워크에서 의존성 주입(Dependency Injection)은 객체 간 결합을 줄이고 코드의 유연성과 테스트 용이성을 높이는 중요한 패턴이다.

 

스프링에서 의존성 주입 방법은 다양하며, 특히 최근에는 생성자 주입 방식이 트렌드로 자리 잡았다.

 

이 글에서는 @RequiredArgsConstructor, @AllArgsConstructor, 그리고 @Autowired를 사용한 주입 방식을 비교하고, Spring Data JPA와 관련된 주요 내용을 다룬다.

 

 

1. 의존성 주입 방법의 종류

1-1. 필드 주입(Field Injection)

@Autowired
private MemberRepository memberRepository;

 

  • 장점: 코드가 간단하고 바로 사용할 수 있다.
  • 단점: 필드가 private으로 선언되기 때문에 주입된 값을 변경하거나 테스트하기 어렵다. 또한 DI 프레임워크에 강하게 의존적이다.
  • 비추천 이유: 최근 스프링에서는 테스트 용이성과 코드 유연성을 위해 필드 주입 대신 생성자 주입을 권장한다

 

 

 

1-2. 생성자 주입(Constructor Injection)

@Autowired
public MemberService(MemberRepository memberRepository) {
    this.memberRepository = memberRepository;
}

 

  • 장점:
    • 객체 생성 시점에 의존성을 주입받아 객체를 완전히 초기화한다.
    • 불변성을 보장한다(final 필드 사용 가능).
    • 테스트 코드 작성 시 Mock 객체 주입이 용이하다.
  • 최신 스프링 특징: 생성자가 하나만 있으면 @Autowired 생략 가능.

 

1-3. 세터 주입(Setter Injection)

@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
    this.memberRepository = memberRepository;
}

 

  • 장점: 런타임 시점에 의존성을 교체하거나 변경 가능.
  • 단점: 의존성을 선택적으로 주입할 위험이 있다. 의존성이 필수라면 적합하지 않다.

 

 

 

 

 

 

2. Lombok 어노테이션을 활용한 생성자 자동 생성

2-1. @RequiredArgsConstructor

@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository;
}

 

  • 특징:
    • final 키워드가 붙은 필드만 포함하는 생성자를 자동으로 생성.
    • 스프링이 생성자 주입을 지원하므로 @Autowired 없이도 의존성을 자동 주입.
  • 장점:
    • 불변성 보장.
    • 코드가 간결해짐.
  • 적용 사례: 대부분의 서비스 레이어 클래스에서 권장된다.

 

 

2-2. @AllArgsConstructor

@AllArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository;
}

 

  • 특징:
    • 클래스의 모든 필드를 매개변수로 받는 생성자를 생성.
  • 단점:
    • 모든 필드가 필요하지 않을 때도 생성자에 포함될 수 있어 불필요한 의존성이 생길 위험이 있다.
  • 적용 사례: 주로 DTO(Data Transfer Object) 클래스에서 사용.

 

 

 

3. Spring Data JPA와 의존성 주입

JPA의 기본 스펙에 따르면 엔티티 매니저(EntityManager)를 주입받을 때 @PersistenceContext를 사용해야 한다.

 

그러나 Spring Data JPA는 @Autowired로도 EntityManager를 주입받을 수 있도록 지원한다.

@RequiredArgsConstructor
public class MemberRepository {
    private final EntityManager em;
}

 

 

원래 방식:

@PersistenceContext
private EntityManager em;

 

 

Spring Data JPA 지원 방식:

  • @Autowired 또는 @RequiredArgsConstructor로 대체 가능.
  • 스프링 부트와 JPA 통합으로 인해 편리한 의존성 주입 제공.

 

 

4. 결론: 선택 기준

필드 주입 간단한 코드 테스트 어려움, 불변성 미보장 간단한 테스트 또는 예제 코드
생성자 주입 불변성 보장, 테스트 용이성 코드 길어질 수 있음 서비스/컨트롤러 등 주요 클래스
세터 주입 런타임 시점 의존성 변경 가능 의존성 선택적 주입 위험 테스트 시 모킹 교체 용도
@RequiredArgsConstructor 불변성 보장, 코드 간결화 final 필드만 포함 가능 서비스/컨트롤러 레이어
@AllArgsConstructor 모든 필드 포함하는 생성자 생성 불필요한 의존성 포함 위험 DTO/POJO 클래스

 

 

 

5. 참고 코드

@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;
    
    public void saveMember(Member member) {
        memberRepository.save(member);
    }
}

 

위 코드는 최신 스프링 트렌드와 함께 JPA, Spring Data JPA가 제공하는 편리함을 잘 활용한 예시이다.

final 필드를 사용해 불변성을 보장하며, @RequiredArgsConstructor를 통해 생성자 주입 방식을 간결하게 표현했다.

 

 

총 정리

 

  • 의존성 주입은 필드 주입, 생성자 주입, 세터 주입으로 나뉘며, 생성자 주입이 가장 권장된다.
  • @RequiredArgsConstructor는 final 필드만 포함한 생성자를 자동 생성해 코드 간결성과 불변성을 보장한다.
  • @AllArgsConstructor는 모든 필드를 매개변수로 받는 생성자를 생성하지만, 불필요한 의존성 주입 가능성이 있다.
  • Spring Data JPA는 @Autowired를 통해 EntityManager 주입을 지원하여 편의성을 높인다.
  • 최신 스프링에서는 @RequiredArgsConstructor를 활용한 생성자 주입이 가장 트렌디하고 실용적이다.

 

 

댓글