쌓고 쌓다
컴포넌트 스캔과 자동 의존관계 설정 본문
화면을 붙이려면 컨트롤러와 뷰 템플릿이 필요하다.
그러려면 멤버 컨트롤러가 필요하다.
이 멤버 컨트롤러는 멤버 서비스를 통해 회원가입하고. 멤버 서비스를 통해서 데이터를 조회한다.
이 관계를 의존 관계가 있다고 표현한다. ( 멤버 컨트롤러가 멤버 서비스를 의존한다. )
MemberController
@Controller
public class MemberController {
}
@Controller 어노테이션을 붙였다. 기능은 없지만
스프링 컨테이너라는 통에 MemberController라는 객체를 생성하여 넣어두고. 스프링이 관리한다.
앞서 작성한 예제 코드를 보자.
컨트롤러 어노테이션을 보고 스프링이 HelloController 객체를 생성하여 들고 있었다.
helloController는 스프링 컨테이너에서 스프링 빈이 관리된다고 표현한다.
MemberService
@Controller
public class MemberController {
private final MemberService memberService = new MemberService();
}
MemberController는 MemberService를 필요로 한다.
new로 생성을 해놨지만 MemberService는 OrderController에서도 가져다 쓸 수 있고 다양한 곳에서 끌어다 쓸 수 있다.
그때마다 여러 개로 생성할 필요가 없다. 그냥 하나만 생성하여 공용으로 쓰면 된다.
=> 스프링 컨테이너에 등록을 하고 사용하자.
MemberService
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
MemberController는 스프링 컨테이너가 뜰 때 생성된다.
그때 생성자를 호출하는데 @Autowired가 되어있으면
스프링이 MemberService를 스프링 컨테이너에서 가져와 연결을 시켜준다.
이대로 실행시켜보자. 아래의 에러가 뜬다.
'hello.hellospring.service.MemberService' that could not be found.
@Autowired라고 되어있기에 스프링 컨테이너에서 MemberService를 가져온다고 했는데.
MemberService를 찾을 수 없다고 한다.
MemberService는 순수한 자바 클래스이다.
스프링이 애를 알 수 있는 방법이 없다. (어노테이션이 있다면 알아 봄)
MemberService 클래스에 @Service 어노테이션을 사용하자. ( 생성자에 마찬가지로 @Autowired )
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Service가 있어 스프링이 올라올 때 애를 스프링 컨테이너에 등록해 준다.
MemberService에 있는 MemberRepository 또한 등록을 해주자.
MemberRepository는 인터페이스이다. 구현체에다 @Repository를 해준다.
@Repository
public class MemoryMemberRepository implements MemberRepository{
...
}
최종적으로 아래의 그림이 완성된다.
빈만 등록한 것이 아닌 @Autowired를 통해 연관관계. 선을 연결시켜 준다.
memberController가 memberService를 쓸 수 있게 되고 memberService가 memberRepository를 쓸 수 있게 한다.
스프링 빈을 등록하는 방법 2가지
1. 컴포넌트 스캔과 자동 의존관계 설정
2. 자바 코드로 직접 스프링 빈 등록하기
현재 한 방법이 1번 방법이다.
컴포넌트 스캔?
MemberController에 사용한 @Controller 어노테이션 대신에 @Component라고 해도 된다.
서비스 어노테이션 안에 @Component가 있기 때문에 @Service라고 해도 된다.
컴포넌트 스캔 원리
- @Component 어노테이션이 있으면 스프링 빈으로 자동 등록된다.
- @Component를 포함하는 @Service, @Controller, @Repository도 스프링 빈으로 자동 등록된다.
@Service, @Component가 붙은 어노테이션들을 다 스프링 컨테이너에 등록하나?
demo라는 패키지를 만들고 @Service를 만들어도 될까?
=> 우리는 HelloSpringApplication을 실행한다. hello.hellospring 패키지 내에 있는 것만 컴포넌트 스캔을 한다.
그래서 Demo는 컴포넌트 스캔이 안되고 등록이 안된다.
참고
스프링은 스프링 컨테이너에 빈을 등록할 때. 기본으로 싱글톤으로 등록한다.
즉 하나만 등록하여 공유한다는 것이다.
orderService라는 게 있다고 하자. 이게 @Autowired로 memberRepository를 내놔하면
똑같은 인스턴스를 넣어준다.
(설정으로 싱글톤이 아니게 가능은 하다.)
'프로그래밍 > spring' 카테고리의 다른 글
회원 웹 기능 - 홈 화면 추가, 등록 (0) | 2023.05.16 |
---|---|
자바 코드로 직접 스프링 빈 등록하기 (0) | 2023.05.14 |
회원 서비스 테스트 ( 의존성 주입, 예외 테스트 코드 ) (0) | 2023.05.07 |
회원 서비스 클래스 작성 (0) | 2023.05.02 |
회원 리포지토리 테스트 케이스 작성 (0) | 2023.05.01 |