해당 내용은 '스프링 입문을 위한 자바 객체 지향의 원리와 이해'와 인프런 김영한님의 '스프링 핵심 원리 - 기본편' 강의를 참고하였습니다.
자 조금만 생각해보자.
우리는 여태 많은 방법의 의존성 주입방법을 배웠다.
근데 우리가 주로 사용하는건 항상 생성자 주입이다.
왜 생성자 주입을 주로 사용하게 될까?
그 이유는 다음과 같다.
예를 들어서 설명해보자.
만약 우리가 기존에 사용하던 FixServiceImpl.java
에서 의존성 주입을 생성자가 아닌 수정자로 받고 있었다고 해보자.
FixServiceImpl.java
@Component
public class FixServiceImpl implements FixService {
private FuelTank fuelTank;
private Transmission transmission;
@Autowired
public void setFuelTank(FuelTank fuelTank){
this.fuelTank = fuelTank;
}
@Autowired
public void setTransmission(Transmission transmission) {
this.transmission = transmission;
}
...
자 이제 이 상태에서 순수한 자바 코드로 이루어진 테스트를 작성해보자.
FixServiceImplTest.java
class FixServiceImplTest {
@Test
void test(){
FixServiceImpl fixService = new FixServiceImpl();
fixService.getFixCost();
}
}
코드를 작성했을 때 아무런 이슈도 없고, 실행도 잘 된다.
그러나 결과는?
java: constructor FixServiceImpl in class hello.core.carTest.fix.FixServiceImpl cannot be applied to given types;
required: no arguments
found: hello.core.carTest.tank.FuelTank,hello.core.carTest.transmission.Transmission
reason: actual and formal argument lists differ in length
의존 관계 주입이 누락되었다고 나온다.
그러나 만약 우리가 수정자(Setter)대신에 생성자를 사용했다면 어떻게 될까?
FixServiceImpl.java
public class FixServiceImpl implements FixService {
private FuelTank fuelTank;
private Transmission transmission;
// @Autowired
// public void setFuelTank(FuelTank fuelTank){
// this.fuelTank = fuelTank;
// }
//
// @Autowired
// public void setTransmission(Transmission transmission) {
// this.transmission = transmission;
// }
@Autowired
public FixServiceImpl(FuelTank fuelTank, Transmission transmission) {
this.fuelTank = fuelTank;
this.transmission = transmission;
}
이미지 처럼 바로 문제 있다고 나온다.
테스트 코드에서도 문제 있다고 지적한다.
생성자 주입을 사용하면 주입해야하는 데이터를 누락하면 컴파일 에러가 바로 발생한다.
생성자를 사용하면, final 을 사용할 수 있다.
이는 1번 불변과 비슷한 맥락의 이야기로, 생성자 주입을 한 번 받으면 바뀌지 않는다.
즉, 생성자에서만 값을 세팅할 수 있다는 것이다.
그리고 final 키워드를 넣으면, 생성자에 값이 설정되지 않았을 때 컴파일 에러를 발생시켜준다.
참고 : 생성자 주입방식이외의 모든 주입 방식은 생성자 이후에 호출되므로,
final
을 사용할 수 없다.
ps. 컴파일 에러는..최고야