티스토리 뷰
자동으로 의존관계를 설정할 수 있지만, 직접 스프링 빈으로 등록하는 방법이 있다.
파일을 한개 만들고 아래와 같이 코드를 작성한다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService();
}
}
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
이렇게 작성하면 스프링이 Configuration을 읽고 이 코드를 스프링 빈에 등록하라는 뜻으로 인식하고 작성해둔 로직을 호출시켜 컨테이너에 생성을 해준다. 스프링 빈에 등록하라고 알려주는 놈이 바로 @Bean 어노테이션이다.
하지만 오류가 뜬다. 위에 Service클래스를 보면 생성자에 Repository가 들어가있는 것을 볼 수 있다.
그래서 스프링 빈으로 등록해줄 때 Repository를 넣어줘야 한다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
이러면 스프링이 뜰 때 Service와 Repository를 등록하고 스프링 빈에 등록되어 있는 Repository를 Service에 넣어준다는 의미가 된다.
컴퍼넌트 스캔과 직접 스프링 빈 등록을 다 사용해봤으면 여기서 의문이 드는게 정상이다.
당연히 컴퍼넌트 스캔 방식이 훨씬 간편한데 왜 둘다 알아야 할까 ?
그 이유는 각각의 장단점을 지니고 있기 때문이다.
DI에는 주입방식이 총 3가지가 있다.
- 필드 주입
- setter 주입
- 생성자 주입
위에서 작성한 코드는 생성자를 통해서 MemberRepository가 MemberService에 주입한 생성자주입을 사용하였다.
필드주입은 말 그대로 필드위에 @Autowired를 쓰면 된다.
public class MemberController {
@Autowired
private MemberService memberService;
}
필드주입 방식은 선호하지 않는다. 내가 원하는 코드로 바꾸기가 불가능하기 때문이다.
setter주입은 setter메소드 위에다 @AutoWired를 붙여주면 끝이다.
@Autowired
public void setMemberService(MemberService memberService) {
this.memberService = memberService;
}
setter주입은 한번 세팅하고 나선 건들지 않지만 무조건 public으로 열려있어야 한다. 그러면 쉽게 노출이 되어 함부로 바꾸다가 잘못 바꾸면 문제가 발생할 수 있다.
실무에서는 주로 정형화된 컨트롤러, 서비스, 레포지토리 같은 코드는 컴퍼넌트 스캔을 사용한다.
정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 직접 스프링 빈으로 등록한다.
정형화 되지 않거나, 상황에 따라 구현 클래스를 변경할 때가 언제일까 ?
만약 회원서비스를 구현하기 전에 아직 데이터 저장소가 선정되지 않았다는 가상의 시나리오를 베이스에 두고
구현하고 있다고 가정해보자. 그러면 Repository를 인터페이스로 설정을 하고 구현체로 MemoryRepository를 쓰고 있다가 나중에 다른 Repository로 바꿔야하는 상황이 온다. 이 때 직접 스프링 빈으로 등록하는 방법을 사용한다.
직접 스프링 빈으로 등록하는 방법을 사용하면 기존에 운영중이던 코드를 하나도 손대지 않고 바꿀 수 있다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new DbMemberRepository();
}
}
직접 등록하는 방식은 같지만 Repository만 다른 Repository로 바뀐걸 볼 수있다.
(MemoryMemberR → DbMemberRepository)
여러 코드를 바꿔야 하는 컴퍼넌트 스캔보다 편리하다는 점이 직접등록의 장점이라 볼 수 있다.
'SpringBoot' 카테고리의 다른 글
자주 사용하는 Thymeleaf 문법 (0) | 2022.07.08 |
---|---|
게시판 화면을 위한 Thymeleaf 적용과 데이터 출력하기 (0) | 2022.07.08 |
setter를 지양하고 Builder 패턴을 사용하자 (0) | 2022.05.05 |
컴퍼넌트 스캔으로 자동 의존관계 설정 (0) | 2022.04.09 |
Java Bean & Spring Bean (0) | 2022.04.04 |
- Total
- Today
- Yesterday