[스프링 입문]스프링 빈과 의존관계

Hyeonjun·2022년 8월 15일
0

스프링입문

목록 보기
4/8
post-thumbnail
post-custom-banner

회원 컨트롤러가 회원 서비스와 회원 리포지토리를 사용할 수 있게 의존관계를 준비하자. 스프링스럽게.

MemberController

@Controller
public class MemberController {

    private final MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

스프링 빈을 등록하는 2가지 방법

  1. 컴포넌트 스캔과 자동 의존관계 설정
  2. 자바 코드로 직접 스프링 빈 등록하기

컴포넌트 스캔 원리

  • @Component annotation이 있으면 스프링 빈으로 자동 등록된다.
  • @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문.
  • @Controller, @Service, @Repository 모두 @Component를 포함한다.
  • 단, @SpringBootApplication과 같거나 하위에 있는 directory의 @Component만 가능하다.
    • @SpringBootApplication의 안에 @ComponentScan@Component를 검색함.

@Controller

  1. 스프링을 처음 실행할 때 Spring Container가 생성됨.
  2. @Controller가 붙어있는 클래스는 객체를 생성해서 Spring에 넣어두고 관리함.

“이를 Spring Container에서 Spring Bean이 관리된다” 라고 함.

@Autowired

  • 생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다. 이렇게 객체 의존 관계를 외부에서 넣어주는 것을 DI (Dependency Injection), 의존성 주입이라 한다.
  • 스프링이 각각의 연관된 객체를 찾기 위해서 @Controller, @Service, @Repository를 붙여 스프링이 해당 객체를 찾아 관리할 수 있도록 한다.
  • 주의! @Autowired를 통한 DI는 스프링이 관리하는 객체에서만 동작한다.
    스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
    컨테이너에 올라가야 사용 가능

Controller, Service, Repository의 생성

  1. Controller에 있는 @Controller Annotation을 확인하고, 해당 클래스의 객체를 생성자로 생성함.
  2. Controller 생성자의 Autowired 되어있는 Service로 이동
  3. Service에 있는 @Service Annotation을 확인하고, 해당 클래스의 객체를 생성자로 생성함.
  4. Service 생성자의 Autowired 되어있는 Repository를 @Repository Annotaoin을 확인하고 객체로 저장.

생성자에 @Autowired를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다. 생성자가 1개만 있으면 @Autowired 생략 가능.

스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다. (유일하게 하나만 등록해서 공유한다.)

따라서 같은 스프링 빈이면 모두 같은 인스턴스이다.

설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외한다면 대부분 싱글톤을 사용한다.

Component Scan을 사용하는 겨웅

  • 정형화된 Controller, Service, Repository와 같은 코드에 사용한다.

SpringConfig

@Configuration
public class SpringConfig {

    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }
}

@Bean

  • @Configuration이 있는 클래스에서 @Bean으로 스프링 빈에 추가할 수 있다.

과거에는 XML로 설정하기도 했지만, 지금은 잘 사용하지 않음

Dependency 주입 방법

의존관계가 실행중에 동적으로 변하는 경우가 (거의) 없으므로 생성자 주입을 권장.

  1. 필드 주입

    @Autowired
    private final MemberService memberService;
    • 중간에 변경할 수 있는 방법이 없어 좋지 않음.
  2. Setter 주입

    @Autowired
    public void setMemberService(MemberService memberService){
    	  this.memberService = memberService;
    }
    • set 메서드가 public하게 노출되어있음.
  3. 생성자 주입

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

Spring Bean으로 등록하는 경우

  • 정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야 하는 경우.
  • 설정(Config)를 통해 스프링 빈으로 등록한다.
profile
더 나은 성취
post-custom-banner

0개의 댓글