본문 바로가기
Spring/개념

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

by MINNI_ 2021. 8. 10.

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

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

  • 목표
    - 회원 컨트롤러가 회원 서비스와 회원 리포지토리를 사용할 수 있게 의존관계 준비
  • 컴포넌트 스캔 원리
    • @Component 애노테이션이 있으면 스프링 빈으로 자동 등록
    • @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔
    • @Component를 포함하는 애노테이션도 스프링 빈으로 자동 등록
      - @Controller
      - @Service
      - @Repository
      ⇒ @controller, @Service, @Repository → 스프링 빈에 자동 등록
  • @Autowired
    - 하나만 등록 가능한 스프링 컨테이너에 등록한 후 공유 (싱글톤)
    - 생성자에 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아 주입  ⇒ DI(의존성 주입)
    - 생성자가 1개만 있으면 @Autowired 생략 가능
    ⇒ 컨트롤러 - 서비스 - 리포지토리 연결 : 자동 의존관계 설정

 

서비스 스프링 빈 등록 X / 컨트롤러와 서비스 연결 X

 

 

서비스와 리포지터리 스프링 빈 등록 O / 컨트롤러-서비스-리포지터리 연결 ⇒ @Autowired

 

# 회원 컨트롤러 스프링 빈 등록
@Controller // 스프링 컨테이너에 MemberController 객체를 생성하여 넣어두며, 스프링이 관리
public class MemberController {

    /* 이러한 객체 생성은 다른 컨트롤러에서도 사용 가능하므로 좋은 방법x, 하나만 생성해서 공유하는 것이 좋음
    * => @Autowired : 하나만 등록이 가능한 스프링 컨테이너에 등록한 후 공유 */
//    private final MemberService memberService = new MemberService();

    private final MemberService memberService;

    @Autowired  // 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다 => DI(의존성주입)
    public MemberController(MemberService memberService) {  
    // 스프링이 스프링 컨테이너에 있는 멤버서비스를 가지고 와서 연결
        this.memberService = memberService;
    }
}
# 회원 서비스 스프링 빈 등록
@Service
public class MemberService {
   private final MemberRepository memberRepository;
   
   @Autowired
   public MemberService(MemberRepository memberRepository) {
   	this.memberRepository = memberRepository;
   }
}
# 회원 리포지토리 스프링 빈 등록
@Repository
public class MemoryMemberRepository implements MemberRepository {}

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

  • 과정
    - 위의 코드에서 회원 서비스와 리포지토리의 @Service, @Repository, @Autowired 애노테이션 제거 후 진행
    - 설정파일에 스프링 빈에 등록하라고 직접 설정
  • @Bean
    - 스프링 빈 등록
  • 생성자 주입 방법 3가지 : 1. 필드 주입   2. setter 주입   3. 생성자 주입
    - '생성자 주입' 권장
       → why? : 의존 관계가 실행 중에 동적으로 변하는 경우 거의 없는데, 생성자 주입은 처음에 세팅되는 시점에 생성되고 변경되지 않게 해줌
    - setter 주입은 public 이므로 누구나 접근 가능하며 변경가능해지므로 BAD
  • 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔(1.1)을 사용
    정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈(1.2)으로 등록
    → 정형화된 코드 : 일반적으로 작성하는 컨트롤러, 서비스, 리포지토리
    → 상황에 따라 변경 : 컴포넌트 스캔(1.1)은 여러 코드 변경해야 하지만, 직접 설정(1.2)는 설정파일만 변경하면 됨
주의
: @Autowired 를 통한 DI는 helloConroller , memberService 등과 같이 스프링이 관리하는 객체에서만 동작 O
: 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작 X

 

@Configuration
public class SpringConfig {

    @Bean   // 스프링 빈 등록
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

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

[ 출처 ]

 

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., 스프링 학습 첫 길잡이! 개발 공부의 길을 잃지 않도록 도와드립니다. 📣 확인해주세

www.inflearn.com

댓글