수색…


저지의 HK2를 사용한 기본 의존성 주입

Jersey (2)는 종속성 주입 (DI) 시스템으로 HK2 를 사용합니다. 다른 인젝션 시스템을 사용할 수는 있지만 인프라는 HK2로 만들어져 우리의 어플리케이션에서 사용할 수 있습니다.

Jersey를 사용하여 간단한 의존성 주입을 설정하는 것은 단지 몇 줄의 코드로 이루어진다. 예를 들어 리소스에 주입하려는 서비스가 있다고 가정 해 보겠습니다.

public class GreetingService {
    public String getGreeting(String name) {
        return "Hello " + name + "!";
    }
}

그리고 우리는이 서비스를 저지 자원에 주입하려고합니다.

@Path("greeting")
public class GreetingResource {

    @Inject
    public GreetingService greetingService;

    @GET
    public String get(@QueryParam("name") String name) {
        return this.greetingService.getGreeting(name);
    }
}

주입이 작동하려면 간단한 구성 만 있으면됩니다.

@ApplicationPath("/api")
public class AppConfig extends ResourceConfig {
    public AppConfig() {
        register(GreetingResource.class);
        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bindAsContract(GreetingService.class);
            }
        });
    }
}

여기서 우리는 GreetingService 를 주입 시스템에 바인딩하고 동일한 클래스에 의해 주사 가능한 것으로 광고하기를 원합니다. 마지막 문장이 의미하는 것은 우리가 GreetingService 로만 주입 할 수 있다는 것입니다. 그리고 다른 클래스가 아닌 것으로 분명히 말할 수 있습니다. 나중에 보게 되겠지만 이것을 바꿀 수 있습니다.

그게 전부 야. 그게 다 필요한거야. 이 ResourceConfig 설정에 익숙하지 않다면 (아마도 web.xml을 사용하고있을 것입니다.) SO Docs에 있는 Jersey에서 JAX-RS 설정하기를 참조하십시오.


참고 : 위의 주입은 서비스가 자원 필드에 주입되는 필드 주입입니다. 또 다른 유형의 주입은 생성자 주입이며, 여기서 서비스는 생성자에 주입됩니다

private final GreetingService greetingService;

@Inject   
public GreetingResource(GreetingService greetingService) {
     this.greetingService = greetingService;
}

필드 주입과 반대로 이동하는 것이 선호되는 방법 일 수 있습니다. 단위 테스트를 쉽게 할 수 있기 때문입니다. 생성자 삽입에는 다른 구성이 필요하지 않습니다.


이제는 클래스 대신 GreetingService 가 인터페이스이고 구현이 있습니다 (매우 일반적입니다). 이것을 설정하기 위해서, 위의 configure 메쏘드에서 다음과 같은 구문을 사용합니다.

@Override
protected void configure() {
    bind(NiceGreetingService.class).to(GreetingService.class);
}

이것은 " NiceGreetingService 바인딩하고 GreetingService 로 광고"라고 읽습니다. 이는 우리가 GreetingService 가 아닌 NiceGreetingService 로 계약서를 광고하기 때문에 위의 GreetingResource 에서 똑같은 코드를 사용할 수 있음을 의미합니다. 그러나 실제 구현은 주입 될 때 NiceGreetingService 됩니다.

이제 스코프는 어떻습니까? 사출 프레임 워크로 작업 한 적이 있다면 서비스의 수명을 결정하는 범위 개념을 접하게 될 것입니다. 요청의 유효 기간 동안 만 서비스가 살아있는 "요청 범위"에 대해 들어 보셨을 것입니다. 또는 서비스의 인스턴스가 하나만있는 "Singleton Scope". 다음 구문을 사용하여 이러한 범위를 구성 할 수도 있습니다.

@Override
protected void configure() {
    bind(NiceGreetingService.class)
            .to(GreetingService.class)
            .in(RequestScoped.class);
}

기본 범위는 PerLookup 입니다. PerLookup ,이 서비스가 요청 될 때마다 새 서비스가 만들어집니다. 위의 예에서 RequestScoped 사용하면 단일 요청에 대해 새 서비스가 만들어집니다. 이것은 우리가 주입하려고하는 장소의 수에 따라 PerLookup 과 동일하거나 다를 수 있습니다. 우리는 그것을 필터와 자원에 주입하려고 시도했을 것입니다. 이것이 PerLookup 인 경우 각 요청에 대해 두 개의 인스턴스가 만들어집니다. 이 경우, 우리는 하나만 원합니다.

사용 가능한 다른 두 범위는 Singleton (단 하나의 인스턴스 생성)과 Immediate ( Singleton 과 같은)이지만 시작시 생성됩니다 (반면 Singleton 에서는 첫 번째 요청까지 생성되지 않습니다).

바인딩 클래스 외에도 인스턴스를 사용할 수도 있습니다. 이것은 우리에게 디폴트 싱글 톤을 제공 할 것이므로 in 문법을 사용할 필요가 없다.

@Override
protected void configure() {
    bind(new NiceGreetingService())
            .to(GreetingService.class);
}

복잡한 생성 로직이 있거나 서비스에 대한 요청 컨텍스트 정보가 필요한 경우에는 어떻게해야합니까? 이 경우에는 Factory 가 있습니다. 우리가 저지 자원에 주입 할 수있는 대부분의 것들, 우리는 또한 Factory 투입 할 수 있습니다. 예를 들어 보자.

public class GreetingServiceFactory implements Factory<GreetingService> {
    
    @Context
    UriInfo uriInfo;
    
    @Override
    public GreetingService provide() {
        return new GreetingService(
                uriInfo.getQueryParameters().getFirst("name"));
    }
    
    @Override
    public void dispose(GreetingService service) {
        /* noop */
    }
}

여기에 우리는 UriInfo 로부터 요청 정보를 얻는 팩토리를 가지고 있습니다.이 경우에는 질의 매개 변수이고, 우리는 그것으로부터 GreetingService 를 생성합니다. 이를 설정하기 위해 다음 구문을 사용합니다.

@Override
protected void configure() {
    bindFactory(GreetingServiceFactory.class)
            .to(GreetingService.class)
            .in(RequestScoped.class);
}

그게 전부 야. 이것들은 단지 기초 일뿐입니다. HK와 저지가해야 할 일이 많이 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow