[spring] provider 사용해보기

괭이밥·2022년 11월 20일

spring

목록 보기
7/10
post-thumbnail

🔍 목차

  1. provider란
  2. provider 예제


🍃 Provider란

스프링의 DL 기능

  • DL: Dependency Lookup, 의존관계 조회
    • 직접 필요한 의존관계를 찾는다.
  • 의존관계 외부에서 주입(DI)와 다른 개념이다.
  • 지정한 빈을 컨테이너에서 대신 찾아준다.

코드에 적용하기
1. ObjectProvider<T> 의존 관계 주입 받기

  • 생성자 주입 - private final ObjectProvider<PrototypeBean> prototypeBeanProvider;
  1. 필요할 때 스프링 빈에서 조회
  • getObject() 사용
  • PrototypeBean prototypeBean = prototypeBeanProvider.getObject();

언제 사용할까?

싱글톤 빈에서 프로토타입 빈 사용시 주의점

  • 싱글톤 빈에서 프로토타입 빈의 의존관계 주입이 끝났다면 프로토타입 빈은 하나만 생성된다!

예시를 통해 알아보자.
다음과 같이 싱글톤 빈에서 프로토타입 빈을 의존한다.

@Component
@Scope(value = "singleton")
public class SingletonBean {

	//프로토타입 빈 의존
    private final PrototypeBean prototypeBean;

	//프로토타입 빈 의존관계 주입
    @Autowired
    public SingletonBean(PrototypeBean prototypeBean) {
        this.prototypeBean = prototypeBean;
    }

    public void logic(){
    	//프로토타입 빈 주소 출력
        prototypeBean.logic();
    }
}

이 때 아래 테스트를 수행한 결과를 보자.

    @Test
    public void provider(){
    	ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        SingletonBean bean1 = ac.getBean(SingletonBean.class);
        bean1.logic();

        SingletonBean bean2 = ac.getBean(SingletonBean.class);
        bean2.logic();
    }
    
실행결과
test.core.prototype.PrototypeBean@281f23f2
test.core.prototype.PrototypeBean@281f23f2

프로토타입 빈 두번 사용했지만 같은 주소를 반환한 것을 볼 수 있다!

  • 싱글톤 빈은 한번 생성된다. 이때 의존관계 주입이 일어난다.

  • 프로토타입 빈은 의존관계 생성될 때 한번 호출된다.

  • 이후 싱글톤 빈 안에서 프로토타입 빈 사용이 일어날 때 생성한 프로토타입 빈만 사용한다.

    따라서 이런 결과가 일어난 것이다. 이 때 프로바이더를 사용하여 내가 필요할 때 스프링 빈에서 찾아 꺼내 사용하는 것이다.



🍃 Provider 예제

prototypeBean 작성

  • @Scope(value = "prototype"): 프로토타입 빈 생성한다.
  • logic(): 현재 prototypeBean를 출력한다.
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
@Scope(value = "prototype")
public class PrototypeBean {
    @PostConstruct
    public void init(){
        System.out.println("PrototypeBean.init");
    }

    public void logic(){
        System.out.println(this);
    }

}

SingletonBean 작성

  • 위에서 작성한 프로토타입빈을 의존한다.
    • ObjectProvider<T> : 저장한 빈을 컨테이너에서 대신 찾아주기 위해 프로바이더를 선언한다.
    • 이후 사용할 때 getObject()로 호출한다.
  • logic(): 프로토타입 빈을 직접 호출한다.
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(value = "singleton")
public class SingletonBean {

    private final ObjectProvider<PrototypeBean> prototypeBeanObjectProvider;

    public SingletonBean(ObjectProvider<PrototypeBean> prototypeBeanObjectProvider) {
        this.prototypeBeanObjectProvider = prototypeBeanObjectProvider;
    }

    public void logic(){
        PrototypeBean prototypeBean = prototypeBeanObjectProvider.getObject();
        prototypeBean.logic();
    }
}

테스트 해보기

  • 먼저 SingletonBean을 가져온다.
  • SingletonBean에 있는 logic을 호출한다.
  • SingletonBean의 로직은 PrototypeBean을 사용한다. 이 때 프로바이더가 해당 빈을 찾아서 반환한다.
    @Test
    public void provider(){
    	ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        SingletonBean bean1 = ac.getBean(SingletonBean.class);
        bean1.logic();

        SingletonBean bean2 = ac.getBean(SingletonBean.class);
        bean2.logic();
    }

실행결과

PrototypeBean.init
test.core.prototype.PrototypeBean@23e44287
PrototypeBean.init
test.core.prototype.PrototypeBean@2b8d084


출처
인프런 '스프링 핵심 원리 - 기본편' 강의

profile
개발도 하고 싶은 클라우드 엔지니어

0개의 댓글