Written on
·
374
1
안녕하세요!!!!
제목 그대로 인터셉터를 2개 등록해서 사용하려고 했더니
Error creating bean with name 'memberApiController' defined in file [/Users/gimnayeon/Desktop/GreenProject/GrinGreen/out/production/classes/com/grin/GrinGreen/api/MemberApiController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberService': Unsatisfied dependency expressed through field 'passwordEncoder'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webConfig' defined in file [/Users/gimnayeon/Desktop/GreenProject/GrinGreen/out/production/classes/com/grin/GrinGreen/login/WebConfig.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'loginService': Unsatisfied dependency expressed through field 'passwordEncoder'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'getPasswordEncoder': Requested bean is currently in creation: Is there an unresolvable circular reference?
위와 같은 오류가 발생합니다.
상황을 대략 적자면
1번 인터셉터로 로그인 제외 url을 설정
2번 인터셉터로 api 작동 전 로그인 후 세션 주입
이렇게 처리를 하려고 하는데 @Autowired 문제일까요?
구글링을 해보려고 했으니 지금 티스토리 등이 정상적으로 열리지 않아 이렇게 질문 남깁니다ㅠ.ㅠ
MemberApiController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/api")
@RestController
public class MemberApiController {
private final MemberService memberService;
private final LoginService loginService;
/** 회원 등록 API **/
@PostMapping("/members")
public CreateMemberResponse saveMember(@RequestBody @Valid
CreateMemberRequest request) {
Member member = new Member();
member.setNickname(request.nickname);
member.setMail(request.mail);
member.setPassword(request.password);
member.setMember_type(request.member_type);
member.setMember_status(request.member_status);
member.setHint_password(request.hint_password);
member.setAnswer_password(request.answer_password);
member.setUpdated_at(now());
member.setCreated_at(now());
String mail = memberService.join(member);
return new CreateMemberResponse(mail);
}
/** 회원 수정 API **/
@PutMapping("/members/{mail}/edit")
public UpdateMemberResponse updateMember(@PathVariable ("mail") String mail,
@RequestBody @Valid UpdateMemberRequest request) {
memberService.update(mail, request.getNickname(), request.getAnswer_password());
Member findMember = memberService.findOne(mail);
return new UpdateMemberResponse(findMember.getNickname(), findMember.getMail(),
findMember.getHint_password(), findMember.getAnswer_password());
}
/** 회원 탈퇴 API **/
@PutMapping("/members/{mail}/delete")
public DeleteMemberResponse deleteMember(@PathVariable ("mail") String mail,
@RequestBody @Valid DeleteMemberRequest request) {
Member member = memberService.findOne(mail);
memberService.delete(mail, request.getPassword());
return new DeleteMemberResponse(member.getMail(), member.getMember_status());
}
/** 회원 로그인 API **/
@PostMapping("/login")
public LoginMemberResponse loginMember(@RequestBody @Valid LoginMemberRequest request) {
Member login = loginService.login(request.getMail(), request.getPassword());
return new LoginMemberResponse(login.getMail());
}
MemberService
@Slf4j
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
@Autowired
private final MemberRepository memberRepository;
@Autowired
private PasswordEncoder passwordEncoder;
/** 회원가입 **/
@Transactional
public String join(Member member){
//비밀번호 암호화 후 레포지토리에 넘기기
String encodedPassword = passwordEncoder.encode(member.getPassword());
member.setPassword(encodedPassword);
validateDuplicateMember(member);//중복회원검증
memberRepository.save(member);
return member.getMail();
}
/** 중복회원검증 **/
private void validateDuplicateMember(Member member) {
List<Member> findMembers = memberRepository.findByMail(member.getMail());
if (!findMembers.isEmpty()){
throw new IllegalStateException("이미 존재하는 회원입니다");
}
}
private void validateDuplicateNickname(Member member) {
Member findMembers = memberRepository.findOndByMail(member.getMail());
if (!findMembers.getNickname().equals(member.getNickname())){
throw new IllegalStateException("이미 존재하는 회원입니다");
}
}
/** 회원전체조회 **/
public List<Member> findMembers(){
return memberRepository.findAll();
}
public Member findOne(String mail) {
return memberRepository.findOndByMail(mail);
}
/** 회원 수정 **/
@Transactional
public void update(String mail, String nickname, String answer_password){
Member member = memberRepository.findOndByMail(mail);
if(nickname.equals(member.getNickname())) {
validateDuplicateNickname(member);
}
member.setNickname(nickname);
member.setAnswer_password(answer_password);
member.setUpdated_at(now());
}
/** 회원 탈퇴 **/
@Transactional
public String delete(String mail, String password){
Member findUser = memberRepository.findOndByMail(mail);
if(!passwordEncoder.matches(password,findUser.getPassword())){
//throw new IllegalStateException("비밀번호가 맞지 않습니다.");
System.out.println("암호 실패");
return null;
}
findUser.setUpdated_at(now());
findUser.setMember_status("D");
return findUser.getPassword();
}
}
LoginService
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class LoginService {
@Autowired
private final MemberRepository memberRepository;
@Autowired
private PasswordEncoder passwordEncoder;
public Member findOne(String mail){ return memberRepository.findOndByMail(mail);}
/** 로그인 **/
@Transactional
//public String login(Member member){
public Member login(String mail, String password){
List<Member> findMember = memberRepository.findByMail(mail);
Member findUser = memberRepository.findOndByMail(mail);
if (findMember==null){
//throw new IllegalStateException("해당 이메일의 유저가 존재하지 않습니다.");
//System.out.println("이메일 실패");
return null;
}
if(!passwordEncoder.matches(password,findUser.getPassword())){
//throw new IllegalStateException("비밀번호가 맞지 않습니다.");
return null;
}
System.out.println("로그인 완료 :"+findUser.getNickname());
//세션 표시를 위해 닉네임값 넘기기
return findUser;
}
/** 비밀번호 매치 **/
@Transactional
public String passwordMatches(Member member){
Member findUser = memberRepository.findOndByMail(member.getMail());
if(!passwordEncoder.matches(member.getPassword(),findUser.getPassword())){
//throw new IllegalStateException("비밀번호가 맞지 않습니다.");
System.out.println("암호 실패");
return null;
}
return findUser.getPassword();
}
/** 비밀번호 변경 **/
@Transactional
public void updatePassword(String mail, String editPassword){
Member member = memberRepository.findOndByMail(mail);
if (editPassword.equals(member.getPassword())) {
throw new IllegalStateException("이전 비밀번호와 동일합니다.");
}
member.setPassword(editPassword);
member.setUpdated_at(now());
}
}
WebConfig
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final LoginService loginService;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new LoginMemberArgumentResolver());
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginCheckInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/", "/members/new",
//"/login", "/logout", "/css/**", "/*.ico", "/error", "/api/**");
"/login", "/logout", "/css/**", "/*.ico", "/error");
registry.addInterceptor(new ApiLoginCheckInterceptor(loginService))
.order(2)
.addPathPatterns("/api/business")
.excludePathPatterns("/api/members/**");
}
}
ApiLoginCheckInterceptor
public class ApiLoginCheckInterceptor implements HandlerInterceptor {
private final LoginService loginService;
public ApiLoginCheckInterceptor(LoginService loginService) {
this.loginService = loginService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Member loginMember = loginService.login("test2@test.com", "test1234!");
HttpSession session = request.getSession();
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
return true;
}
}
Answer 1
0
안녕하세요. 김도연님, 공식 서포터즈 David입니다.
코드로는 안 올려주셨는데 스프링 시큐리티를 사용중이신 걸로 보입니다.
시큐리티 설정 클래스, PasswordEncoder 클래스 등과 관련된 의존관계 주입이 순환참조 형태를 띄고 있는 건 아닌지 확인해주세요.
감사합니다.
안녕하세요!
PasswordEncoder 의존 주입에 static을 붙이니 해결 됐습니다. 감사합니다!!!
혹시 이유를 알 수 있을까요?