회원 컨트롤러(MemberController)를 구현하고, 이 때 회원 서비스(MembeerService)와 회원 리포지토리(MemberRepository)를 사용할 수 있도록 의존관계를 준비한다.
package hello.hellospring.controller;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
@AutoWired
가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다. 이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI(Dependency Injection), 의존성 주입이라고 한다.Parameter 0 of constructor in hello.hellospring.controller.MemberController required a bean of type 'hello.hellospring.service.MemberService' that could not be found
…
Consider defining a bean of type 'hello.hellospring.service.MemberService' in your configuration.
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Service
어노테이션을 달아줘서 스프링 컨테이너에 memberService 를 등록해준다.Dependency Injection
이다. (스프링이 주입~)@Repository
어노테이션을 달아준다.쉽게 정리하면?
memberController 생성 → 스프링 컨테이너에서 @Controller 확인 후 스프링 컨테이너에 등록하면서 생성자 호출 → 이 때 @AutoWired 확인해서 memberController 가 memberService 를 필요로 한다는 사실 확인하여 컨테이너에 있는 memberService 를 넣어준다.
여기서 service 와 repository 간에도 같은 과정 반복. 단지 memberRepository 가 아니라 구현체인 memoryMemberRepository 가 대상이다.
@Component
어노테이션이 있으면 스프링 빈으로 자동 등록된다.@Controller
컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.@Component
를 포함하는 다음 어노테이션도 스프링 빈으로 자동 등록된다.@Controller
@Service
@Repository
@Component
, 연결은 @AutoWired
!But, 아무 패키지의 파일에나 등록한다고 스프링 컨테이너에서 스캔 가능한 것은 아님!
기본적으로 Application 이 속한 패키지 하위 경로에서만 가능하다.
참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
무슨 말? 만약 memberService 이외에 orderService 가 있어서 memberRepository 를 요구할 경우 새로운 memberRepository 가 아니라 같은 인스턴스를 제공한다.