[Spring] 스프링 빈과 의존관계

일단 해볼게·2022년 11월 9일
0

Springboot

목록 보기
12/26

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

스프링이 뜰 때 컨트롤러 객체를 가지고 있다. → 스프링 컨테이너에서 스프링 빈이 관리된다.

스프링 컨테이너에 등록하면 컨테이너에서 받아서 쓰도록 코드를 변경해야한다.

컴포넌트 스캔과 자동 의존관계 설정

회원 컨트롤러에 의존관계 추가

  • 회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용할 수 있다.

main/java/hello.hellospring/controller/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 : 스프링이 제공하는 컨트롤러여서 자동으로 등록된다.

컴포넌트 스캔 원리

@Component 를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록된다.

  • @Controller
  • @Service
  • @Repository

→ @Controller, @Service, @Repository 코드 내부에 @Component가 있기 때문이다.

회원 서비스 스프링 빈 등록

main/java/hello.hellospring/service/MemberService

@Service
public class MemberService {

 private final MemberRepository memberRepository;

 @Autowired
 public MemberService(MemberRepository memberRepository) {
	 this.memberRepository = memberRepository;
 }
}

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

회원 리포지토리 스프링 빈 등록

main/java/hello.hellospring/repository/MemoryMemberRepository

@Repository
public class MemoryMemberRepository implements MemberRepository {}

참고 : 스프링 빈은 싱글톤으로 등록되는게 기본 설정이다. 싱글톤이 아니게 설정할 수 있지만 특이 케이스를 제외하면 대부분 싱글톤을 사용한다.

자바 코드로 직접 스프링 빈 등록하기

회원 서비스와 회원 리포지토리의 @Service, @Repository, @Autowired 애노테이션을 제거하고
진행한다. (@Controller는 그대로 유지한다.)

main/java/hello.hellospring/SpringConfig

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에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있다. 의존관계가 실행중에
동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.

main/java/hello.hellospring/controller/MemberController

@Controller // 스프링이 뜰 때 컨트롤러 객체를 가지고 있다. -> 스프링 컨테이너에서 스프링 빈이 관리된다.
public class MemberController {

    private final MemberService memberService;

    /*@Autowired // setter 주입 (위에서 final 제거해야한다.) -> public 설정해야해서 노출된다.
    public void setMemberService(MemberService memberService) {
        this.memberService = memberService;
    }*/

    //    @Autowired private MemberService memberService; // 필드 주입 -> 별로 안좋음, 중간에 변경할 수 없다.

    // 생성자 주입을 쓰는게 좋다.
    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}
  • 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다.
  • 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.
profile
시도하고 More Do하는 백엔드 개발자입니다.

0개의 댓글