반응형

문제 개요
Spring Boot Application Initialize 후 의존성 주입 과정에서 순환참조 문제가 발생했다.

원인 분석
Bean 생성 과정에서 상호 의존성을 주입하는 과정에서 순환참조 문제가 발생했음.
문제의 코드
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final Rq rq;
// JwtAuthFilter → memberService 의존
private final MemberService memberService;
// ...
}
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberService {
private final MemberRepository memberRepository;
// memberService → SecurityConfig.PasswordEncoder 의존
private final PasswordEncoder passwordEncoder;
private final AuthTokenService authTokenService;
// ...
}
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig {
// SecurityConfig → JwtAuthFilter 의존
private final JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// ...
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
IOC 컨테이너는 빈 생성 과정에서 모든 빈 오브젝트를 싱글톤으로 만들게 되는데,
이 과정에서 싱글톤으로 만들어진 빈 오브젝트가 우로보로스처럼 서로를 호출해서 문제가 발생함.
이렇게 서로를 꼬리물듯이 의존성을 주입하게 되면 스프링 IOC 컨테이너는 어떤 스프링 빈을 기준으로 먼저 생성하고 의존성을 주입할지 결정할 수 없는 문제가 발생한다.
해결 방법
문제의 빈 객체를 다른 클래스로 이동 (해결)
@Configuration
@RequiredArgsConstructor
public class AppConfig {
@Bean
// 기존 SecurityConfig → AppConfig으로 이동
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
순환참조 구조를 해소할 수 있게끔 순환참조 문제의 빈 콘텍스트를 다른 클래스로 이동시켰다.
따라서 개선된 구조는 아래와 같이 순환참조 문제를 해결하였다.
- 기존 : JwtAuthFilter → MemberService → SecurityConfig → JwtAuthFilter →...
- 개선 : AppConfig → MemberService → SecurityConfig → JwtAuthFilter
@Lazy를 사용하는 방법 (권장되지 않음 / 대안)
Lazy를 사용하면 프록시 객체를 통해 Bean을 생성하며, 필요 시점에 호출하여 빈을 생성한다.
이는 단순히 잘못된 구조에서 Bean 생성시점을 늦출 뿐이기에 근본적인 해결책이 되지 못한다.
기존에 의존성 구조를 구성할 때 순환참조가 발생하지 않게 짜는 것이 좋다.
반응형
'DEV > Spring' 카테고리의 다른 글
| [Spring] 이메일 코드 발송 서비스 개발 간 @Async 적용 (0) | 2026.03.19 |
|---|---|
| [Spring] SecurityConfig Spring Method Security 적용하기 (0) | 2024.02.20 |
| [트러블슈팅][Spring] ApplicationRunner RuntimeException 발생 시 shutdown되는 오류 해결 (0) | 2024.02.20 |
| [트러블슈팅][Spring] .sql 파일 init이 자동으로 실행되지 않는 문제 원인 / 해결방법 (0) | 2024.02.20 |
| [트러블슈팅][Spring] JPA OneToOne 양방향 관계 시 의도하지 않은 N+1 문제 발생 원인과 해결 방법 (0) | 2024.02.20 |