TIL - 2022

[TIL 020] 스프링부트 - 자바 코드로 직접 스프링 빈 등록하기

바랄 희 2022. 3. 31. 02:07

김영한 강사님의 '스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술' 강의를 듣고 작성했습니다.

오류가 존재할 가능성이 다분합니다! 댓글로 알려주세요

 


컴포넌트 방식이 아닌 직접 스프링 빈을 등록하는 방법을 배웠다. 

 

package hello.hellospring;

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 MemoryMemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }
}

 

매우 간단한데 우선 SpringCofig 라는 클래스를 생성하고, 이에 Bean 을 생성할 수 있도록 객체를 생성한다.

MemberService 를 새로 선언하면 해당 로직이 호출되어 알아서 스프링 빈에 등록된다. 

 

MemberService 객체 내에 memberRepository() 라는 객체명이 들어간 이유는 생성자가 있어야 하기 때문이다. 

따라서 아래의 메서드가 먼저 호출되어 레포지토리 객체가 생성자로 취급되어 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 // dependency injection
    public MemberController(MemberService memberService){
        this.memberService = memberService;
    }


}

 

컨트롤러는 따로 Bean에 등록하지 않고 컴포넌트 방식으로 @Controller 어노테이션을 활용하여 빈에 등록되도록 한다. 

 

의존관계 설정에는 세가지 방법이 있는데, 위처럼 주입시키는 방식을 생성자 주입이라고 한다. 이를 위해서는 당연히 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 void setMemberService(MemberService memberService){
        this.memberService = memberService;
    }
}

위와 같은 의존관계 설정 방식은 setter 방식인데, 이는 무조건 Public 으로 메서드가 지정되어야 하므로 중간에 객체가 바꿔질 우려가 있어 선호되지 않는다. 

 

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 final MemberService memberService; --> 필드주입

}

위와 같은 방식은 필드주입 방식이라고 하며, 이는 선호되지 않는다. 왜냐하면 이렇게 될 경우 외부에서 변경이 불가능하기 때문이다. (테스트코드를 짤 시에 안좋다고 한다. 심지어 인텔리제에서는 오류가 난 것처럼 물결표시도 띄움)