스프링 입문 (5) - 스프링 빈과 의존관계

2024. 3. 15. 20:00·스프링

전전차시에서 봤던 스프링 구조를 살펴보자.

스프링 컨테이너에 helloController가 등록되어 있는 것을 볼 수 있다.

이를 스프링에서 "스프링 빈"에 등록되었다 라고 하며, 스프링 빈 내에서 의존관계를 가지며 동작하게 된다.

초록색 동그라미가 땅콩(bean)같다고 하여 빈이라고 표현하는 것 같다.

무슨 소리인가 싶겠지만, 천천히 알아보자.

 

이전차시에서 Member에 관련된 서비스, 리포지토리, 객체를 만들었다.

이들을 유기적으로 연결하여 멤버 컨트롤러가 서비스를 통해서 기능하고, 서비스는 리포지토리를 통해 데이터를 조회할 수 있어야한다. (의존 관계가 있다.)

 

다음과 같이 의존관계를 표현할 수 있고, 이를 스프링 컨테이너에 스프링 빈이 관리된다고 표현한다.

컨트롤러 외부 요청 -> 서비스 비즈니스 로직 동작 -> 리포지토리 데이터 저장 ... 정형적인 패턴으로 기억해두면 된다.

 

컨트롤러가 서비스에 의존하고,

서비스가 리포지토리에 의존하고... 를 이해하면 아래에서 DI를 받는 것이 이해될 것이다.

 

 

hello/hellospring/controller/MemberController.java

package hello.hellospring.controller;

import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

// @Controller를 명시함으로써 스프링 컨테이너가
// 스프링이 처음에 실행될 때 멤버컨트롤러 객체를 생성하여 스프링 빈에 등록한다.
@Controller
public class MemberController {

    private final MemberService memberService;

/*  @Autowired란? 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어줌.
    이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI(Dependency Injection, 의존성 주입)이라 함.
    이전 테스트에서는 개발자가 직접 주입했고, 여기서는 @Autowired에 의해 스프링이 주입함
*/
    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

}

 

MemberService 클래스에도 @Service를 붙여준다.

MemoryMemberRepository 클래스에도 @Repository를 붙여준다.

 

 

 

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

 

1. 컴포넌트 스캔과 자동 의존관계 설정 (위에서 한 방법)

2. 자바 코드로 직접 스프링 빈 등록하기

 

 

컴포넌트 스캔 원리

- @Component - 스프링 빈으로 자동 등록

- @Component를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록(애노테이션 클래스에 들어가보면 @Component가 애노테이션 되어있음)

    - @Controller

    - @Service

    - @Repository

 

참고

- 생성자가 1개만 있으면 @Autowired는 생략할 수 있음

- 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록함(유일하게 하나만 등록해서 공유). 따라서 같은 스프링 빈이면 모두 같은 인스턴스임. 설정으로 싱글톤이 아니게 설정할 수 있지만 특별한 경우를 제외하면 대부분 싱글톤 사용

- HelloSpringApplication.java 가 속해있는 hello.hellospring 이외의 패키지에서의 애노테이션은 스프링에서 스캔하지 않으므로 적용되지 않음

 

 

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

MemberService, MemoryMemberRepository에서 먼저 애노테이션을 지우고 진행한다.

 

hello/hellospring/service/SpringConfig.java

package hello.hellospring.service;

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

@Configuration
public class SpringConfig {
    // MemberController은 따로 등록 못해줘서 Autowired해줘야함
    @Bean
    public MemberService memberService() {
        return new MemberService(memberRepository());
    }

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

 

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

 

참고

- 과거에는 XML로 설정했지만 요즘엔 잘 사용하지 않음

- 실무에서는 자바코드로 많이 사용

- DI에는 필드 주입, setter 주입, 생성자 주입 3가지 방법이 있다. 의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장함

- 필드 주입 : @Autowired private MemberService memberService;

- setter 주입 : 나중에 호출이 돼서 멤버서비스에 들어옴. public으로 열려있어야 된다는 단점이 있음. 중간에 바꿀일이 없는데도 ㅠ. final로도 선언못해서 바뀌게 되는거

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

- 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다.

- 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면(이전에 메모리멤버리포지토리를 쓰다가 다른 DB로 변경해야 하는 경우)설정을 통해 스프링 빈으로 등록한다(지금 코드 그대로 멤버리포지토리만 바꿔치기 할 수 있음. 설정만 변경하면 되니깐.. 컴포넌트 스캔을 사용하면 모든 코드를 손대야함)

- @Autowired를 통한 DI는 helloController, memberService등과 같이 스프링이 관리하는 객체에서만 동작하며, 스프링 빈으로 동작하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.

 

사진, 코드 출처 - https://inf.run/hivx6

 

'스프링' 카테고리의 다른 글

스프링 입문 (7) - DB 접근 기술  (0) 2024.03.18
스프링 입문 (6) - 회원 관리 예제 : 웹 MVC 개발  (0) 2024.03.18
스프링 입문 (4) - 회원 관리 예제 - 백엔드 개발  (0) 2024.03.14
스프링 입문 (3) - 웹 개발 기초  (3) 2024.03.12
스프링 입문 (2) - View 환경 설정, 빌드해보기  (0) 2024.03.12
'스프링' 카테고리의 다른 글
  • 스프링 입문 (7) - DB 접근 기술
  • 스프링 입문 (6) - 회원 관리 예제 : 웹 MVC 개발
  • 스프링 입문 (4) - 회원 관리 예제 - 백엔드 개발
  • 스프링 입문 (3) - 웹 개발 기초
효재감자
효재감자
  • 효재감자
    효재감자의 우당탕탕 개발일지
    효재감자
  • 전체
    오늘
    어제
    • 분류 전체보기 (73)
      • 아무거나 (3)
      • 백준 (44)
      • 알고리즘 (4)
      • 자바 (1)
      • 리눅스(우분투) 및 클라우드 (2)
      • 스프링 (14)
        • 스프링 시큐리티 인 액션 (도서 정리) (5)
      • 플러터(Dart) (0)
  • 블로그 메뉴

    • 홈
    • Github
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
효재감자
스프링 입문 (5) - 스프링 빈과 의존관계
상단으로

티스토리툴바