MemberController class를만든다.
package hello.hellospring.controller;
import org.springframework.stereotype.Controller;
@Controller
public class MemberController {
}
위의 코드처럼만 작성을 하더라도 스프링 컨테이너라는 통이 생기는데 controller annotation이 있으면 컨트롤러 객체를 생성해서 스프링에 넣어두고 관리를 한다.
-> spring container에서 spring bean이 관리된다라고 표현한다!
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService=memberService;
}
}
Memberservice는 별 기능이 없기 때문에 여러 객체를 생성할 필요가 없다. 그렇기 때문에 스프링 컨테이너에 등록을 하고 쓴다.
그래서 위의 생성자처럼 작성한다.
@Autowired는 spring 컨테이너에서 memberservice를 가져오는 역할을 한다.
하지만 위 코드를 실행시키면
MemberService를 찾을 수 없다고 뜬다.
왜냐?? MemberService는 단순 java이기에 spring이 알 껀덕지가 없다.
그렇기 때문에 MemberService class 파일에 @Service를 추가해준다.
@Service는 스프링 컨테이너에 service라고 등록을 시켜주는 것이다.
그리고 MemoryMemberRepository로 가서 @Repository를 붙여준다.
(전에 게시글과 이어지는 글입니다.)
controller와 service를 연결을 시켜주어야한다.
그것이 바로 @Autowired 이것이 바로 DI이다.
또한 컴포넌트 스캔방식과 자동 의존관계 설정이다.
컴포넌트 스캔과 자동 의존관계 설정
- @Component : 에노테이션이 있으면 스프링 빈으로 자동 등록된다.
- @Controller : 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
@Component를 포함하는 다음 에노테이션도 스프링 빈으로 자동 등록된다.
- @Controller
- @Service
- @Repository
참고 : 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다.(유일하게 하나만 등록해서 공유한다.) 따라서 같은 스프링 빈이면 모두 같은 인스턴스이다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
main -> java -> hello.hellospring -> SpringConfig class 생성
package hello.hellospring;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Bean //내가 빈을 등록할 것이다.
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
< MemberController >
package hello.hellospring.controller;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService)
{
this.memberService=memberService;
}
}
Controller는 어쩔 수 없다. spring이 어짜피 관리하는 거기 때문에
@Controller로 둔다. 그러면 아래의 그림이 완성된다.
< DI의 3가지 종류 >
1. 생성자 주입 (권장!)
2. 필드 주입 (비추!)
3. setter 주입