스프링 DI
스프링 DI 방식
생성자 주입
말 그대로 생성자를 이용하여 의존 관계를 주입하는 방법
생성자를 통해 주입하기 때문에 해당 객체 생성시 한번의 호출이 보장된다.
@Service public class UserImpl implements UserService{ private UserRepository userRepository; @Autowired public UserImpl(UserRepository userRepository){ this.userRepository = userRepository; } }
수정자 주입
메소드를 통해 객체를 주입하는 방식을 사용한다. 생성자 주입과는 달리 주입받는 객체가 변결될 가능성이 있는 경우 사용한다. (실제로 변경하는 경우는 드믈다.)
@Service public class UserImpl implements UserService{ private UserRepository userRepository; @Autowired public void setUserImpl(UserRepository userRepository){ this.userRepository = userRepository; } }
필드 주입필드에 바로 의존 관계를 주입하는 방법이다. 코드가 간결해 져서 많이 사용되었다. 그러나 외부에서 접근이 불가능하다. 또한 테스트 코드의 중요성이 부각됨에 따라 필드의 객체를 수정할 수 없는 필드 주입은 거의 사용하지 않게 되었다. 또한 필드 주입은 반드시 DI프레임워크가 존재해야한다.
@Service public class UserImpl implements UserService{ @Autowired private UserRepository userRepository; }
일반 메소드 주입일반 메소드를 활용하여 의존 관계를 주입하는 방법. 수정자 주입과 동일하며 마찬가지로 거의 사용할 필요가 없다.
⇒ 결론적으로 생성자 주입을 주로 사용한다.
생성자 주입이 선호되는 이유
객체의 불변성 확보
의존 관계의 변경이 필요한 상황이 거의 없음. 따라서 생성자를 통해 불변성을 보장하는게 좋다. 왜냐하면 생성자를 사용하면 단 1회의 객체 주입이 보장되기 때문이다.
테스트 코드의 작성
테스트 코드를 작성하는 경우 생성자를 통해 좀 더 간단하게 테스트 코드를 만들 수 있다. 만약 필드 주입을 사용하면 원하는 객체를 주입할 수 없으므로 생성자 주입이 유리하다.
SomeObject someObject = new SomeObject(); MadComponent madComponent = new MadComponent(someObject); madComponent.someMadPlay();
final 키워드 작성 및 Lombok과의 결합
생성자 주입을 통해 final을 사용하면 컴파일 시점에 누락된 의존성을 확인가능하다. 또한 final키워드를 붙임으로써 Lombok 과 결합되어 코드를 간결하게 작성할 수 있다.
@Service @RequiredArgsConstructor // final이 붙은 변수에 생성자 주입 public class UserServiceImpl implements UserServie{ private final UserRepository userRepository; @Override public void register(String name){ userRepository.add(name); } }
순환 참조 에러 방지
만약 순환참조를 생성자로 주입하게 되는 경우 이러한 순환 참조 에러를 사전에 방지할 수 있다. 왜냐하면 애플리케이션 구동시점(객체의 생성)에 파악 가능하다.
래퍼런스
https://mangkyu.tistory.com/125
https://madplay.github.io/post/why-constructor-injection-is-better-than-field-injection
'개발' 카테고리의 다른 글
[Java] static과 final의 차이가 뭘까?(feat. JVM 메모리) (2) | 2022.03.07 |
---|---|
JAVA의 스레드를 공부하자 (0) | 2022.02.26 |
[TDD] 자바와 JUnit을 활용한 실용주의 단위 테스트 (작성중) (0) | 2022.02.24 |
[JUnit5] JUnit5를 공부해보자(Spring Boot, REST API) (0) | 2022.02.24 |
JAVA의 Servlet이 뭐지? (0) | 2022.02.19 |