[Spring 입문하기] Section 04. 스프링 빈과 의존관계

2024. 1. 25. 13:15·Programming/Spring
728x90
반응형

✏️ 스프링 빈(Bean)

빈(Bean)이란 스프링 컨테이너에 의해 재사용 가능한 소프트웨어 컴포넌트이다.
즉 스프링 컨테이너에 의하여 생성되고 관리하는 자바 객체를 뜻하며, 하나 이상의 빈(Bean)을 관리한다.

  • Spring Framework에서는 ApplicationContext.getBean() 등의 메서드로 직접 자바 객체를 가져올 수 있다.
  • IntelliJ 에서는 Bean 인 경우 아래 사진처럼 왼쪽에 아이콘으로 표시된다.

스프링에서 스프링 빈을 인지하는 2가지 방법

  1. 스프링은 약속되어 있는 어노테이션이 붙어있는 클래스를 자동으로 인지한다. @Component어노테이션이 붙어있다면, 스프링이 자동으로 인지할 수 있게 된다.
    → 컴포넌트 스캔을 이용한 방식
  2. Bean Configuration File에 직접 Bean을 등록하면 스프링이 인지할 수 있게 된다.
    → 자바 코드로 직접 스프링 빈으로 등록하는 방식

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

컴포넌트 스캔

@Component어노테이션이 있으면 스프링 빈으로 자동 등록된다.

  • @Component를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록된다.
    • @Controller
    • @Service
    • @Repository

Spring 프로젝트에서 (프로젝트명)Application class를 @SpringBootApplication 어노테이션이 붙어있음을 확인할 수 있다.

이를 정의한 곳을 확인해보면

@ComponentScan 어노테이션이 붙어 있음을 확인할 수 있다.

이 어노테이션은 어느 지점부터 컴포넌트를 찾아보라고 알려주는 것이다. 즉, 이 어노테이션을 사용한 @SpringBootApplication 어노테이션이 PlaylistPackApplication 클래스에 붙어있으므로 이 클래스의 하위 모든 패키지를 훑어보면서 @Component 어노테이션을 활용한 모든 클래스를 찾고, Bean으로 등록한다.


DI (Dependency Injection), 의존성 주입

객체 의존 관계를 외부에서 넣어주는 것

  • 의존성 주입은 반드시 Bean으로 등록된 객체들 끼리만 가능하다. ( 컨테이너에 Bean을 등록되어 있지 않은 객체는 의존성 주입을 해주지 않음)
  • 생성자에 @Autowired 를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다.

의존성 주입 방법

  • 필드주입

    • 코드가 간결하다

    • 하지만, 클래스 외부에서 접근이 불가능해 테스트하기 어렵다는 단점이 있다.

    • 프레임워크에 의존적이고 객체지향적으로 좋지 않다.

      @Service
      public class StationFieldService {
        @Autowired
        private StationRepository stationRepository;
      
        public String sayHi() {
            return stationRepository.sayHi();
        }
      }
  • setter 주입

    • 변경 가능성이 있는 의존 관계에 사용한다.

    • 생성자 호출 이후에 필드 변수에 변경이 일어나야 하므로, stationRepository 변수에 final 제어자를 붙일 수 없다.

      @Service
      public class StationSetterService {
        private StationRepository stationRepository;
      
        @Autowired
        public void setStationRepository(StationRepository stationRepository) {
            this.stationRepository = stationRepository;
        }
      
        public String sayHi() {
            return stationRepository.sayHi();
        }
      }
  • 생성자 주입

    • 생성자를 호출할 때 딱 1번만 호출되기 때문에 stationRepository 변수를 final로 관리할 수 있다.

    • 생성자 주입 사용 시, 생성자가 1개인 경우 @Autowired를 생략할 수 있다.

      @Service
      public class StationConstructorService {
        private final StationRepository stationRepository;
      
        @Autowired
        public StationConstructorService(final StationRepository stationRepository) {
            this.stationRepository = stationRepository;
        }
      
        public String sayHi() {
            return stationRepository.sayHi();
        }
      }

순환참조를 방지할 수 있고 final로 선언하여 불변성을 보장할 수 있으며 테스트에 용이한 생성자 주입을 권장한다


회원 컨트롤러에 의존관계 주입 예제 코드

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;
    }

}

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


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

  • @Configuration을 이용하면 Spring Project 에서의 Configuration 역할을 하는 Class를 지정할 수 있다.
  • Bean 으로 등록하고자 하는 Class에 @Bean 어노테이션을 사용해주면 간단하게 Bean을 등록할 수 있다.

자바 코드로 스프링 빈 등록 예제 코드

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();
    }
}
반응형

'Programming > Spring' 카테고리의 다른 글

[Spring 입문하기] Section 07. AOP  (0) 2024.01.25
[Spring 입문하기] Section 06. 스프링 DB 접근 기술  (0) 2024.01.25
[Spring 입문하기] Section 03. 회원 관리 예제 - 백엔드 개발  (0) 2023.07.13
[Spring 입문하기] Section 02. 스프링 웹 개발 기초  (0) 2023.07.11
[Spring 입문하기] Section 01. 프로젝트 환경설정  (0) 2023.07.11
'Programming/Spring' 카테고리의 다른 글
  • [Spring 입문하기] Section 07. AOP
  • [Spring 입문하기] Section 06. 스프링 DB 접근 기술
  • [Spring 입문하기] Section 03. 회원 관리 예제 - 백엔드 개발
  • [Spring 입문하기] Section 02. 스프링 웹 개발 기초
제가안난데여♪(´ε`*)
제가안난데여♪(´ε`*)
기억의 유한함을 기록의 무한함으로 ✍️ 예비 개발자가 꿈꾸는 공간 여기는 안나의 개발 블로그 💻
  • 제가안난데여♪(´ε`*)
    안나의 전두엽 어딘가 🧠
    제가안난데여♪(´ε`*)
    기억의 유한함을 기록의 무한함으로 ✍️ 예비 개발자가 꿈꾸는 공간 여기는 안나의 개발 블로그 💻
  • 전체
    오늘
    어제
    • 분류 전체보기 (128)
      • 간단하게 한스푼🥄 (1)
      • Programming (56)
        • Spring (16)
        • Vue.js (6)
        • Deep Learning (3)
        • DataBase (5)
        • React (26)
      • DevOps (21)
        • Docker (12)
        • Linux (4)
      • Algorithm (46)
        • 알고리즘 정리 (5)
        • 자료구조 (0)
        • PS - 백준 (28)
        • 99클럽 코테 스터디 (13)
      • Project (0)
        • CampFire (0)
      • 안나의 취뽀일기 (˵ •̀ ᴗ - ˵ ) ✧ (4)
        • SSAFY_9기 (2)
        • SW 부트캠프 (2)
  • 잔디 달력

    «   2025/06   »
    일 월 화 수 목 금 토
    1 2 3 4 5 6 7
    8 9 10 11 12 13 14
    15 16 17 18 19 20 21
    22 23 24 25 26 27 28
    29 30
  • 인기 글

  • 태그

    topology sort
    자바 스택
    springboot
    항해99
    linux
    Vue
    99클럽
    front-end
    자바
    알고리즘
    java stack
    백준 java
    java 백준
    Spring
    greedy
    백준 구현문제
    java
    도커
    docker
    Vue.js 입문하기
    리액트 상태
    til
    개발자 취업
    Vue.js
    stack
    김영한
    코딩테스트 준비
    백준
    도커컨테이너
    React
  • 06-11 11:44
    반응형
  • hELLO· Designed By정상우.v4.10.3
제가안난데여♪(´ε`*)
[Spring 입문하기] Section 04. 스프링 빈과 의존관계
상단으로

티스토리툴바