컴포넌트 스캔과 자동 의존관계 설정

지금까지 맴버 서비스와 리포지토리와 맴버 객체를 만들고, 서비스를 통해서 맴버를 가입할 수 있고 맴버 리포지토리에 저장이 되고 리포지토리에서 꺼내올 수 있는 로직을 만들었습니다.

화면을 붙이고 싶은데 그렇기 위해선 컨트롤러와 뷰 템플릿이 필요합니다. 회원 가입이 되고 가입된 결과를 HTML로 뿌려주려 합니다.

그럼 우선 맴버 컨트롤러를 만들어야 하는데 맴버 컨트롤러가 맴버 서비스를 통해서 회원 가입을 하고 맴버 서비스를 통해서 조회할 수 있어야합니다.

이렇게 되는 것을 의존관계가 있다고 표현합니다. (맴버 컨트롤러가 맴버 서비스를 의존한다고 표현합니다.)

이 작업을 스프링답게 해보겠습니다.

MemberController 클래스를 만듭니다.

Untitled

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;

@Controller
public class MemberController {

}

여기까지만 해놓으면 기능은 없지만 스프링 컨테이너에 @Controller가 있으면 MemberController 객체를 생성해서 넣어주고 관리합니다. 그러니까 스프링과 관련된 컨트롤러 같은 기능이 동작합니다.

동작 원리 그림

이 것을 스프링 컨테이너에서 스프링 빈이 관리된다고 표현합니다.

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 {

    MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

이제 MemberService를 가져다 써야합니다.

그런데 MemberService memberService = new MemberService();처럼 new로 생성을 해서 쓸 수 도 있지만 스프링이 관리를 하게 되면 스프링 컨테이너에 등록을 하고 스프링 컨테이너에서 받아서 쓰도록 바꿔야합니다.

new해서 사용하면 문제가 있습니다. MemberController말고 다른 여러 컨트롤러에서 MemberService를 가져다 쓸 수 있습니다. 예를 들어, 주문 컨트롤러에서도 MemberService를 가져다 쓸 수 있고 여러 곳에서 가져다 쓸 수 있습니다.

하지만 인스턴스를 여러개 생성할 필요가 없습니다. 하나만 생성해서 같이 공용으로 사용하면 됩니다.

그래서 new로 생성을 해서 사용하는 것 보다는 스프링에 등록을 하고 사용을 하는게 좋습니다.

즉, 생성자로 만들어주고 @Autowired해주면 됩니다.

@Autowired 자세히

MemberController는 어차피 스프링 컨테이너가 뜰 때 생성을 해주는데 그 때 생성자를 호출하고 생성자에 @Autowired가 있으면 스프링이 스프링 컨테이너에 있는 memberService를 가져와서 연결시켜줍니다.

그런데 이대로 실행을 하면 오류가 뜹니다.

Consider defining a bean of type 'hello.hellospring.service.MemberService' in
  your configuration.

MemberController는 스프링이 뜰 때 스프링 컨테이너에 등록이 됩니다. @Autowired라고 되어있으면 스프링 컨테이너에서 관리하는 MemberService를 가져다가 넣어줍니다.

그런데 지금 보면 MemberService는 순수한 자바 클래스입니다. 스프링이 알 수 있는 방법이 없습니다.

MemberController는 애노테이션을 걸어두었으니 생성을 하는 규칙이 있지만 MemberService는 순수한 클래스라 아무것도 안됩니다.

그래서 MemberService에 @Service를 넣어줍니다.

@Service라고 하면 스프링이 올라올 때 MemberService을 서비스네 하고 스프링이 스프링 컨테이너에 등록해줍니다.