Inflearn brand logo image

인프런 커뮤니티 질문&답변

wlsql852님의 프로필 이미지
wlsql852

작성한 질문수

토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1

회원 애플리케이션 서비스 테스트 (2)

EmailSender, passwordEncoder 빈 주입 문의

작성

·

162

3

안녕하세요, 강사님. 올려주신 강의를 열심히 듣고 있습니다.

제가 코드를 따라하고 있는데 MemberService에서 주입한 emailSender와 passwordEncoder에 Could not autowire. No beans of 'PasswordEncoder' type found. 라는 오류가 뜹니다.
찾아보니 해당 인터페이스가 빈으로 등록되지 않아서 생긴 오류라고 하는데 어디서 빈으로 등록한건지 못찾겠습니다. 급한대로 두 인터페이스에 @Component를 해봤는데 MemberService의 오류는 사라졌지만 MemberResisterTest에 NoSuchBeanDefinitionException 문제가 뜹니다.
원래는 인터페이스들을 어떻게 빈으로 등록했던건가요?

답변 3

1

토비님의 프로필 이미지
토비
지식공유자

이 에러를 만난 것이 다음 중 어떤 상황인지에 따라서 해결 방법이 다릅니다.
1. 테스트 실행 중에 에러 발생
2. Splearn 애플리케이션 실행 중에 에러 발생
3. IntelliJ에서 코드를 보는 중에 warning/error 아이콘이 보여서 살펴보이 이런 메시지 발생

1번이라면 제가 강의를 진행하는 중에 다음과 같은 테스트 설정 파일을 만들어서 해당 인터페이스를 필요로 하는 MemberService 등이 뜰 때 에러가 나지 않도록 했습니다. 혹시 test 모듈에 이게 빠진 건 아닌지 확인해보세요.

 

@TestConfiguration
public class SplearnTestConfiguration {
    @Bean
    public EmailSender emailSender() {
        return (email, subject, body) -> System.out.println("Sending email: " + email);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return MemberFixture.createPasswordEncoder();
    }
}

 

2번이라면 아마 강의 흐름에서 테스트를 통해서만 검증을 했고, 스프링 부트 애플리케이션을 직접 띄우는
것은 없었기 때문에 애플리케이션 실행을 하면 이 문제를 만났을 수도 있습니다. 좀 더 수업이 진행되면 main 모듈 쪽에 이 두 개의 인터페이스 구현을 한 코드를 넣는 부분이 나옵니다. 그 때까지는 우선 테스트를 통해서만 검증을 해보시면 좋겠습니다. 그래도 정 궁금하시면 강의 예제 최종 본에서 이 두 개의 인터페이스를 구현한 코드를 찾아서 main 모듈 쪽에 넣으시면 됩니다.

 

3번은 IntelliJ의 스프링 지원 기능 오류, 버그 때문에 보이는 겁니다. 이건 그냥 무시하시면 됩니다. IntelliJ의 스프링 빈 체크 기능은 악명이 높습니다. 그래서 저는 이걸 끄도록 강의 중간에 한번 설명 드릴텐데요. 정확하지도 않을 뿐더러, 개발중에 자꾸 쓸데없이 튀어 나와서 방해가 됩니다. 에러 메시지를 클릭하시고 inspection을 중지시키면 더 이상 보이지 않을 겁니다. 빈의 의존성 검증은 테스트를 실행하거나 애플리케이션을 시작하면 정확하게 확인이 되기 때문에 IDE의 부족한 기능에 의존할 필요는 없습니다.

 

마지막으로, 인터페이스에는 @Component를 붙이지 않습니다. 빈은 오브젝트로 만들어져야 하는데 그러려면 클래스가 필요하기 때문입니다. 인터페이스에만 넣으면 이를 구현한 클래스가 없어서 DI로 주입하는 게 불가능하니, 이런 상황에서 문제가 해결되지는 않습니다.

 

해보시고 그래도 문제가 계속 발생한다면, GitHub에 코드를 공유하고 알려주시면 제가 받아서 확인해볼 수도 있습니다. 어쨌든 궁금하신 건 계속 질문을 해주세요.

0

저도 동일한 질문을 하려고했는데, 이미 질문 답변이 이뤄지고 있었네요. ㅎㅎ 패스워드 인코더랑 이메일 센더 구현체가 없으니 스프링 빈 주입 안되는 게 맞는 거 같고, 인텔리제이가 적절하게 빨간줄 그어주고 있는 상황입니다..

궁금한 것은 토비님 인텔리제이 화면에서는 왜 빨간줄이 그어지지 않는지 궁금하네요. 강의 준비하시면서 미리 구현체를 만들어 두신건가요?

 

스프링을 잘 모르느시는 분들은 혼란 스러울 만한 거 같긴합니다.

토비님의 프로필 이미지
토비
지식공유자

강의에 보여지지 않는 코드를 따로 만들지는 않습니다.

IntelliJ의 과도한 inspection을 끄는 것도 설명을 해야 하기 때문에 미리 세팅을 바꾸지 않은 상태로 IDE를 초기화 하고 강의 녹화를 시작했습니다.

만약 제가 작업할 때는 안 나왔는데 수강하시는 분들이 코드를 만들 때 나왔다면, 추측되는 이유는 강의 녹화 중에 IntelliJ 버전이 한번 업그레이드 됐는데, 그 이후에 스프링 관련 빈 체크 기능이 훨씬 강화되어서 나올 수 있을 듯합니다. 그래서 최신 버전으로 처음부터 코드를 작성하시는 경우, 저는 보지 못했던 스프링 관련 체크가 강조되어 보일 수는 있겠네요.

강의 어느 부분에선가 제가 강조해서 말씀드리지만, IntelliJ의 스프링 관련 각종 체크 기능은 끄시는게 좋습니다. 별 도움이 안 되는데다 문제가 있는 것도 아닌데 경고나 에러가 떠서 개발자를 당황시킵니다. 코드 편집 중에 나오는 스프링 관련 경고 등은 무시해주세요.

0

안녕하세요, 인프런 AI 인턴입니다. wlsql852님, 질문 주신 사항에 대해 도와드리겠습니다.

MemberService에서 emailSender와 passwordEncoder가 자동으로 주입되지 않는 이유는 이들에 대한 빈이 스프링 컨텍스트에 등록되지 않았기 때문입니다. 이 문제를 해결하려면 EmailSender와 PasswordEncoder 타입의 빈을 수동으로 정의하거나, 직접 구성 클래스를 만들어 빈을 등록해야 합니다.

빈으로 등록하는 방법은 여러 가지가 있습니다. 가장 일반적인 방법은 @Configuration 어노테이션이 붙은 클래스 내에 @Bean 어노테이션을 사용하여 해당 타입을 반환하는 메서드를 정의하는 것입니다. 예를 들어:

@Configuration
public class AppConfig {
    
    @Bean
    public EmailSender emailSender() {
        return new YourEmailSenderImplementation();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); // 혹은 원하는 구현 클래스
    }
}

이렇게 구성 클래스를 추가하면 설정된 구현체가 생성되어 스프링 컨텍스트에 등록됩니다.

실제로 MemberService를 위한 예제나 내용을 다루는 이 유사한 질문를 참고하셔도 좋습니다. 여기서도 빈 불일치 또는 등록 문제를 다루고 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

wlsql852님의 프로필 이미지
wlsql852

작성한 질문수

질문하기