본문 바로가기

Java & Kotlin

[Spring] 스프링 4.3이상에서 @Autowired 애노테이션 생략과 생성자 주입 방식

스프링 프레임워크는 다양한 방식의 의존성 주입(Dependency Injection, DI)을 지원합니다. 그 중 생성자 주입은 가장 권장되는 방식으로, 불변성을 보장하고 객체의 상태를 안전하게 유지할 수 있게 합니다. 스프링 4.3부터는 이러한 생성자 주입을 더욱 간편하게 사용할 수 있는 기능이 추가되었습니다. 이번 글에서는 스프링 4.3에서 @Autowired 애노테이션을 생략하는 방법과 생성자 주입 방식에 대해 알아보겠습니다.

생성자 주입 방식의 DI

생성자 주입은 객체가 생성될 때 필요한 의존성을 주입하는 방식입니다. 이 방식은 의존성이 항상 초기화 단계에서 설정되므로 객체의 불변성을 보장할 수 있으며, 테스트 용이성도 높습니다. 아래는 생성자 주입 방식의 예제입니다.

@Component
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

    // 생성자를 통한 의존성 주입
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Override
    public void registerMember() {
        memberRepository.save();
    }
}

위 코드에서 MemberServiceImpl 클래스는 MemberRepository를 생성자를 통해 주입받습니다. 생성자 주입을 사용하면 memberRepository 필드는 final로 선언될 수 있으며, 이는 해당 필드가 한 번 초기화된 이후 변경되지 않음을 보장합니다.

@Autowired 애노테이션 생략

스프링 4.3부터는 생성자가 하나만 있을 경우, @Autowired 애노테이션을 생략해도 스프링이 자동으로 의존성을 주입해줍니다. 이는 개발자가 불필요한 애노테이션을 작성하지 않아도 되게 하여 코드의 간결성을 높여줍니다.

@Component
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

    // @Autowired 애노테이션 생략 가능
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Override
    public void registerMember() {
        memberRepository.save();
    }
}

위 코드에서는 @Autowired 애노테이션이 없이도 MemberRepository가 자동으로 주입됩니다. 이는 스프링이 클래스에 생성자가 하나만 있을 때 이를 자동으로 주입 대상으로 인식하기 때문입니다.

생성자가 여러 개일 경우

만약 클래스에 생성자가 여러 개 있다면, 스프링은 어떤 생성자를 사용해야 할지 알 수 없으므로 @Autowired 애노테이션을 명시적으로 사용해야 합니다. 예를 들어:

@Component
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

    // 주입할 생성자에 @Autowired 애노테이션 명시
    @Autowired
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    // 다른 생성자
    public MemberServiceImpl(String someOtherDependency) {
        // ...
    }
}

위 코드에서는 어떤 생성자를 주입 대상으로 사용할지 명확히 하기 위해 @Autowired 애노테이션을 사용했습니다.

정리

스프링 4.3부터는 단일 생성자에 대해 자동 주입 기능을 제공하여 @Autowired 애노테이션을 생략할 수 있습니다. 이는 코드의 간결성과 가독성을 높여주며, 개발자가 의존성 주입을 더욱 직관적으로 사용할 수 있게 합니다. 생성자 주입 방식은 객체의 불변성을 보장하고, 테스트 용이성을 높이는 장점이 있으므로, 가능한 한 이 방식을 사용하는 것이 좋습니다.

스프링의 이러한 기능을 통해 우리는 더욱 유연하고 편리한 의존성 주입을 구현할 수 있습니다. 이번 글이 스프링 DI와 @Autowired 애노테이션 생략에 대한 이해를 높이는 데 도움이 되길 바랍니다.