본문 바로가기
에러노트

expected at least 1 bean which qualifies as autowire candidate

by o3oppp 2025. 1. 21.

발생

게시판 만들기 프로젝트 진행 도중 테스트 코드 작성 후 실행 시 해당 오류가 발생하였다.

에러 로그

expected at least 1 bean which qualifies as autowire candidate

현재 내 프로젝트 내부 코드에서 Beans의 생성자를 찾거나 정의하지 못하는 경우 발생한다. 오류 내용을 자세히 살펴보자.

  1. expected at least 1 bean which qualifies as autowire candidate : autowired 할 bean이 적어도 1개 필요
  2. No qualifying bean found for dependency : 종속에 적합한 bean이 없음

결론적으로 Autowired 할 수 있는게 없다는 뜻으로, 로그에서 알려주는 클래스를 확인해보았다.

해결

PostDto.java

package project.post.dto;

import lombok.Getter;
import lombok.Setter;
import project.post.domain.PostStatus;

import java.time.LocalDateTime;

@Getter
@Setter
public class PostDto {
    String title;
    String content;
    LocalDateTime postDate;
    
    public PostDto(String title, String content, LocalDateTime postDate) {
        this.title = title;
        this.content = content;
        this.postDate= postDate;
    }
}

PostService.java

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class PostService {
	
    private final MemberRepository memberRepository;
    private final PostRepository postRepository;
    //private final PostStatus postStatus; // 오류 발생 원인

    /**
     * 게시글 등록
     */
    @Transactional
    public Long savePost(Long memberId, PostDto postDto){
        Member member = memberRepository.findOne(memberId);
        Post post = new Post();
        post.setTitle(postDto.getTitle());
        post.setContent(postDto.getContent());
        post.setStatus(PostStatus.CREATE);
        post.setPostDate(postDto.getPostDate());
        post.setMember(member);
        postRepository.savePost(post);
        return post.getId();
    }

    /**
     * 게시글 조회
     */
    public Post findPostById(Long postId){
        return postRepository.findOne(postId);
    }
	...
}

@RequiredArgsConstructor에 의해 final 키워드가 붙은 인스턴스들을 Bean 객체로 등록하려 했다. 하지만 PostStatus.java 는 DTO로 스프링 Bean이 아니기 때문에 오류가 발생하였다. 필자는 PostStatus를 주석처리하여 해결하였지만, 다음과 같은 추가적인 방법이 존재한다.

@Service
@Transactional(readOnly = true)
public class PostService {
	
    @Autowired private final MemberRepository memberRepository;
    @Autowired private final PostRepository postRepository;
    @Autowired(required=false) private final PostStatus postStatus;
	...
}

@Autowired의 required 기본값은 true이기 때문에, 자동 주입 대상이 없는 경우 required 값을 false로 설정하면 된다. 이 경우 자동 주입할 대상이 없어도 오류가 발생하지 않는다. 더 정확히는 자동 주입할 대상이 없으면 수정자 메서드 자체가 호출되지 않는다.