스프링 입문 -11. 컴포넌트 스캔과 자동 의존관계 설정

Sukhun-Net·2023년 5월 27일
post-thumbnail

배경

화면을 붙이고 싶다.
컨트롤러와 View templete 필요

멤버 컨트롤러 만들 때

  • 멤버 서비스를 통해 회원가입 해야한다.
  • 멤버 서비스를 통해 데이터 조회할 수 있어야 한다.
  • 이를 멤버 컨트롤러가 멤버 서비스를 의존한다고 표현

controller 에 MemberController 생성

@Controller
public class MemberController {
    
}

다음과 같이 annotation 작성해주면 (@Controller)
스프링 컨테이너(통)에서 MemberController를 객체로 생성하여 넣어둔다. 그리고 스프링이 이를 관리한다. ( = 이때, 스프링 컨테이너에서 관리하는 것을 스프링 빈이라고 한다.)

private final MemberService memberService = new MemberService(); 와 같이 객체를 새로 생성하기보다는 




private final MemberService memberService; 
+
// Generate(생성자) - Construct로 연결해주기   
@Autowired 
public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

// 뒤에 다시 같은 코드에 대한 설명있음. 
위와 같이 생성자에 @Autowired(annotation) - 연결 기능 

helloController는 스프링이 제공하는 컨트롤러여서 스프링 빈으로 자동 등록된다. @Controller 가 있으면 자동 등록된다.

반면, MemberService의 경우 다음과 같은 오류가 생긴다.

  • Error1 :
    'hello.hellospring.service.MemberService' that could not be found.

왜냐하면, MemberService 의 경우 순수한 자바 class 이다.
spring이 얘를 알 수 있는 방법이 없다.

해결책 : MemberService 코드에 가서 @Service 작성
=> 스프링 컨테이너에 memberService 등록해줌.

MemoryMemberRepository 에 가서는
@Repository 해준다.

MemberService - @Service

helloController - @Controller

*정형화된 방식
컨트롤러 통해서 외부 요청을 받고
서비스에서 비즈니스 로직을 만들고
리포지토리에서 데이터를 저장하고

상황 : 현재 컨트롤러와 서비스를 연결시켜줘야 함
=> @Autowired 사용

@Controller
public class MemberController {
    private final MemberService memberService;

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

위와 같이 생성자 (generate - construct) 에서 @Autowired 작성하면 MemberController가 생성이 될 때, spring bean 에 등록되어 있는 memberService 객체를 가져다 넣어줌

*이게 바로 의존관계 주입 (dependency injection, DI) 이다.

MemberService 코드에도 똑같이 다음과 같이 @Autowired 해주기

@Service
public class MemberService {

    private final MemberRepository memberRepository;

    @Autowired
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

■ 정리
스프링 빈을 등록하는 2가지 방법

  1. 컴포넌트 스캔과 자동 의존관계 설정
    ( 우리가 한 @Service 등의 작업이 컴포넌트 스캔)

왜 컴포넌트 스캔이라고 부르느냐?
-@Service 등 내부를 들어가보면 @Component를 포함하고 있음을 확인할 수 있음)

컴포넌트 관련된 annotation이 있으면 그것들은 모두 spring이 객체로 하나씩 생성하여 스프링 컨테이너에 등록을 한다.

@Autowired는 연관관계, 선을 연결해준다.

Autowired는

MemberController 가 memberService를 쓸 수 있게 해주고, memberService가 memberRepository를 쓸 수 있게 해준다.

Q. 그렇다면 아무곳이나 @Component가 있어도 되나요?

A: 아니다.

우리는 현재 HelloSpringApplication을 실행시키고 있다.

따라서, package hello.hellospring, 이 패키지를 포함해서 하위들은 자동으로 스프링이 다 뒤져서 스프링 빈으로 등록한다.

참고 : 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다.
(싱글톤? => 유일하게 하나만 등록해서 공유한다. memberService는 memberService 하나만. memberRepository는 memberRepository 하나만.)

따라서 같은 스프링 빈이면 모두 같은 인스턴스다.

  • Error2 : Run실행시 테스트코드에서 컨트롤러로 돌리는 방법
    HelloSpringApplication 클래스를 열면 좌측 중앙에 초록색 삼각형 버튼에 run 버튼 사용
  1. 자바 코드로 직접 스프링 빈 등록하기 (다음 강의)
profile
Data Scientist (Computer Vision, Multimodal)

0개의 댓글