728x90
스프링(Spring)으로 웹 애플리케이션을 개발하다 보면, 서비스나 리포지토리 같은 빈(Bean)을 컨트롤러나 다른 클래스에 주입해야 하는 상황이 많습니다.
이때 사용할 수 있는 의존성 주입(DI, Dependency Injection) 방식은 크게 3가지가 있습니다.
1. 의존성 주입(DI) 방식 비교
1) 필드 주입 (Field Injection)
@RestController
public class SampleController {
@Autowired
private SampleService sampleService;
}
- 코드가 간단하고 빠르게 작성 가능
- 하지만 테스트 시 Mocking이 어렵고, 리플렉션(Reflection)에 의존 → 유지보수성 낮음
- 최근에는 잘 권장되지 않는 방식
2) 세터 주입 (Setter Injection)
@RestController
public class SampleController {
private SampleService sampleService;
@Autowired
public void setSampleService(SampleService sampleService) {
this.sampleService = sampleService;
}
}
- 런타임 중에도 의존성 변경 가능 → 유연성 있음
- 하지만 불변성(immutability)이 보장되지 않음
- 선택적인 의존성 주입에는 사용하기도 함
3) 생성자 주입 (Constructor Injection) ✅ 권장
@RestController
public class SampleController {
private final SampleService sampleService;
public SampleController(SampleService sampleService) {
this.sampleService = sampleService;
}
}
- 불변성 보장 (
final키워드와 함께 사용 가능) - 스프링 4.3 이후 → 생성자가 하나뿐이라면
@Autowired생략 가능 - 테스트 코드 작성이 용이 (Mock 객체 주입 가능)
- 의존성이 명확하게 드러나 코드 가독성 높음
2. Lombok과 함께 쓰는 생성자 주입
Lombok의 @RequiredArgsConstructor를 사용하면, final 또는 @NonNull 필드만 대상으로 자동으로 생성자 생성이 가능합니다.
@RequiredArgsConstructor
@RestController
public class PrivacyApiController {
private final PrivacyService privacyService;
@GetMapping("/api/v1/privacies")
public Page<PrivacyListResponseDto> findPage(RequestDto requestDto,
@PageableDefault(sort = "privacy_no", direction = Sort.Direction.DESC) Pageable pageable) {
return privacyService.findPage(requestDto, pageable);
}
}
→ 위 코드는 사실 아래와 동일합니다.
@RestController
public class PrivacyApiController {
private final PrivacyService privacyService;
public PrivacyApiController(PrivacyService privacyService) {
this.privacyService = privacyService;
}
}
✅ 코드 간결 + 불변성 유지 + 주입 방식 명확성 → 가장 깔끔한 스타일
3. 왜 생성자 주입을 권장할까?
- 불변성(Immutable) 보장
final과 함께 쓰면 런타임 중 변경 불가
- 테스트 용이성
- JUnit, Mockito 등으로 단위 테스트할 때 Mock 객체를 직접 주입 가능
- 순환 참조 방지
- 생성자 주입 시 순환 참조 문제가 발생하면 애플리케이션 실행 단계에서 바로 에러가 발생
- 필드 주입은 런타임 후에야 에러 확인 → 디버깅 어려움
- 명확한 의존성 표현
- 생성자를 보면 “이 클래스가 어떤 서비스에 의존하는지” 한눈에 파악 가능
4. 결론
스프링에서 의존성을 주입하는 방법은 여러 가지가 있지만,
실무에서는 생성자 주입(특히 Lombok의 @RequiredArgsConstructor 활용)이 가장 권장됩니다.
- 전자정부프레임워크(eGovFrame) 기반 프로젝트도 Spring 5 이상에서는 그대로 적용 가능
- MSA(Spring Cloud) 환경에서도 서비스 간 의존성을 안전하고 명확하게 관리할 수 있음
-> 따라서 새로운 프로젝트를 시작한다면, “생성자 주입 + Lombok 조합”을 기본 패턴으로 삼는 것을 추천
728x90
'개발 > Spring' 카테고리의 다른 글
| MSA 환경(JAR)에서 실행 가능한 Spring Interceptor 기반 중복 방지 + 버튼 비활성화 (0) | 2025.09.12 |
|---|---|
| Spring Interceptor 기반 중복방지 (0) | 2025.09.12 |
| Spring Boot와 Jasypt로 비밀번호 암호화 및 복호화 설정 (0) | 2025.03.17 |
| Spring Boot에서 JSP 페이지 접근 시 "Path with WEB-INF or META-INF" 경고 해결 방법 (0) | 2025.02.25 |
| Spring Framework 및 Spring Boot 버전에 따른 지원 Java 버전 (0) | 2025.02.24 |