[인프런] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB/섹션 4. 스프링 빈과 의존관계
컴포넌트 스캔과 자동 의존관계 설정
yyndevv
2023. 2. 24. 01:15
* 인프런 김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 강의를 듣고 작성한 내용입니다.
(강의 링크)
회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용할 수 있게 의존관계 준비
회원 컨트롤러에 의존관계 추가
MemberController: MemberService 통해서 회원가입, 데이터 조회 → 컨트롤러가 멤버 서비스에 의존한다!
@Controller annotation 있으면 스프링 뜰 때 딱 생성해서 자기가 관리를 한다. 스프링과 관련된 컨트롤러나 이런 기능들이 동작하는 것
// private final MemberService memberService = new MemberService();
// 하나만 생성해서 공용으로 쓰면 되기 때문에 위 표현 대신 아래와 같이 표현
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 // 생성자에 @Autowired 있으면 memberService를 스프링이 스프링 컨테이너에 있는 memberService에 연결시켜줌
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
@Autowired: 스프링 컨테이너에서 멤버 서비스 가져온다
- 이때 MemberService는 순수한 자바 클래스이므로 스프링이 얘를 알 수 있는 방법이 없음. annotation 있으면 스프링이 아 얘를 내가 관리해야겠다 하고 아는데 이 경우에는 모름.
해결책: @Controller @Service @Repository
- 굉장히 정형화된 패턴
- @Controller 컨트롤러 통해서 외부 요청 받고 @Service 서비스에서 비즈니스 로직 만들고 @Repository 리포지토리에서 데이터 저장
- 이렇게 하면 스프링이 뜰 때 컨트롤러 서비스 리포지토리 쫙 가지고 올라옴
Controller와 Serivce 연결시켜주어야 함
연결시켜줄 때 생성자에 @Autowired : MemberController 생성될 때 스프링 빈에 등록되어있는 MemberService 가져다가 넣어줌 → Dependency Injection
- memberService는 memberRepository가 필요
- @Autowired 되어 있으면 memberService 생성할 때 스프링 뜰 때 Service 등록하면서 생성자 호출
- @autowired 있으면 멤버 리포지토리 필요하구나 스프링 컨테이너에 있는 멤버 리포지토리(여기에서는 MemoryMemberRepository) 딱 넣어줌
그림처럼 연결 완성!
메인 메서드 잘 실행된다 하지만 회원 컨트롤러와 관련된 어떤 기능도 없는 상태 일단 연결만 한 것
스프링 빈을 등록하는 2가지 방법
- 컴포넌트 스캔과 자동 의존관계 설정: @Service @Controller @Repository 말고 원래 @Component 사용 → 컴포넌트 스캔이라고 함
- 스프링이 올라올 때 컴포넌트와 관련된 annotation 있으면 다 스프링이 객체 하나씩 생성해서 스프링 컨테이너에 등록
- Autowired는 선을 연결해주는 것
컴포넌트 스캔 원리
- @Component 애노테이션이 있으면 스프링 빈으로 자동 등록된다.
- @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
- @Component 를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록된다.
- @Controller
- @Service
- @Repository
- 궁금증: 아무곳에나 이 @Component 있어도 되나요?
- 기본적으로는 안됨, HelloSpringApplication의 패키지를 포함해서 하위들은 자동으로 스프링이 뒤져서 스프링 빈으로 등록. 그런데 이 하위 패키지가 이것과 동일하거나 아닌 경우에는 컴포넌트 스캔 하지 않음(특수하게 대상에 포함하게 하도록 하는 방법이 있긴 하지만 기본적으로는 X)
- 참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다. 용량도 절약할 수 있음!
오류 관련 해결
중간에 한참 테스트를 하다 넘어오자 정작 메인 메서드가 실행이 되지 않는 상황이 있었다. 아래 링크 참고하여 해결!
intellij로 스프링 실행시 test만 자꾸 실행될때 https://blog.codingteacher.kr/276