繁体   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