Spring boot @Bean

강정우·2022년 10월 25일
0

spring

목록 보기
18/25
post-thumbnail

스프링 빈과 의존관계

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

@Bean

  • @Bean을 왜 쓰냐? 마치 datapool 처럼 객체를 계속 만들어서 memory에 과부하가 가지 않도록 하고 미리 spring container에 등록한 객체를 빌려서 사용하도록 유도하여 메모리 소모량을 줄일 수 있기 때문이다.

  • 생성자에 @Autowired 가 있으면 스프링이 관련된 객체를 스프이 Container에서 찾아서 넣어준다.

    이렇게 객체 의존 관계를 외부에서 넣어주는 것. 이를 DI(dependency injection)라고 한다.

Singleton

  • Spring은 Spring Container에 @Bean을 등록할 때 기본적으로 싱글톤(하나만 등록해서 공유)으로 등록한다.
    따라서 같은 @Bean이면 모두 같은 instance이다.

  • 설정으로 싱글톤이 아니게 설정할 수 있지만 특별한 경우아니고선 대부분 싱클톤으로 등록한다.

@Component

  • 그러다면 Spring이 이 class들을 인식하기위해 어떠한 annotation들을 부여해야할까?
    통상적으로 1. @Controller(외부 요청 받고) 2. @Service(비지니스 로직을 만들고) 3. @Repository(data를 저장하고)

@Autowired

  • 위 사진을 보면 Controller와 Service를 무엇으로 연결해주는가? 바로 @Autowired로 이어준다. Spring프로젝트가 딱 뜰때 component scan을 하고 이때 어?보니까 저기 memberRepository가 필요하네?! 하고 딱 저부분을 가져와서 넣어준다. 이것이 바로 의존관계 주입 즉 DI 되시겠다.
    요 일련의 과정이 완료가 되면 위의 Spring Bean 등록 이미지 처럼 3개가 비로소 이어진 형태가 된다.

1. 컴포넌드 스캔과 자동 의존 관계 설정

  • @Component 요게 있으면 스프링 빈으로 자동 등록을 해준다.
  • @Component 하위에 있는 것이 @Controller,@Service,@Repository가 있고
  • @Controller가 스프링 빈으로 자동 등록된 이유도 Component Scan이 가능하기 때문이다.

    생성자에 @Autowired를 사용하면 객체 생성 시점에 Spring Container에서 해당 Bean을 찾아서 주입하는데 이때 싱성자가 1개밖에 없다면 생략가능!

컴포넌트 스캔 범위

  • 그렇다면 어디어디를 spring project가 뒤지는가? 바로 ProjectNameApplication 이 파일이 있는 package 내에 있는 모든 파일 되시겠다.

  • 하지만 억지로 외부 클래스도 컴포넌트로 등록하겠다고 한다면 @componentscan 이라는 어노테이션을 추가하면 되긴 한다.

2. 스프링 빈을 자바 코드로 직접 등록(@Configuration, @Bean)

@Configuration
public class SpringConfig {
	// spring container에 등록하고 싶은 class를 생성자 함수로 작성
    
    @Bean
    public MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }

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

}
  • 이렇게 SpringConfig 라는 클래스 파일을 하나 만들고 그 안에 @Bean annotation을 사용하여 클래스들 을 등록해도 좋다.

  • 이때 가능한 @Component들은 @Service, @Repository가 있고 @Controller는 이런식으로 spring config로는 등록이 불가하다.

@Component와 @Bean의 장단점

  • DI에는 필드, setter, 생성자 주입 이렇게 3가지의 방법이 있다. 의존관계가 실행중에 동적으로 변하는(서버에 떠있는데 그 중간에 바꾸는) 경우는 거의(99%) 없으므로 생성자 주입을 권장한다. 만약 수정 소요가 있다면 config 파일을 손보고 다시 올린다.

생성자 주입

필드 주입

  • 필드에 spring project가 실행이 되면 값을 바꿀 수 없기에 별로 좋지 못하다.

setter 주입

  • 문제는 public으로 들어가기 때문에 controller단에서 아무 개발자가 건들 수 있다.
    이는 앞서 언급했던 문제가 생길 수 있기 때문에 지양하는 것이 좋다.

  • 이렇게 되면 원래는 loading할 때 조립시점(spring prj가 최초 로딩되는 시점)에서 바꾸는건데 이 이후에 바뀔 가능성이 있기 때문에 사용을 지양하자.

실무에서는 주로 정형화된 Controller, Service, Repository와 같은 코드는 Component Scan을 사용한다.
그리고 정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 springconfig를 통해 @Bean으로 등록한다.

  • 참고로 위처럼 하려면 당연히 뒤따라야하는 것이 요구사항을 사전이 미리 정확하게 정의하여 Component Scan할 class와 springconfig로 등록할 class를 명확하게 구분지어야한다.

  • 즉 자바로 수동으로 등록해주면 코드가 거의 연체동물마냥 유연해지고 유지보수 소요가 대폭 줄어든다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글