스프링은 스프링 컨테이너에 빈으로 등록된 객체를 담아 관리하며, 해당 객체들을 필요로 하는 곳에 자동으로 주입함. 또한 스프링 컨테이너가 관리하는 빈이어야만 의존성 주입을 받을 수 있음. 즉 주입받는 쪽과 주입되는 쪽이 모두 빈이어야 함
의존성 주입에는 @Autowired를 사용하는 등의 방법이 있지만 권장되는 방식은 생성자 주입
@Service
public class UserService {
// 사용할 필드를 명시하고
private final EmailService emailService;
// 생성자를 작성하면 스프링 컨테이너가 주입
public UserService(EmailService emailService) {
this.emailService = emailService;
}
}
만약 Lombok을 사용한다면 이렇게 줄일 수 있음
@Service
@RequiredArgsConstructor
public class UserService {
private final EmailService emailService; // final 필수!
}
이렇게 해 두고, 의존성 주입 관련 Config 객체를 별도로 두어 설정할 수 있음
이것의 목적은 저 EmailService가 인터페이스일 때, 구체적으로 주입되는 구현체를 정할 수 있음
@Configuration
public class AppConfig {
@Bean
public EmailService emailService() {
return new GmailService();
//return new NavermailService();
//return new HanmailService();
}
}
이렇게 하면 필요한 객체가 바뀔 때 서비스 로직을 직접 수정하는 것이 아닌 config만 수정하면 됨
UserService에서는 emailService가 어떤 객체로 들어오든 그저 자신의 로직을 수행
즉 객체 생성과 비즈니스 로직 수행이라는 관심사를 분리할 수 있음