728x90

질문 내용)

스프링으로 프로젝트하시는 분들 @RequiredArgsConstructor 사용하시나요?
프로젝트 구조에서 컨트롤러 - 서비스(인터페이스) - 서비스(구현체) 와 같이 구성함
서비스(인터페이스)를 사용하는 이유는 구현체를 변경하는 것이 용이하기 때문(그 외에도 여러 이유들이 있겠지만 제가 생각했을 때 가장 큰 장점은 이 부분입니다)
@RequiredArgsConstructor 어노테이션을 컨트롤러에 사용 시 스프링에서 자동으로 빈으로 등록된 서비스를 호출해서 의존성 주입해줌
이 때 새로운 구현체 생성 시 자동 주입이 불가하므로 어떤 구현체를 사용할 지 지정해줘야됨
구현체가 변경될 일이 없다면 해당 어노테이션을 써도 문제가 될것이 없지만 그럼 서비스 인터페이스를 따로 두는 이유가 없을 것 같음
구현체가 변경될 일이 있다면 자동 DI보다는 직접 주입해주는게 유지보수 및 관리에도 편할 것 같음(@RequiredArgsConstructor 사용 이유가 없을 것 같음)
때문에 @RequiredArgsConstructor 어노테이션을 사용하는지 궁금증이 생겼습니다.


(chat-GPT)

'@RequiredArgsConstructor' 어노테이션은 스프링에서 Lombok 라이브러리가 제공하는 기능으로, 클래스의 final 필드나 '@NonNull'로 선언된 필드에 대해 생성자를 자동으로 생성해주는 기능을 합니다. 이 어노테이션을 사용하면 코드에서 수동으로 생성자를 작성할 필요 없이 의존성 주입을 편리하게 처리할 수 있습니다.

서비스 인터페이스를 사용하는 이유와 '@RequiredArgsConstructor'의 사용 여부에 대한 질문에 대한 답변을 아래와 같이 정리해볼 수 있습니다.

서비스 인터페이스의 장점

  1. 유연성: 서비스 인터페이스를 사용하면 구현체를 변경하거나 교체하는 것이 용이합니다. 예를 들어, 특정 비즈니스 로직의 구현을 변경하거나, 테스트 목적으로 대체 구현체를 사용하는 경우 유용합니다.

  2. 테스트 용이성: 인터페이스를 사용하면, Mock 객체나 Stub 객체를 생성하여 테스트할 때 의존성을 쉽게 주입할 수 있습니다. 이는 유닛 테스트와 통합 테스트에서 유용합니다.

  3. 모듈화: 서비스 인터페이스를 통해 시스템의 모듈화가 잘 이루어질 수 있습니다. 인터페이스를 통해 의존성을 주입받기 때문에 구현체가 변경되더라도 인터페이스를 사용하는 클라이언트 코드는 영향을 받지 않습니다.

'@RequiredArgsConstructor'와 의존성 주입

'@RequiredArgsConstructor'를 사용하는 이유는 다음과 같습니다:

  1. 간결한 코드: Lombok의 '@RequiredArgsConstructor'를 사용하면 생성자를 자동으로 생성해주므로, 코드가 간결해지고 가독성이 좋아집니다. 직접 생성자를 작성할 필요가 없으므로, 코드 작성과 유지보수의 부담이 줄어듭니다.

  2. Immutable 객체: 생성자를 통한 의존성 주입은 객체를 불변(Immutable)으로 만들 수 있으며, 이는 객체의 상태가 변경되지 않음을 보장할 수 있어 안전합니다.

구현체 변경 시

'@RequiredArgsConstructor'를 사용하더라도, 스프링의 의존성 주입 메커니즘은 여전히 동작합니다. 구현체가 변경될 때는 다음과 같은 점을 고려할 수 있습니다:

  1. 구현체 명시: 스프링에서는 '@Primary' 어노테이션을 사용하여 기본 구현체를 지정하거나, '@Qualifier'를 사용하여 특정 구현체를 명시적으로 주입할 수 있습니다. 이렇게 하면 원하는 구현체를 정확히 주입할 수 있습니다.

  2. 환경 설정: 'application.properties'나 'application.yml' 파일에서 구현체의 설정을 다르게 할 수도 있습니다. 이를 통해 환경별로 구현체를 쉽게 변경할 수 있습니다.

  3. 조건부 빈 등록: 조건부 빈 등록을 통해, 특정 조건에 맞는 구현체를 선택적으로 빈으로 등록할 수 있습니다. 예를 들어, '@Profile'을 사용하여 프로파일에 따라 다른 빈을 등록할 수 있습니다.

결론

  • '@RequiredArgsConstructor'는 코드의 간결함과 유지보수의 용이성을 제공하며, 생성자를 통해 의존성 주입을 편리하게 처리할 수 있습니다.
  • 서비스 인터페이스는 유연성, 테스트 용이성, 모듈화 등의 장점을 제공하며, '@RequiredArgsConstructor'와 함께 사용하더라도 이러한 장점이 사라지지 않습니다.
  • 구현체 변경 시에도 스프링의 다양한 기능을 활용하여 구현체를 지정하거나 환경에 맞게 조정할 수 있습니다.

결론적으로, '@RequiredArgsConstructor'는 의존성 주입을 편리하게 하고, 코드의 가독성과 유지보수를 향상시키기 위해 널리 사용됩니다. 서비스 인터페이스와 함께 사용하더라도, 유연한 구현체 변경과 유지보수는 여전히 가능하며, 적절한 스프링 기능을 활용하면 이러한 장점을 계속해서 누릴 수 있습니다.

+ Recent posts