문제
repositoryImpl부터 하나씩 구현하고 있는데 @Autowired 주입이 안되는 문제가 발생했다.
문제 원인
이 오류는 @Autowired가 붙은 userRepository 필드가 Spring에서 관리되고 있는 Bean 내부에서 선언되지 않았기 때문에 발생하는 문제이다."must be defined in valid Spring bean"이라는 것은 @Autowired가 작동하려면 이 코드가 Spring이 관리하는 객체, 즉 Bean이어야 한다는 뜻이다.
UserServiceImpl 클래스는 서비스 계층을 담당한다.이 클래스 자체가 Spring의 Bean으로 등록되어 있어야 스프링이 userRepository를 자동 주입할 수 있다. 그런데 지금 이 클래스에 @Service나 @Component 같은 Bean 등록 어노테이션이 빠져 있기 때문에 오류가 발생한 것이다.
해결 방법
UserServiceImpl 클래스 선언부 위에 아래처럼 @Service 어노테이션을 추가하면 된다.
@Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@Autowired
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
// ...
}
@Service는 이 클래스가 비즈니스 로직을 담당하는 서비스 계층이라는 것을 의미한다. 어노테이션을 붙이면 Spring이 이 클래스를 Bean으로 등록한다. 어노테이션을 붙이면 Spring이 UserServiceImpl 객체를 생성하고, 생성자에 UserRepository를 자동으로 주입할 수 있게 된다.
추가로, @Service가 제대로 동작하려면 applicationContext.xml 또는 root-context.xml에 컴포넌트 스캔 설정이 있어야 한다. 예를 들어 com.hello.user.service 패키지에 이 클래스가 있다면, 아래와 같은 설정이 있어야 한다.
<context:component-scan base-package="com.hello.user"/>
이 설정을 통해 @Service, @Component, @Repository, @Controller 같은 어노테이션이 붙은 클래스들을 자동으로 감지하고 Bean으로 등록하게 된다.