시작이 반

[Spring] 8.스프링 빈과 의존관계 본문

Programming/Spring

[Spring] 8.스프링 빈과 의존관계

G_Gi 2021. 1. 20. 22:19
SMALL

강의 참고 : www.inflearn.com/roadmaps/373

 

[초급~중급] 우아한형제들 개발팀장 김영한의 스프링 완전 정복 | 더 나은 학습을 위한 가이드

대세를 따르세요! 자바 스프링 베스트셀러 우형 개발팀장에게 배우는 스프링 완전 정복 🚩 오픈 3개월 만에 수강생 7000+명의 극찬 릴레이 ✨원리와 실무를 한방에, 김영한의 스프링 학습 1O1! 입

www.inflearn.com

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

 

지금 까지는 멤버 서비스와 리포지토리를 만들었다.

서비스를 통해서 가입을하고 리포지토리에 저장하고 리포지토리에서 꺼내올 수 있는 로직을 만들었다.

이제 화면을 보여주고 싶다... -> 컨트롤러와 뷰 템플릿이 필요하다.

 

그럴려면 이제 멤버 컨트롤러를 만들어야한다.. 이 컨트롤러는 멤버 서비스를 통해 회원가입하고 데이터를 조회 할 수 있어야한다. 이것이 서로 의존관계에 있다고 하는 것이다.

 

 

스프링 컨테이너가 @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 {

    private final MemberService memberService;

    @Autowired //스프링 컨테이너에있는 멤버 서비스를 연결시켜줌
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

오류가난다.. 

memberService가 스프링 빈으로 등록되어 있지 않기 때문..

현재 MemberService는 순수한 자바 class코드이다.

이때 해당 클래스에 @Service를 넣어준다. 추가적으로 Repository쪽에는 @Repository를 넣어준다.

@Controller를 통해서 외부 요청을 받고

@Service에서 비지니스 로직을 생성

@Repository에서 데이터 저장

 

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

  • 컴포넌트 스캔과 자동 의존관계 설정
  • 자바 코드로 직접 스프링 빈 등록하기

스프링 빈은 등록될때 싱글톤으로 등록됨

 

컴포넌트 스캔 원리

  • @Component 애노테이션이 있으면 스프링 빈으로 자동 등록된다.
  • @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
  • @Component를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록 - @Controller @Service @Repository 

 

Controller와 Service를 연결시켜줄때 @Autowired를 사용한다.

Service는 Repository가 필요 이때도 마찬가지로 @Autowired사용

-> Dependency Injection (의존성 주입)

 

Component는 main으로 실행되는 패키지 안에서의 하위 패키지들을 뒤져서 있는것만 스프링 빈으로 등록

 


자바 코드로 직접 스프링 빈 등록

 

package hello.hellospring;

import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfig {

    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }
}

@Configuration 을 사용하여 Bean을 생성 할 수있다.

 

여기서는 향후 메모리 리포지토리를 다른 리포지토리로 변경할 예정이므로, 컴포넌트 스캔 방식 대신에 자바 코드로 스프링 빈을 설정함

 

  • 참고: DI에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있다. 의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.
  • 참고: 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다. 그리고 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다. -> 나중에 DB로 바꿀 것이다. 다른 코드는 수정하지 않고 바꿀수 저장소만 바꿀 수 있음
  • 주의: @Autowired를 통한 DI는 helloConroller, memberService등과 같이 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.

 

 

LIST