[섹션 4. 스프링 빈과 의존관계] 컴포넌트 스캔과 자동 의존관계 설정 / 인프런 김영한 스프링 입문
이번 시간에는 컴포넌트 스캔을 통한 의존관계 설정을 했다~~!
컴포넌트 스캔과 의존관계는 아래에 설명할 예정ㅋㅋㅋ
일단 화면 구현을 하기 위해서는 mvc중에서 컨트롤러랑 view 템플릿이 필요함.
회원가입하고 회원가입 결과를 html로 뿌려주는 작업을 할 예정인데,
그러기 위해선 멤버 컨트롤러를 만들어야 한다.
이 컨트롤러가 멤버 서비스를 통해서 회원가입을 하고 멤버 서비스를 통해서 데이터를 조회할 수 있어야 한다.
이것을 컨트롤러가 멤버 서비스를 의존한다고 표현함!
컨트롤러 어노테이션을 달아주면 스프링이 작동할 때,
스프링 컨테이너에 컨트롤러 어노테이션이 있으면
어노테이션이 달린 클래스 객체를 생성해서 스프링이 관리하게 된다.
아래처럼 어노테이션을 붙여줬으니 스프링 컨테이너가 관리를 함
MemberService를 가져다 쓸 때, 사진처럼 new 연산자로 만들수도 있지만~~ (이렇게 안한다는 뜻ㅋㅋㅋ)
스프링이 관리를 하게 되면 전부 스프링 컨테이너에 등록을 하고 스프링 컨테이너로부터 받아서 쓰도록 바꿔야함.
여러개 각각 컨트롤러에서 생성할 필요 없이
하나만 생성하면 스프링 컨테이너에 등록되고, 그것을 같이 공용으로 쓰면 된다.
그리고 Autowired 어노테이션을 걸어주면 컨테이너가 뜰 때, MemberController 객체를 생성함.
그리고 생성자를 호출한다.
MemberController의 파라미터인 MemberService를
스프링이 스프링 컨테이너에 있는 MemberService를 가져다가 연결을 시켜줌.
이렇게 서비스의 코드들을 보면 순수한 자바 코드이다.
이렇게 되면 스프링이 서비스의 위치를 알 방법이 없음;;
그렇기 때문에 Service 어노테이션을 달아주면 스프링이 올라올 때,
서비스를 인식하고 스프링 컨테이너에 MemberService를 등록해준다.
리포지토리도 마찬가지로 어노테이션 추가!
이렇게 컨트롤러, 서비스, 리포지토리 어노테이션을 달아주면,
스프링이 뜰 때, 저 3가지를 가져와서 스프링 컨테이너에 등록을 해준다~~
스프링 빈 등록 이미지와 의존 관계는 위와 같음~~!
의존 관계가 사진에서와 같이, 컨트롤러랑 서비스랑 연결시켜줘야한다.
나중에 Autowired로 연결해주면 Controller가 서비스를 쓸 수 있고, Service가 Repository를 쓸 수 있게 된다.
컨트롤러 클래스에서 MemberController가 생성이 될 때,
스프링 빈에 등록되어 있는 MemberService의 객체를 가져다가 Autowired를 통해서 넣어준다.
이렇게 의존관계를 주입해주는 것을 DI(Dependency Injection)라고 함.
서비스에서도 마찬가지로 Autowired 어노테이션을 추가해준다.
위에 설명한 것처럼, 스프링이 서비스를 스프링 컨테이너에 등록하면서 생성자를 호출한다.
서비스에 Autowired 되어 있는걸 보고 스프링이 MemberRepository가 필요한것을 인식함.
그래서 스프링 컨테이너에 있는 MemoryMemberRepository를 주입해준다~~
구현을 다하고 메인 메소드를 실행하니 이상없이 서버가 올라오는 것을 확인!
Controller, Service, Repository 모두 다 API를 확인해보면 Component 애노테이션이 있는걸 확인할 수 있음.
이렇게 위의 세개를 어노테이션해 컴포넌트 스캔이라고 부른다.
Component 어노테이션이 있으면 스프링 빈으로 자동 등록이 되며,
위의 세 어노테이션은 Component 어노테이션을 포함한다~~
작동 원리는 스프링이 올라올 때, 컴포넌트 관련 어노테이션들이 있으면(Controller, Service, Repository),
각자 객체로 하나씩 생성해서 스프링 컨테이너에서 등록해서 관리함.
그 다음에 Autowired를 통해 의존관계를 주입해준다.
그렇다면 의문이 드는점이, 아무 클래스나 만들어서 @Service 어노테이션을 달면 작동을 할까?
답은 X.
메인 메소드가 위치한 클래스의 패키지(hello.hellospring)와 그 하위 패키지들은 스프링이 스캔을 해서 스프링 빈으로 등록을 한다.
그 이외에 패키지들은 스프링 빈으로 컴포넌트 스캔의 대상이 아니기 때문에 등록하지 않음.
위의 예시에서 만든 demo 패키지는 메인 메소드의 클래스의 패키지와 하위 패키지에 속하지 않으므로 컴포넌트 스캔 대상이 아님~~
스프링이 빈을 등록하는 것에 관련해서,
스프링이 스프링 컨테이너에 스프링 빈을 등록할 때, 기본적으로 싱글톤을 등록한다.
싱글톤은 유일하게 하나만 등록한다는 뜻.
즉, helloController는 helloController 하나만! memberService는 memberService 하나만. 이런식으로~~!
유일하게 하나만 등록해서 공유한다.
그렇기 때문에 같은 스프링 빈이면 모두 같은 인스턴스이다.
예를 들어, memberService 말고 orderService(주문 서비스)가 있다고 했을 때,
Autowired해서 memberRepository를 연결하면, memberService에 연결한 같은 memberRepository의 인스턴스를 넣어준다~~!
그렇기 때문에 메모리도 절약되는 장점이 있다.