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;
}
}
MemberService는 순수한 클래스다 스프링이 얘를 알 방법이 없다. 그러면 @Service를 넣어주면된다 그리고 리포지토리 구현체로 가서 @Repository를 해준다. 컨트롤러랑 서비스랑 연결을 시켜줘야됨 @Autowired 이게바로 의존관계를 주입시켜 주는것 memorymemberrepository가 구현체로 있는 것을 딱 서비스에 주입을 해줌
스프링 빈을 등록하는 2가지 방법 컴포넌트 스캔과 자동 의존관계 설정
아무 때나 @Component가 있어도 될까? 이거는 기본은 안된다. 우리가 실행시키는 HelloSpringApplication의 패키지를 포함해서 하위들은 자동으로 스프링이 뒤져서 빈에 등록됨
싱클톤 : 유일하게 하나만 등록함 hellocontroller 은 hellocontroller 하나만 memberservice는 memberservice하나만 등록을 하고 공유한다.
@Service // 스프링이 실행될 때, 스프링 컨테이너가 서비스 객체를 만들고 스프링 빈으로 등록한다.
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Repository // 스프링이 실행될 되면 스프링 컨테이너가 서비스 객체를 만들고 스프링 빈으로 등록한다.
public class MemoryMemberRepository implements MemberRepository {}
참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만
등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수
있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다
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();
}
}
DI에는 3가지 방법이 있는데 하나가 생성자 주입 두번째 필드 주입(별로 안좋음) 마지막으로 SETTER 주입이 있다 SETTER를 만들어주고 @Autowired 달아줌 이거에 단점은 누군가가 멤버 컨트롤을 호출하면 퍼블릭으로 노출이되어야 함 요즘 권장하는 것은 생성자 주입
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다.
정형화된 컨트롤러는 일반적으로 우리가 작성하는 컨트롤러 서비스 리포지토리
그리고 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다 -> 중요 상황에 따라 구현 클래스를 변경해야 한다!