Back-End/Spring

[SpringBoot][스프링 입문] - 4.2 자바 코드로 직접 스프링 빈 등록하기

얄루몬 2021. 12. 25. 08:20

1. 직접 등록에 앞서서 Annotation 제거하기

진행에 앞서서 멤버 서비스에서 컴포넌트 스캔으로 연결해주었던 관계를 다 지우고 시작해야 한다.

그러면 위의 사진과 같이 Bean에 등록되어 있지 않는다고 메시지가 뜬다.

 

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

package hello.hellospring.service;

import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
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();
    }

}

위의 코드가 아래의 그림처럼 전부 구현된 코드이다. 

 

📌 Controller의 경우엔 어차피 Spring Bean이 관리하기 때문에 컴포넌트 스캔을 사용해야 한다. 또한 컴포넌트 스캔이기 때문에 Autowired를 사용해야 한다.

 

 

3. 자바 코드로 스프링 빈 설정을 하는 이유 

  • 의존관계가 실행중(Runtime 중간에 변경하는 경우를 의미한다.)에 동적으로 변하는 경우는 거의 없기 때문에 생성자 주입을 권장한다.
  • 메모리 리포지토리를 다른 리포지토리로 변경할 예정이기 때문에 컴포넌트 스캔 방식 대신 자바 코드로 스프링 빈 설정을 진행한다.
  • 정형화되지 않거나 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다. 
    • 상황에 따라 구현 클래스 변경 - MemberRepository를 지금은 가상의 MemoryMemberRepository로 구현해 놓은 상태지만 수업을 더 진행하고서는 다른 클래스로 변경하기 위해서 자바 코드로 스프링 빈을 설정한 것이다.

<필드 주입>

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 {

    // 필드주입
    @Autowired private MemberService memberService;

}

필드 주입을 하는 것은 별로 좋지 않다.

왜냐하면 스프링 뜰때만 주입하고 중간에 코드를 바꿀 수가 없기 때문이다.(치명적 단점)

 

<생성자 주입>

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;
    }
}

가장 선호하는 방식이고 처음에 조립할 때 넣고 중간의 변경을 불가하게 하는것.

 

<setter 주입>

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 MemberService memberService;

    @Autowired //새터 주입
    public void setMemberService(MemberService memberService){
        this.memberService = memberService;
    }
}

중간에 바뀔 일이 없는데 public하기 때문에 중간에 바뀌게 됐을 때 문제가 많이 발생한다. 

아무 개발자나 호출할 수 있게 해놓는 것이기 때문에 문제가 난다.

 

4. 컴포넌트 스캔을 사용해서 빈 설정을 하는 경우

  • 정형화된 설계는 컴포넌트 스캔을 사용해서 빈을 설정한다. 
    • 변경이 적은 경우에 사용한다는 의미이다.