순서
- 4. 스프링 빈과 의존관계
4.1 컴포넌트 스캔과 자동 의존관계 설정
스프링 빈을 등록하고, 의존관계 설정하기
멤버 컨트롤러가 회원서비스와 리포지토리를 사용할 수 있게 의존관계를 준비하자.
멤버 컨트롤러에 의존관계 추가
먼저 컨트롤러를 생성 해 보자
@Controller
public class MemberController {
}
MemberController 위에 @Controller 어노테이션을 작성하면, 스프링은 이 어노테이션을 보고 멤버컨트롤러 객체(스프링 빈)를 생성해서 스프링 컨테이너에 넣고, 스프링이 관리한다.
MemberController에 MemberService추가
@Controller
public class MemberController {
private final MemberService memberService = new MemberService();
}
이전에는 new 연산자를 이용해 MemberService를 새로 생성했었다. 이는 다른 컨트롤러들도 new로 생성하여 memberService를 가져다 쓸 수 있기 때문에, 많은 문제가 발생한다.
memberService는 기능이 많이 없어서, 스프링 빈으로 하나만 등록하고 공용으로 쓰는것이 낫다. ( 스프링 컨테이너에는 하나만 등록이 되기 때문 + @부가적인 효과 )
또한 우리는 스프링 프레임웤을 이용하기 때문에 스프링이 관리하고 스프링 컨테이너에서 받아서 쓰는것이 바람직 하기 때문이다.
위의 MemberController를 아래와 같이 변경해 보자
@Controller
public class MemberController {
//private final MemberService memberService = new MemberService();
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
우리는 @Controller 어노테이션을 작성을 하면, 스프링 컨테이너가 뜰 때 MemberController를 스프링 빈으로 생성하는 것을 알고 있다.
MemberController를 생성하는 과정에서 MemberService객체를 새로 생성하는 것이 아닌, MemberController의 생성자 호출 시 매개 변수로 memberService를 받아서 생성 하도록 변경을 하였다.
여기에 생성자에 @Autowired 를 추가하면, 생성자의 매개변수인 memberService를 스프링이 스프링 컨테이너에 있는것을 가져와서 넣어준다. ( 즉 생성 시점에 컨테이너에서 해당 빈을 찾아서 주입한다.) 생성자가 1개만 있으면 @Autowired는 생략할 수 있다.
다만 지금은 빨간줄이 있어 빌드시 오류가 뜰 것이다.
이유는 MemberService는 현재 어떠한 어노테이션이 없는 순수한 자바 클래스 이기때문에, 스프링은 이 놈이 스프링 빈인지 모른다.
따라서 이 MemberService를 빈으로 등록해주면 된다.
방법은 MemberService 클래스에 @Service를 작성하면 끝이다.(매우 간단! 스프링이 @Service 어노테이션을 보고 컨테이너에 등록을 해 주어서, MemberController의 생성자에서 쓸 수 있게 된다.)
(마찬가지로 MemberService의 생성자도 memberRepository를 매개변수로 받기 때문에, 구현체인 MemoryMemberRepository클래스에 @Repository 를 추가하여 스프링 빈으로 등록하면, MemberService가 생성될때 스프링 컨테이너에 등록된MemoryMemberRepository 스프링 빈을 가져와 쓴다. 이것이 바로 Dependency Injection - 의존관계를 외부에서 주입 )
- 주의: @Autowired 를 통한 DI는 helloConroller , memberService 등과 같이 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
이렇게 각자 스프링 컨테이너에 있는것을 필요에 따라 가져다 연결하여 쓰면 된다.
( Controller, Service , Repository - 정형화된 패턴이다 )
상기와 같은 방법으로 스프링 빈을 등록하는 방법이 컴포넌트 스캔과 자동 의존관계 설정 방식이다.
(왜 컴포넌트 스캔이냐면, @Service, @Repository 로 작성한 클래스들도 들여다 보면 @Component가 붙어 있다. 컴포넌트와 관련된 어노테이션을 가진 클래스들은 스프링에서 객체를 생성해서 스프링 컨테이너에 등록해준다. 등록된 컴포넌트들을 스캔해서 DI 를 하기 때문.)
참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다.메모리 절약하고 좋다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
'Java | Spring > Spring 입문' 카테고리의 다른 글
[스프링 입문] 5. 회원 관리 예제 - 웹 MVC 개발 (0) | 2022.03.14 |
---|---|
[스프링 입문] 4.2 자바 코드로 직접 스프링 빈 등록하기 (0) | 2022.03.13 |
[스프링 입문] 3.5 회원 서비스 테스트 (2) | 2022.02.27 |
[스프링 입문] 3.4 회원 서비스 개발 (0) | 2021.10.26 |
[스프링 입문] 3.3 회원 리포지토리 테스트 케이스 작성 (0) | 2021.10.05 |
댓글