개발하는 자몽

Dependency LookUp 본문

Java/Spring

Dependency LookUp

jaamong 2022. 8. 12. 13:37

빈을 찾기 위한 다양한 의존성 검색 방법

스프링 빈 스코프를 공부하다가 의존성 주입(DI)뿐만 아니라 의존성을 갖는 빈을 검색 (DL, Depndency Lookup)할 때도 있다는 것을 알게 되었다. 스코프가 prototype이거나 request인 경우가 대표적이다. Spring은 빈을 검색하기 위한 다양한 방법들을 제공한다.

@Scope("prototype") //또는 @Scope("request")
public class UserRequest {
...
}

 

 

1. ApplicationContext

스프링은 DI 컨테이너인 ApplicationContext를 관리하고 있다. 그래서 ApplicationContext를 통해 필요한 빈을 검색할 수 있다.

@Service
@RequiredArgsConstructor
public class DemoService {

    private final ApplicationContext ac; 
    
    public void logic() {
    	UserRequest userRequest = ac.getBean(UserRequest.class); //DL
        ...
    }
    ...
}

이 방법은 일반 애플리케이션 코드에 스프링 API가 들어가게 되는 문제점이 있다. 즉, 스프링에 의존적이라는 뜻인데 이는 바람직하지 못하다. 또한 이에 대한 단위 테스트를 작성하는 것도 힘들다.

 

 

2. ObjectProvider

ObjectProvider는 ObjectFactory를 상속받았으며, getObject()를 호출하여 컨테이너를 통해 해당 빈을 찾아서 반환한다. 이 방법 또한 스프링에 의존적이다. 

@Service
@RequiredArgsConstructor
public class DemoService {
    private final ObjectProvider<UserRequest> userRequestProvider;
    
    public void logic(...) {
    	UserRequest userRequest = userRequestProvider.getObejct(); //DL
        ...
    }
    ...
}

 

 

3. JSR-330 Provider

'javax.inject.Provider' 라는 JSR-330 자바 표준이다. build.gradle에 'javax.inject:javax.inject.1' 라이브러리를 추가해서 사용해야 한다. 스프링 컨테이너를 통해 해당 빈을 찾아서 반환한다. get() 메서드 하나로 기능이 매우 단순하여 단위 테스트를 만들거나 mock 코드를 만들기가 훨씬 쉽다.

@Service
@RequiredArgsConstructor
public class DemoService {
	
    private final Provider<UserRequest> userRequestProvider;
    
    public void logic(...) {
    	UserRequest userRequest = userRequestProvider.get(); //DL
        ...
    }
    ...
}

 

 

4. 프록시(Proxy)

프록시 방식은 UserRequest의 가짜 프록시 클래스를 만든다. 사용 방법은 DL 대상의 클래스/인터페이스 상단 @Scope 애노테이션에 프록시 옵션을 추가한다. 적용 대상이 클래스면 'TARGET_CLASS'이고 인터페이스이면 'INTERFACES'로 작성하면 된다.

package hello.core.common;

...

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserRequest {
	...
}
package hello.core.web;

...

@Service
@RequiredArgsConstructor;
public class UserService {
	
    private final UserRequest userRequest;
    
    public void logic(...) {
    	... //전처럼 DL 코드가 필요치 않다.
    }
    
}

프록시 방식은 CGLIB(바이트 코드 조작) 라이브러리로 내 클래스를 상속 받은 가짜 프록시 객체를 만들어서 주입한다. 스프링 컨테이너에 "userRequest"라는 이름으로 진짜 클래스 대신에 가짜 프록시 객체를 등록한다. 

 

 

 

 

 

참고

 

[Spring] 빈을 찾기 위한 다양한 의존성 검색 방법, DL(Dependency LookUp)

1. 빈을 찾기 위한 다양한 의존성 검색 방법, DL(Dependency LookUp) Spring으로 개발을 하다보면 의존성을 주입(DI, Dependency Injection) 받는 것 뿐만 아니라 의존성을 갖는 빈을 검색(DL, Dependency LookUp)..

mangkyu.tistory.com

 

스프링 핵심 원리 기본편 23일차

# 스프링 핵심 원리 기본편 # 프로토타입 스코프_싱글톤 빈과 함께 사용 시 Provider로 문제 해결 싱글톤 빈과 프로토타입 빈을 함께 사용할 때 마다 항상 새로운 프로토타입 빈읋 생선하는 방법 중

dlagusgh1.tistory.com

Comments