ss35789 / ShopEase-BE

ShopEase project(BE)
0 stars 0 forks source link

[스프링 순환 참조(Circular reference)란?] #5

Open ss35789 opened 2 months ago

ss35789 commented 2 months ago

서로 다른 빈(Bean)이 서로를 참조하면서 스프링이 어떤 빈을 먼저 생성해야 할지 결정하지 못하기 때문에 발생한다.

순환 참조는 DI 상황에 발생한다. DI 방법은 Setter, 필드, 생성자 방식으로 3가지가 있다.

Setter, 필드 주입 방식 필드, Setter 주입 방식에서는 애플리케이션 로딩 중에는 순환 참조 문제가 발생하지 않는다. 애플리케이션 로딩 중에 주입하지 않고 실제로 사용하는 시점에 주입을 하기 때문에 해당 메서드를 호출하는 시점에 순환 참조가 발생한다. 생성자 주입 방식 반면 생성자 주입 방식은 애플리케이션 로딩 중에 순환 참조가 발생한다. 빈을 생성하는 시점에 참조하려는 다른 빈을 주입해줘야 하기 때문이다. 순환 참조의 경우 빈A와 빈B가 서로를 참조하다보니 서로가 서로를 주입하는 무한 반복이 발생하는 것이다.

해결 PasswordEncoder Bean을 SecurityConfiguration 외부에서 등록되도록 분리해야 한다.

PasswordEncoderConfig 클래스를 만들어 이 클래스에서 PasswordEncoder Bean을 생성하도록 하자

@Configuration
public class PasswordEncoderConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
}

같은 방법으로 비지니스 코드를 Controller에서 Service 레이어로 모두 정리하려고 하는데 생긴 순환 참조,


@Configuration
public class AuthenticationManagerConfig {

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

}

위와 같은 방법으로 해결하려 했지만 실패

ss35789 commented 2 months ago

UserDetailService 를 상속받았던 UserService에서 분리해 따로 UserDetailService 클래스를 만들어 해결