jersey
저지와의 의존성 주입
수색…
저지의 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와 저지가해야 할 일이 많이 있습니다.