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

Dodam·2023년 7월 28일
0

[Spring]

목록 보기
4/9
post-thumbnail

스프링 빈을 등록하는 방법

  1. 컴포넌트 스캔과 자동 의존관계 설정
  2. 자바 코드로 직접 스프링 빈에 등록하는 방법

스프링 컨테이너에 빈을 등록하는 이유

: 객체를 다루는 일반적인 방법은 개발자가 프로그램 로직 상 필요한 객체를 그때그때 직접 생성하고 필요한 메서드를 호출하는 것이다.

자바의 경우, new 키워드를 통해 필요한 곳에 인스턴스를 생성하는 로직을 넣는다.

하지만 스프링에서는 클래스들의 인스턴스(객체)를 일일이 개발자가 다루는 것이 아니라 스프링에게 관리를 맡긴다. 이것이 스프링의 주요 특징 중 하나인 IoC(Inversion of Control)이다.

IoC는 제어의 역전이라고 하며, 쉽게 말해 제어의 흐름을 바꾸는 것이다.
필요한 객체를 개발자가 직접 생성하는 것이 아니라 스프링이 생성해 놓은 객체를 가져와서 쓰게 된다.

IoC (Inversion of Controler): 제어의 역전, 객체를 개발자가 아닌 외부(스프링 컨테이너)에서 생성, 관리

이 때 스프링이 객체들을 미리 생성해 관리하는 공간을 스프링 컨테이너라고 하며, 이렇게 스프링에 의하여 생성되고 관리되는 자바 객체를 스프링에서는 빈(Bean)이라고 한다.

스프링 컨테이너 (Spring Container): 스프링에서 자바 객체들을 관리하는 공간

스프링 빈 (Spring Bean): 스프링에 의하여 생성되고 관리되는 자바 객체


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

회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용할 수 있도록 의존관계를 준비한다.

회원 컨트롤러에 의존관계 추가

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;
 	}
}
  • 생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다.
    이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI (Dependency Injection), 의존성 주입이라고 한다.

컴포넌트 스캔 원리

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

회원 서비스 스프링 빈 등록

@Service
public class MemberService {

	private final MemberRepository memberRepository;

	@Autowired
	public MemberService(MemberRepository memberRepository) {
		this.memberRepository = memberRepository;
 	}
}
  • 생성자에 @Autowired를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다.
  • 생성자가 1개만 있으면 @Autowired는 생략 가능

회원 리포지토리 스프링 빈 등록

@Repository
public class MemoryMemberRepository implements MemberRepository {}
memberService와 memberRepository가 스프링 컨테이너에 스프링 빈으로 등록된다.

스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다.
(유일하게 하나만 등록해서 공유한다.)
따라서 같은 스프링 빈이면 모두 같은 인스턴스이다.


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

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();
 	}
}
  • DI에는 필드 주입, setter 주입, 생성자 주입 3가지 방법이 있다.
  • 의존 관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 보통 생성자 주입을 권장
  • 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.
  • @Autowired를 통한 DI는 helloController, memberService 등과 같이 스프링이 관리하는 객체에서만 동작한다.
profile
Good things take time

0개의 댓글