💡스프링 빈이란 뭘까?
MemberController.java 파일에는 @Controller
MemberService.java 파일에는 @Service
MemoryMemberRepository.java 파일에는 @Repository 어노테이션이 붙어 있다.
이 어노테이션에 들어가보면 @Component 어노테이션이 붙어있는 것을 확인할 수 있는데,
스프링은 @Component이 붙어있으면 각 클래스의 객체를 1개만 만들어 공유해서 사용하게 만든다.
이를 "싱글톤"이라고 부르며, 생성되는 객체를 "스프링 빈"으로 등록하여, IoC 컨테이너라는 공용 공간에서 관리한다.
객체가 여러 개 생성됐을 때의 문제를 막고, 효율적으로 관리할 수 있다.
개발자가 아니라 스프링이 객체들을 관리하기 때문에 IoC(Inversion of Control), 제어의 역전이라고 부른다.
IoC 컨테이너는 빈 생성, 의존성 주입(DI) 등의 역할을 개발자 대신 해줘서,
우리는 "어떤 것을 쓸래!" 라고 명시만 해주면 스프링이 자동으로 찾아서 코드로 전달받을 수 있다.
Component와 Bean
컴포넌트 등록가능한 범위⭐
💡 IoC 컨테이너를 통한 의존성 주입 방법
=> 어떤 것이, 왜 더 좋은 아키텍처인지 설명할 수 있게 공부하자!
[ 변경 전 MemberService.java 코드 ]
public class MemberService {
private final MemoryMemberRepository memoryMemberRepository;
static int total_id;
public MemberService(){
memoryMemberRepository = new MemoryMemberRepository();
}
[ DI 방법 1 - 필드 주입 ]
기존 생성자를 지우고 @Autowired 키워드를 붙여, 스프링 IoC 컨테이너에서 자동적으로 DI 되게 한다.
public class MemberService {
@Autowired //의존성 주입(DI) 방법1. 싱글톤으로 만들어진 MemoryMemberRepository를 이 변수에 주입하겠다!!!
private MemoryMemberRepository memoryMemberRepository;
static int total_id;
[ DI 방법 2 - 생성자 주입 ]
가장 많이 사용하는 방법 ⭐
생성자가 1개밖에 없을 때에는 Autowired 생략 가능하다.
장점
(1) final 키워드를 통해 상수로 사용함으로써 재생성을 막는다.⭐
(2) 다형성 구현 가능 == 역할과 구현 분리⭐
(3) 순환 참조 방지
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemoryMemberRepository memoryMemberRepository) {
this.memberRepository = memoryMemberRepository;
}
[ DI 방법 3 - @RequiredArgsConstructor 사용 ]
@RequiredArgsConstructor
@NonNull 어노테이션이 붙어 있는 필드 또는 초기화되지 않은 final 필드를 대상으로 생성자 생성한다.
@RequiredArgsConstructor
public class MemberService {
private final MemoryMemberRepository memoryMemberRepository;
방법 1과 3은 다형성의 장점이 없다.
인터페이스에 의존해야 하는데 구현체에 의존하고 있기 때문에 구현체를 바꾸는 순간 아래에 있는 코드에서 memoryMemberRepository 부분들을 모두 변경해주어야 한다.
반면에, 방법 2는 구현체에 의존하고 있기 때문에 구현체를 변경하고 싶다면
아래와 같이 세 부분만 변경해주면 된다 !!
private final MemberRepository memberRepository;
@Autowired
public MemberService(JpaMemberRepository jpaMemberRepository) {
this.memberRepository = jpaMemberRepository;
}
구현체를 자주 바꿔줘야 하는 클래스에는 방법 2를 주로 사용하고, 변경이 거의 없는 곳에는 방법 3을 주로 사용한다.
'Back-End 공부 > Spring' 카테고리의 다른 글
스프링 MVC - 기본 CRUD 만들기 프로젝트 (0) | 2024.01.17 |
---|---|
스프링 DB 연결 및 Transactional 처리 (0) | 2024.01.16 |
Controller, Service, Repository에 Dto 객체 추가해 실습하기 (1) | 2024.01.15 |
application.properties와 application.yml 환경 설정 변경 (1) | 2024.01.15 |
실습으로 CSR, SSR 작동원리 이해하기 CORS 에러 해결 (1) | 2024.01.14 |