-인프런에서 김영한강사님의 스프링 강의를 들으며 정리하는 노트-
스프링 빈을 등록하는 방법
- 컴포넌트 스캔과 자동 의존관계 설정
- 자바 코드로 직접 스프링 빈 등록
앞으로 설명에 쓸 폴더구조는 다음과 같다
@Controller, @Service, @Repository, @Autowired 어노테이션을 통해!
package com.hello.hellospring.controller;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
package com.hello.hellospring.service;
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
package com.hello.hellospring.repository;
@Repository
public class MemoryMemberRepository implements MemberRepository {}
생성자에 @Autowired 가 있으면 객체 생성 시점에서 스프링이 연결된 객체를 스프링 컨테이너에서 찾아서 넣어준다.
이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI(Dependency Injection), 의존성 주입이라 한다.
@Component 어노테이션이 있으면 스프링 컨테이너에 스프링 빈으로 자동 등록되는데,
@Controller, @Service, @Repository 가 @Component 어노테이션을 포함한다.
다음과 같이 스프링 빈 등록이 되었다!
여기서 질문!
@Contorller와 같은 어노테이션을 아무데나 붙여도 되나? NO !!!!!
기본적으로 HelloSpringApplication 을 실행시키기 때문에 그 패키지(com.hello.hellospring)를 포함하는 하위들을 뒤져서 스프링 빈으로 등록. 하지만 이 패키지와 동일하거나 하위 패키지가 아닌 경우 스프링 빈으로 컴포넌트 스캔으로 안한다.
@Configuration, @Bean
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() { //이것을 호출해서 스프링 빈에 등록해줌
return new MemberService(memberRepository()); //스프링 빈에 등록되어 있는 MemberRepository를 MemberService에 넣어줌
}
@Bean
public MemberRepository memberRepository() {
//구현체를 new해주기 (interface는 new안됨)
return new MemoryMemberRepository();
}
}
이 방법을 사용할 때는
서비스와 리포지토리의 @Service, @Repository, @Autowired 어노테이션 제거 후 진행
실무에서는 주로 1번 방식을 사용한다고 한다.
2번 방식은 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 할 때 사용한다.
상황에 따라 구현 클래스를 변경해야 하는게 어떤 것일까?
현재 강의 상황으로 말하자면,
지금 데이터저장소를 정하지 않았고 메모리를 통해 관리중인데, 2번 방법을 사용하게 되면 나중에 디비를 정했을 때 다른 코드는 하나도 건들이지 않고 memberRepository함수 리턴하는 부분만 바꿔주면 된다는 편리함이 있다.
추후 할일.
왜 스프링 빈을 사용하는가? 내용추가하기.
(지금 생각으로는왜'스프링 빈을 등록해야 모든 곳에서 같은 컨트롤러, 서비스, 리포지토리 객체를 사용하니까' 로 알고있음)