스프링 순환참조

이호석·2022년 7월 26일
0

프로젝트를 하던 도중 생각지도 못한 순환참조 에러를 만나게 되었다.

순환참조

순환참조란 서로 다른 beanA가 다른 beanB에 종속되고, beanB도 beanA에 종속될때를 의미한다. 스프링은 빈들을 생성할 때 순서를 정하고 그 순서에 맞게 생성을 하게 되는데, 위와 같은 상황은 서로가 서로를 의존하기 때문에 먼저 생성되어야하는 빈을 결정할 수가 없다.

해결방법

1. 재설계

순환참조가 발생했다면 보통 설계에 문제가 있고 책임이 잘 분리되지 않았다고 판단한다. 두 bean을 합쳐버리거나, 처음부터 아예 다른 방식으로 설계를 할 수도 있다.

2. @Lazy사용

스프링은 bean을 프로그램 시작시점이 아닌 해당 bean 실행시점에 초기화를 할 수 있다. 이 방식을 채택하면 프로그램 시작시간을 줄일 수도 있다.
물론 당연히 단점도 있다. 이 기능을 이용하면 프로그램의 문제 발견이 늦어질 수도 있고, HTTP 요청이 올 때 힙메모리를 사용하기 때문에 충분한 메모리가 있는지 미리 확인이 필요하다. 더 자세한 내용은 스프링 공식문서에서 확인이 가능하다.

3. Setter 이용

세번재 해결방법은 순환참조는 생성자 주입 방식에서만 발생하는데, 이를 이용한 setter메소드 주입 방식 이용이다. 이렇게 되면 스프링은 빈을 생성하기는 하지만 의존성은 필요할 때까지 주입되지 않는다. 그리고 해당 빈들의 메소드가 서로 순환호출을 해야만 에러가 발생한다. 여기서의 에러는 @ToString 순환호출과 흡사하다.

정리

검색을 많이 해봤지만 역시 가장 권장되는 해결책은 재설계다. 이번 에러를 마주친 이유는 기본적인 mvc패턴을 지키지 않아서이다. 이와 같은 실수가 반복되지 않기 위해서는 Repository -> Service -> Controller 단뱡향 의존성을 띄도록 관리하는 것이고, 지속적인 공부가 필요해 보인다.

0개의 댓글