스프링 컨테이너에 등록되어 스프링이 관리하는 자바 객체.
스프링은 한 개 이상의 빈을 관리한다.
스프링 빈은 객체의 생성, 의존성 주입, 생명주기 관리 등을 자동화하여 개발자의 부담을 줄이고, 효율적인 애플리케이션 구성을 가능하게 한다.
객체 간의 의존 관계를 구성할 때, 스프링 컨테이너는 필요한 빈을 찾아 객체에 주입하고, 이를 통해 객체 간의 의존성을 자동으로 설정해준다.
회원가입과 회원 조회 기능을 수행하는 MemberController는 MemberService에 의존한다. 이를 위해 두 클래스 간의 의존관계를 설정해야 하는데, 설정 방법에는 컴포넌트 스캔을 통한 자동 빈 등록과 자바 코드로 직접 스프링 빈을 등록하는 방법이 있다.
두 방법 중 컴포넌트 스캔을 활용한 자동 등록 방식부터 알아보자.
package hello.hello_spring.controller;
import hello.hello_spring.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;
}
}
controller 패키지 하위에 MemberController 클래스를 만들고 클래스에 @Controller 어노테이션을 붙이면, 스프링이 이 클래스를 컴포넌트 스캔을 통해 자동으로 인식하고, 스프링 컨테이너에 빈으로 등록해 관리하게 된다.
이후 스프링은 @Autowired 가 붙은 생성자를 보고, 스프링 컨테이너에 등록되어 있는 MemberService 타입의 빈을 자동으로 주입한다. 이를 통해 new 키워드로 직접 객체를 생성하지 않고도 MemberService를 사용할 수 있게 된다.
이처럼 스프링 컨테이너가 객체의 생성과 주입을 관리하는 것이 바로 의존성 주입(Dependency Injection, DI)이다.
어노테이션을 추가해야 스프링이 각각의 클래스를 인식하고 빈으로 등록할 수 있다. 또한 컨트롤러 클래스의 생성자에 @Autowired 어노테이션을 붙여 DI를 적용한 것처럼, 두 클래스의 생성자에도 똑같이 적용한다.
여기까지 따라왔다면, 컨트롤러, 서비스, 리포지토리가 위 그림처럼 연결된다.
컴포넌트 스캔 방식은 컴포넌트와 관련된 @Controller, @Service, @Repository 어노테이션들을 인식해 각각의 객체를 생성한 후 스프링 빈에 등록해 관리하고, @Autowired 어노테이션을 통해 객체들 간의 연관 관계를 설정하는 방식이다.
한 가지 유의해야 할 것은, 컴포넌트 스캔 방식에서 스프링이 모든 범위의 파일들에 대해 적용되는 것이 아니라, 메인 클래스(여기선 HelloSpringApplication)가 포함된 패키지 내 파일들을 대상으로 적용된다는 것이다.