본문 바로가기
공부/Trouble Shooting

빈 순환참조 문제 The dependencies of some of the beans in the application context form a cycle:

by son_i 2023. 10. 21.
728x90

회원가입, 로그인 인증 구현 후 프로젝트 실행시켰더니 오류가 발생했다.

***************************
APPLICATION FAILED TO START
***************************

Description:

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

   jwtAuthenticationFilter defined in file [C:\spring_prac\Mission\reservation\out\production\classes\com\soni\reservation\security\JwtAuthenticationFilter.class]
┌─────┐
|  tokenProvider defined in file [C:\spring_prac\Mission\reservation\out\production\classes\com\soni\reservation\security\TokenProvider.class]
↑     ↓
|  manageService defined in file [C:\spring_prac\Mission\reservation\out\production\classes\com\soni\reservation\service\ManageService.class]
└─────┘


Action:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.


Process finished with exit code 1

➡️원인

빈 순환참조 문제 !

애플리케이션 커넥스트에서 일부 Bean의 종속성이 순환주기를 형성할 때 문제가 발생함.

순환 종속성/순환 참조 문제는 둘 이상의 Bean이 생성자를 통해 서로를 주입하려고 할 때 발생.

 

코드를 보면

memberService에 이 부분이 있고

    private final TokenProvider tokenProvider;

TokenProvider에 이 부분이 있다.

    private final ManageService manageService;

여기서 참조를 끊어주려면 TokenProvider에서 ManageService를 필요하지 않게 해주면 될 것 같다.

아니면 memberService에서 토큰을 컨트롤러에 반환하는 부분을 컨트롤러에서 차라리 service의 리턴값을 받아 generateToken을 호출해줘도 된다. 둘 중 뭐가 더 좋은 방법일까 ?

 

➡️해결

security- GetAuthentication 클래스 파일 생성.

TokenProvider에서 유일하게 memberService 를 참조해야하는 getAuthentication을 이 파일로 옮김.

 

- GetAuthentication.java

package com.soni.reservation.security;

import com.soni.reservation.service.ManageService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class GetAuthentication {
    private final ManageService manageService;
    private final TokenProvider tokenProvider;

    public Authentication getAuthentication(String jwt) {
        //jwt 토큰으로부터 인증정보를 가져옴
        UserDetails userDetails = this.manageService.loadUserByUsername(tokenProvider.getMail(jwt));

        //스프링에서 지원해주는 토큰 형식으로 바꿔줌.
        //리턴되는 토큰은 사용자 정보와 사용자 권한 정보를 가지게 됨.
        return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
    }

}

나머지 코드 충돌이 일어나는 부분 고쳐줌

오류 해결 ~