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