gpt4 book ai didi

java - 如何让 Jersey 使用 Dagger 依赖注入(inject)?

转载 作者:太空狗 更新时间:2023-10-29 22:35:58 24 4
gpt4 key购买 nike

Jersey 通常使用 HK2 依赖注入(inject),但我想将 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,因为我想用 Dagger 替换 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.

}

所以主要方法看起来类似于:

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 集成?

最佳答案

你不应该把它想成“如何将 Dagger 与 Jersey 融为一体”。弄清楚如何设置 Jersey ,然后一旦弄清楚了,就可以担心使用 Dagger 了。

这是(非常粗略地)我会怎么做。

创建您自己的 ResourceConfig 类实现。

@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();

}

}

然后继续构建您的组件,并启动您的 HttpServer

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

还有一点需要注意。我个人从不使用 @Named("") 注释。我更喜欢使用限定符。因此,您创建了一个具有唯一值的 Qualifier 注释。然后你可以注入(inject)类似的东西

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

然后在注入(inject)的时候

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

如果您使用@Named 批注,您将不会在编译时检查冲突或缺失值。您会在运行时发现没有注入(inject)值,或者名称与其他名称冲突。它很快就会变得凌乱。

关于java - 如何让 Jersey 使用 Dagger 依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49221066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com