스프링에서는 여러 빈을 관리하면서 의존성을 주입해준다.
이때 범위를 지정하여 어노테이션 된 클래스를 찾아 빈을 생성하거나 관리한다.
해당 글에서는 컨트롤러가 서비스, 리포지토리를 사용할 수 있도록 의존관계를 세팅하는 예시를 기록한다.
첫번째는 컴포넌트 스캔 방법이다.
빈으로 등록하기 위해 각각 어노테이션(@Component, @Repository, @Service, @Controller, @Configuration, @Autowired) 등을 사용하여 자동으로 의존관계가 주입되도록 한다.
1. 컨트롤러에 의존관계 추가
@Autowired 를 사용하면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 주입해준다.
이처럼 객체 의존관계를 외부에서 주입해주는 것을 DI (Dependency Injection), 의존성 주입이라 한다.
@Controller // 컨트롤러가 스프링 빈으로 자동 등록됨
public class MemberController {
private final MemberService memberService;
@Autowired // 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 주입해줌
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
2. 서비스에 스프링 빈 등록
생성자에 @Autowired를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아 주입한다.
또한, 생성자가 1개만 있으면 @Autowired를 생략할 수 있다.
@Service // 스프링 빈으로 자동 등록됨
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
3. 리포지토리에 스프링 빈 등록
@Repository
public class MemoryMemberRepository implements MemberRepository {
...
}
서비스와 리포지토리가 스프링 컨테이너에 스프링 빈으로 등록되었다.
🚨 참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본적으로 싱글톤으로 등록한다. 따라서 같은 스프링 빈이면 모두 같은 인스턴스이다.
자바 코드로 클래스를 따로 만들어 스프링 빈을 등록한다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
🚨 참고: @Autowired 를 통한 DI는 스프링이 관리하는 객체에서만 동작한다. 따라서 스프링 빈으로 등록하지 않고 직접 생성한 객체에서는 동작하지 않는다.
정형화된 컨트롤러, 서비스, 리포지토리를 사용하는 코드는 컴포넌트 스캔을 사용
정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야하는 상황에서는 설정을 통해 스프링 빈으로 등록하는 방법을 사용