Free Lines Arrow
본문 바로가기
Spring/spring 기초 스터디

[Spring] Bean Scope Prototype: part3

by skahn1215 2021. 6. 14.
728x90
반응형

싱글톤과 프로토타입을 같이 사용했을때 문제점 해결

앞에서 싱글톤과 프로토타입을 같이 사용하면 발생되는 문제점을 봤다.

https://vprog1215.tistory.com/79

 

[Spring] Bean Scope Prototype: part2

싱글톤과 프로토타입을 같이 사용했을때 문제점 Bean Scope Prototype: Part1 은 아래 페이지에서 확인하자. https://vprog1215.tistory.com/71 [Spring] Bean Scope Prototype: part1 Bean Scope Prototype: part..

vprog1215.tistory.com

 

Provider 로 해결하는 방법을 알아보자

 

Spring 의 Provider 기능 사용.

스프링에서 제공해 주는 Provider기능을 사용하면 다음과 같이 간결하게 구현 할 수 있다.

특징

 

ObjectProvider 사용

  • ObjectProvider 를 선언을 먼저 해준다.
  • 그렇게 되면 컨테이너에서 해당 빈을 찾을수가 있다.
  • ObjectFactory 를 상속받아 ObjectProvider 가 구현되어 있다.
  • ApplicationContext ac; 를 사용하지 않고도 쉽게 Bean을 가져올수 있다.
  • getObject() 를 호출하여 스프링컨테이너를 통해 해당빈을 찾아서 반환한다. (DL 이라고한다.)

 

코드 설명

    // ClientBean 은 싱글톤
    @Scope("singleton")
    static class ClientBean {
       /*
        // 생성시점에 주입 그래서 계속 같은걸 쓴다.
        // 처음 주입때만 생성한다.
        // private final PrototypeBean prototypeBean;

        @Autowired
        ApplicationContext ac;

        // 이때 PrototypeBean을 요청하고 찾는다.
        // 이미 생성시점에 만들어 진 애를 사용한다.
        @Autowired
        public  ClientBean(PrototypeBean prototypeBean) {
           this.prototypeBean = prototypeBean;
        }

        public int logic() {
            // 여기가 핵심이다. 그냥 부를때 마다 빈을 가져온다.
            // 그렇게 되면 프로토타입의 동작을 제대로 한다.
            PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class);
            prototypeBean.addCount();
            return prototypeBean.getCount();
        }
        */


        @Autowired
        //private ObjectProvider<PrototypeBean> prototypeBeanProvider;  //방법1
        private ObjectFactory<PrototypeBean> prototypeBeanProvider;     //방법2

        public int logic() {
            // 항상 새로운 타입의 프로토타입이 생성됨.
            PrototypeBean prototypeBean =  prototypeBeanProvider.getObject();
            prototypeBean.addCount();
            int count = prototypeBean.getCount();
            return count;
        }
    }

 

 

 

JSR-330 Provider 사용

사용법

  • gradle 에  'java.inject:javax.inject:1' 
  • private ObjectFactory<PrototypeBean> prototypeBeanProvider; 에서 
    private Provider<PrototypeBean> prototypeBeanProvider;  변경
  • getObject() 에서 get() 으로 변경만 해주면된다.

특징

  • 자바표준이다. 스프링말고도 다른곳에서 사용가능하다.
  • 별도의 라이브러리 추가 필요
  • get() 하나만으로 해결

 

build.gradle 파일

plugins {
	id 'org.springframework.boot' version '2.4.4'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

//lombok 설정 추가 시작
configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}
//lombok 설정 추가 끝

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'

	// JSR-330 Provider 
    implementation 'java.inject:javax.inject:1'

	//lombok 라이브러리 추가 시작
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'

	testCompileOnly 'org.projectlombok:lombok'
	testAnnotationProcessor 'org.projectlombok:lombok'
    //lombok 라이브러리 추가 시작

	testImplementation ('org.springframework.boot:spring-boot-starter-test') {
		exclude group: 'org.junit'
	}
}

test {
	useJUnitPlatform()
}

 

코드구현

    // ClientBean 은 싱글톤
    @Scope("singleton")
    static class ClientBean {
       /*
        // 생성시점에 주입 그래서 계속 같은걸 쓴다.
        // 처음 주입때만 생성한다.
        // private final PrototypeBean prototypeBean;

        @Autowired
        ApplicationContext ac;

        // 이때 PrototypeBean을 요청하고 찾는다.
        // 이미 생성시점에 만들어 진 애를 사용한다.
        @Autowired
        public  ClientBean(PrototypeBean prototypeBean) {
           this.prototypeBean = prototypeBean;
        }

        public int logic() {
            // 여기가 핵심이다. 그냥 부를때 마다 빈을 가져온다.
            // 그렇게 되면 프로토타입의 동작을 제대로 한다.
            PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class);
            prototypeBean.addCount();
            return prototypeBean.getCount();
        }
        */


        /*
        @Autowired
        //private ObjectProvider<PrototypeBean> prototypeBeanProvider;  //방법1
        private ObjectFactory<PrototypeBean> prototypeBeanProvider;     //방법2

        public int logic() {
            // 항상 새로운 타입의 프로토타입이 생성됨.
            PrototypeBean prototypeBean =  prototypeBeanProvider.getObject();
            prototypeBean.addCount();
            int count = prototypeBean.getCount();
            return count;
        }
   */

        @Autowired
        private Provider<PrototypeBean> prototypeBeanProvider;

        public int logic() {
            // 항상 새로운 타입의 프로토타입이 생성됨.
            PrototypeBean prototypeBean = prototypeBeanProvider.get();
            prototypeBean.addCount();
            int count = prototypeBean.getCount();
            return count;
        }
    }

 

정리

  • Prototype은 잘 사용되지 않는다.
  • ObjectProvider 는 프로토 타입외에도 DL을 해줄때 사용된다. 편의기능도 있기 때문에 좋다.
  • JSR-330 Provider 는 스프링을 사용하지 않을때 쓴다. 정말 잘 쓰지 않아도 된다는것 같다.

 

 

 

참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/lecture/55390?tab=note 

 

스프링 핵심 원리 - 기본편 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

 

728x90
반응형

'Spring > spring 기초 스터디' 카테고리의 다른 글

[Spring] Annotation  (0) 2021.07.23
[Spring] Bean Scope Web: part4  (0) 2021.06.15
[Spring] Bean Scope Prototype: part2  (0) 2021.06.12
[Spring] Bean Scope Prototype: part1  (0) 2021.06.01
[Spring] Bean Scope  (0) 2021.06.01

댓글