Spring 순환참조 오류

2023. 12. 12. 10:18카테고리 없음

최근 스프링에서 프로젝트를 구성하는 과정에서 순환참조 오류라는 처음보는 오류가 발생했다.

postman으로 api테스트를 진행하던도중 postman콘솔에 오류메세지가  출력되지않고

멈춰버리는 현상이 나타났던 것이다.

 

깜짝 놀라 인텔리제이 콘솔에서 수많은 오류코드를 지나 

 

다음과같은 챗바퀴같은 오류메세지를 볼수있었다.

 

순환참조가 발생하는 이유는 다음과도 같다.

 

스프링에서 순환 참조(circular dependency)란 서로를 참조하는 빈(Bean)이 발생하는 상황을 의미한다. 예를 들어 클래스 A가 클래스 B를 참조하고, 동시에 클래스 B가 클래스 A를 참조하는 경우 순환 참조가 발생하는 것이다.

 

둘이 계속 챗바퀴를 도는모습

 

이러한 순환 참조는 의존성 주입(Dependency Injection)을 사용하는 프레임워크에서 발생할 수 있는 문제로, 스프링은 기본적으로 싱글톤 범위의 빈을 사용하며, 빈을 생성할 때 해당 빈이 의존하는 다른 빈을 주입한다. 하지만 서로를 참조하는 빈이 있다면, 스프링은 머리가 아파지는 것이다!

 

그래서 이 프로젝트를 구동시 무한루프에 빠져 정상적으로 작동하지 않게된 것이다.

 

그럼 이를 어떻게 해결할 수 있을까??

 

생성자 주입-> 세터 주입방식

 

기존 생성자 주입방식은

public class MyClass {
    private final MyDependency myDependency;

    public MyClass(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
}

위와같이 객체가 생성될때 의존성이 주입되는 방식이었다.

 

세터 주입 방식은 객체를 생성한 후에 세터 메서드를 통해 의존성을 주입하는 방식이다. 즉, 클래스의 일반적인 세터 메서드를 통해 필요한 의존성을 주입한다.

public class MyClass {
    private MyDependency myDependency;

    public void setMyDependency(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
}

별 차이가 없어보이지만 생성자가 아닌 객체가 생성된 후 세터 메서드로 호출해서 의존성을 주입시켜준다.

 

그럼 세터주입이 무조건 더 좋은것인가? 그런건또 아니다.

각 방법의 장단점은 다음과 같다.

생성자 주입의 장단점

 

1. 불변성

생성자 주입은 필드가 final 로 선언되기때문에 객체의 불변성을 유지할 수 있다. 이는 객체의 안정성을 높이고, 의존성이 항상 주입되어 있어 객체가 유효한 상태를 유지할 수 있게 한다.

2. 코드의 명확성

생성자 주입은 객체가 필요로 하는 의존성이 무엇인지 명확하게 드러나므로 코드의 가독성을 향상시킨다.

 

3. 확실한 의존성 주입

객체가 생성될 때 모든 필수 의존성이 주입되어 있어야 하므로, 생성자 주입은 의존성 주입을 보장한다.