본문 바로가기
일이야기/Spring

생성자 주입에 대하여...

by Cloud9™ 2022. 5. 17.

필드 주입을 하더라도 SpringBoot 2.6 이후 순환 참조가 기본적으로 금지되도록 변경되었다.

@Service
public class ServiceA {

    @Autowired
    ServiceB serviceB;

    public void test() {
        serviceB.test();
    }
}

@Service
public class ServiceB {

    @Autowired
    ServiceA serviceA;

    public void test() {
        serviceA.test();
    }
}

Field 주입을 사용한 경우에도 서버 기동 시 에러가 발생하면서 부팅이 되지 않는다.

굳이 순환참조를 허용하려면 application.properties에 다음을 추가해야 한다.

spring.main.allow-circular-references=true

 

물론 생성자 주입을 사용함으로써 발생 가능한 코드 악취를 제거할 수 있다.

클린코드의 저자 로버트C. 마틴에 따르면

함수는 인자는 0개가 가장 이상적이며 특별한 경우가 아니라면 3항을 넘지 말아야 한다고 권고한다.

함수에 입력 변수가 많으면 그만큼 복잡도가 높아지고 변수에 대한 의존도가 높아진다 뜻이다.

클래스의 경우에도 SRP(Single Responsibility Principle) 단일 책임 원칙에 따라

코드가 변경될 이유는 오직 단 한 가지여야만 하는데 너무 많은 의존 주입은 코드 변경의 이유를 만들게 된다.

의존 주입이 많아진다는 건 하나의 클래스에 기능이 집약된다는 의미다.
어느 함수든 3항 이상의 인자를 가진다면 설계를 변경해야 할 요건 중 하나다.

그러나 이건 필드 주입에 대한 갯수 제한을 미리 약속할 수도 있고

특히 Lombok의 @RequiredArgsConstructor를 사용하게 되면 필드 주입과 다를 바가 없다.

 

생성자 주입을 사용하면 테스트 시에 @Mockito를 사용하지 않고도

생성자를 직접 호출해서 테스트를 할 수 있다는 장점이 있다.

new를 사용해서 서비스를 호출해도 nullPointerException에서 자유롭다.

하지만 개발/테스트 서버가 제공되는 환경에서 바로 테스트 가능한 경우에는 필요하지 않다.

 

마지막으로 생성자 주입 시 Bean을 final로 선언하여 immutable한 코드 작성이 가능하다.

다만 누가 serviceB를 다른 값으로 변경하겠냐는 물음에는 답을 찾기 어려울 수 있다.

주변이 이렇게 코딩하는 사람이 있으면 살려둬서는 안된다.

 

결론은...

필드 주입을 잘 쓰고 있는 개발자에게 이제부터 생성자 주입을 사용하라고

설득해야 하는데 Spring Boot 2.6 이전보다 저항력이 높아졌다는거다. 

정말 뭔가 어쩔 수 없이 바꿔야 한다라는 강력한 펀치 포인트가 있어야 하는데...흠

그래서 Spring Team에서도 권고만 하는 것이려니 생각해본다.

댓글