✏️ 스프링 빈(Bean)
빈(Bean)이란 스프링 컨테이너에 의해 재사용 가능한 소프트웨어 컴포넌트이다.
즉 스프링 컨테이너에 의하여 생성되고 관리하는 자바 객체를 뜻하며, 하나 이상의 빈(Bean)을 관리한다.
- Spring Framework에서는
ApplicationContext.getBean()
등의 메서드로 직접 자바 객체를 가져올 수 있다. - IntelliJ 에서는 Bean 인 경우 아래 사진처럼 왼쪽에 아이콘으로 표시된다.
스프링에서 스프링 빈을 인지하는 2가지 방법
- 스프링은 약속되어 있는
어노테이션이 붙어있는 클래스
를 자동으로 인지한다.@Component
어노테이션이 붙어있다면, 스프링이 자동으로 인지할 수 있게 된다.
→ 컴포넌트 스캔을 이용한 방식 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 |