웹 백엔드 개발/Spring Boot

[SpirngBoot/오류] 의존성 순환(Circular Dependency) 오류 해결

iinana 2025. 3. 21. 21:38

Spring Boot에서 OAuth2 파트를 공부하면서 만들어 둔 프로그램을 실행시키던 중 아래와 같은 오류가 발생했다. 

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  webOAuthSecurityConfig defined in file [C:\Users\...\build\classes\java\main\com\study\blogproject\config\WebOAuthSecurityConfig.class]
↑     ↓
|  userService defined in file [C:\Users\...\build\classes\java\main\com\study\blogproject\service\UserService.class]
└─────┘

 

 오류 메시지 중 "The dependencies of some of the beans in the application context form a cycle"는 의존성에 순환이 발생했다는 의미이다. Spring Boot에서는 기본적으로 순환 의존성을 허용하지 않는데, 오류 메시지에서 짚어준 파일을 보면, WebOAuthSecurityConfig.class와 UserSevice.class, 이 두 class에서 서로를 의존하는 것으로 보인다. 그래서 그 두 파일을 살펴보았다. 

 아래 코드를 보고 처음에는 WebOAuthSecurityConfig 클래스는 UserService를 주입받고 있으나, UserService는 WebOAuthSecurityConfig를 주입받지 않고 있다고 생각했다. 하지만 잘 보면, WebOAuthSecurityConfig에 @Bean으로 정의된 BcryptPasswordEncoder를 주입받고 있음을 알 수 있다. 이로 인해 순환 의존성 문제가 발생한 것이다. 

/** UserService.java **/
@RequiredArgsConstructor
@Service
public class UserService {
    private final UserRepository userRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    // WebOAuthSecurityConfig에서 @Bean으로 정의된 BCryptPasswordEncoder 주입
    
    public Long save(AddUserRequest dto) {
        return userRepository.save(User.builder()
                .email(dto.getEmail())
                .password(bCryptPasswordEncoder.encode(dto.getPassword()))
                .build()).getId();
    }

    /** 생략 **/
}
/** WebOAuthSecurityConfig.java **/

@RequiredArgsConstructor
@Configuration
public class WebOAuthSecurityConfig {
    private final OAuth2UserCustomService oAuth2UserCustomService;
    private final TokenProvider tokenProvider;
    private final RefreshTokenRepository refreshTokenRepository;
    private final UserService userService; //UserService 주입

    /** 생략 **/
    
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

 

 

 따라서 이를 해결하기 위해 아래와 같이 코드를 수정해줬다. UserService 클래스 내에서 BcryptPasswordEncoder가 사용되는 메서드는  save 메서드밖에 없었기 때문에 메서드 안에서 BcryptPasswordEncoder를 생성해주었다. 이렇게 하면 UserService 클래스에서 더 이상 WebOAuthSecurityConfig 클래스에 의존하지 않기 때문에 WebOAuthSecurityConfig 클래스는 따로 수정하지 않아도 된다. 

/** UserService.java 수정 **/
@RequiredArgsConstructor
@Service
public class UserService {
    private final UserRepository userRepository;

    public Long save(AddUserRequest dto) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        return userRepository.save(User.builder()
                .email(dto.getEmail())
                .password(encoder.encode(dto.getPassword()))
                .build()).getId();
    }
}
728x90
반응형