발생
게시판 만들기 프로젝트 진행 도중 테스트 코드 작성 후 실행 시 해당 오류가 발생하였다.
에러 로그
expected at least 1 bean which qualifies as autowire candidate
현재 내 프로젝트 내부 코드에서 Beans의 생성자를 찾거나 정의하지 못하는 경우 발생한다. 오류 내용을 자세히 살펴보자.
- expected at least 1 bean which qualifies as autowire candidate : autowired 할 bean이 적어도 1개 필요
- 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로 설정하면 된다. 이 경우 자동 주입할 대상이 없어도 오류가 발생하지 않는다. 더 정확히는 자동 주입할 대상이 없으면 수정자 메서드 자체가 호출되지 않는다.