簡體   English   中英

如何使 Jersey 使用 Dagger 依賴注入?

[英]How to make Jersey work with Dagger dependency injection?

Jersey 通常使用 HK2 依賴注入,但我想將 Jersey 與 Dagger 2 一起使用。Dagger 和 HK2 都實現了 JSR 330,我已經將其作為證據表明這應該可以不費吹灰之力。 我找到了使 Jersey 與 CDI(例如 Weld)、Spring DI 和 Guice 一起工作的方法,但我在 Dagger 上找不到任何東西。

提供一些上下文:我在 SE 環境中運行 Grizzly-Jersey 服務器,而不是在 EE 容器中。 我的 Maven 項目有com.google.dagger:daggerorg.glassfish.jersey.containers:jersey-container-grizzly2-http作為依賴項,但沒有org.glassfish.jersey.inject:jersey-hk2 ,因為我想替換 HK2用匕首。

資源類如下所示:

@Path("/example")
public final class ExampleResource {

    private final Dependency dependency;

    @Inject
    public ExampleResource(final Dependency dependency) {
        this.dependency = Objects.requireNonNull(dependency);
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Example getExample() {
        return this.dependency.giveExample();
    }

}

Dagger 組件可以定義如下:

@Component
public interface Application {

    public ExampleResource exampleEndpoint();
    public XyzResource xyzEndpoint();
    // etc.

}

這樣 main 方法看起來類似於:

public final class Main {

    public static void main(final String[] args) {
        final Application application = DaggerApplication.create();
        final URI baseUri = UriBuilder.fromUri("http://0.0.0.0/").port(80).build();
        final ResourceConfig resourceConfig = new ResourceConfig();
        // how to initialize `resourceConfig` using `application`?
        final HttpServer httpServer = GrizzlyHttpServerFactory
                .createHttpServer(baseUri, resourceConfig, false);
        try {
            httpServer.start();
        } catch (final IOException ex) {
            ...
        }
    }

}

立即運行應用程序會導致異常: IllegalStateException: InjectionManagerFactory not found. 似乎需要這個工廠的 Dagger 實現。

我的問題是:如何將 Dagger 與 Jersey 集成?

您不應該將其視為“如何將匕首與球衣融為一體”。 弄清楚如何設置 jersey,然后一旦弄清楚了,就可以擔心使用匕首了。

這是(非常粗略地)我會怎么做。

創建您自己的 ResourceConfig class 實現。

@ApplicationPath("/service")
public class MyResourceConfig extends ResourceConfig {

    @Inject
    public MyResourceConfig(
            @Nonnull final ExampleResource exampleResource) {
        this.register(exampleResource);
    }

}

然后創建一個模塊來設置創建 HttpServer 所需的一切

@Module
public class MyServiceModule {

    @Provides
    @Singleton
    @Named("applicationPort")
    public Integer applicationPort() {
        return 80;
    }

    @Provides
    @Singleton
    @Named("applicationBaseUri")
    public URI baseUri(
            @Named("applicationPort") @Nonnull final Integer applicationPort) {
        return UriBuilder.fromUri("http://0.0.0.0/").port(applicationPort).build();
    };

    @Provides
    @Singleton
    public HttpServer httpServer(
            @Named("applicationBaseUri") @Nonnull final URI applicationBaseUri,
            @Nonnull final MyResourceConfig myResourceConfig) {
        return GrizzlyHttpServerFactory
                .createHttpServer(applicationBaseUri, myResourceConfig, false);
    }

}

然后創建公開 HttpServer 的組件。 我通常喜歡制作盡可能少暴露的組件。 在這種情況下,您需要公開的只是 HttpServer。

@Singleton
@Component(modules = { MyServiceModule.class })
protected interface ServiceComponent {

    HttpServer httpServer();

    @Component.Builder
    interface Builder {

        // Bind any parameters here...

        ServiceComponent build();

    }

}

然后只需 go 並構建您的組件,並啟動您的 HttpServer

public static void main(String[] args) {
    final ServiceComponent component = DaggerServiceComponent.builder().build()
    try {
        component.httpServer().start();
    } catch (Exception ex) {
        // handle exception...
    }
}

還有一件事要注意。 我個人從不使用 @Named("") 注釋。 我更喜歡使用限定詞。 因此,您創建了一個具有唯一值的 Qualifier 注釋。 然后你可以注入類似的東西

@Provides
@Singleton
@MyUniqueQualifier
public String myUniqueQualifierProviderValue() {
    return "something";
}

然后注射的時候

@Inject
public SomeClass(@MyUniqueQualifier @Nonnull final String myUniqueQualifiedValue) 

如果您使用 @Named 注釋,您將不會在編譯時檢查是否存在沖突或缺失值。 您會在運行時發現沒有注入值,或者名稱與其他名稱沖突。 它很快就會變得凌亂。

您需要實現一個InjectionManagerFactory ,它將返回一個委托給Dagger的InjectionManager ,並通過在META-INF/services一個條目將其注冊為META-INF/services ,類似於hk2: https//github.com/jersey/jersey /blob/master/inject/hk2/src/main/resources/META-INF/services/org.glassfish.jersey.internal.inject.InjectionManagerFactory但引用了您自己的實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM