java - Jersey 3 - 使用bindFactory配置绑定(bind)

标签 java dependency-injection jersey jersey-3.0

使用 Jersey 3.0.1,我正在努力使绑定(bind)工作。

我有这个绑定(bind)模块与以下工厂:

public static class MyBinder extends AbstractBinder {
    @Override
    protected void configure() {
      LOG.info("Attempting to configure binder");
      bindFactory(DataSourceFactory.class).to(HikariDataSource.class).in(Singleton.class);
      bindFactory(JooqConfigFactory.class).to(Configuration.class).in(Singleton.class);
      bindFactory(DSLContextFactory.class).to(DSLContext.class).in(Singleton.class);
      LOG.info("Configured binder");
    }
}

public static class DataSourceFactory implements Supplier<HikariDataSource> {
    @Override
    public HikariDataSource get() {
      ...
      return new HikariDataSource(config);
    }
}

public static class JooqConfigFactory implements Supplier<Configuration> {
    @Inject
    HikariDataSource dataSource;

    @Override
    public Configuration get() {
      ...   
      return conf;
    }

}

public static class DSLContextFactory implements Supplier<DSLContext> {
    @Inject
    Configuration config;

    @Override
    public DSLContext get() {
      return DSL.using(config);
    }
}

然后我使用嵌入式 Jetty 设置 Servlet:

public void start() throws Exception {
    int port = appConfig.getProperty("http.port", 9998);
    Server server = new Server(port);

    ServletContextHandler ctx =
        new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
    ctx.setContextPath("/");
    server.setHandler(ctx);
    ResourceConfig config = new JerseyConfig();
    ServletHolder servlet = new ServletHolder(new ServletContainer(config));
    servlet.setInitOrder(1);
    ctx.addServlet(servlet, "/*");

    server.start();
    server.join();
}

public static class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
      packages("com.sodonnell.jersey", "jersey.config.server.provider.packages");
      register(new MyBinder());
    }
}

在我的 Rest 服务中,我只是尝试注入(inject)一个私有(private)实例变量:

public MyClass {

  @Inject  // javax.inject.Inject
  private DSLContext dslContext;

}

但是这个 dslContext 始终为空。我可以从日志中看到,它打印了 LOG.info("Configured binder"); 消息。然而,将类似的日志放入我的工厂类中表明它们从未被调用。

有人知道我缺少什么吗?

编辑

为了让事情变得更简单,我创建了这个类:

public class SimpleClass {

  private static Logger LOG = LoggerFactory.getLogger(SimpleClass.class);

  public SimpleClass() {
    LOG.info("Call the simple class constructor");
  }

更改了我的 Binder 模块:

import com.google.inject.Injector;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import org.jooq.Configuration;
import org.jooq.DSLContext;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
import org.jooq.impl.DefaultConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.Properties;
import java.util.function.Supplier;
...


 // This is a nested class 
 public static class MyBinder extends AbstractBinder {
    @Override
    protected void configure() {
      LOG.info("Attempting to configure binder");
      bind(new SimpleClass()).to(SimpleClass.class); 
    }
  }

然后尝试注入(inject) SimpleClass:

package com.sodonnell.hdfs3.rest;

import com.sodonnell.hdfs3.SimpleClass;
import com.zaxxer.hikari.HikariDataSource;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.HEAD;
import jakarta.ws.rs.core.HttpHeaders;

import jakarta.ws.rs.Path;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.Response;
import org.jooq.DSLContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;

  @Inject
  private SimpleClass simpleClass;
...

但它仍然为空,尽管我看到了两条日志消息。我肯定缺少一些基本设置。

SimpleClass 示例的完整精简代码位于:

github.com/sodonnel/jerseyBind

最佳答案

答案很简单。您正在使用 Jersey 3.0,它已切换为新的 Jakarta 命名。 javax 被抛出窗外 - 这包括 javax.inject。所有 javax 包名称现已更改为 jakarta。因此,要使注入(inject)正常工作,@Inject 导入应该是

import jakarta.inject.Inject;

此更改是 Java EE 更改为 Jakarta EE 的一部分从 Jakarta EE 8 到 Jakarta EE 9,所有命名空间都从 javax 更改为 jakarta。因此,像 javax.servlet 这样的东西现在将是 jakarta.servlet。奇怪的是,是的,这是一个巨大的突破性变化,没有向后兼容性。

在您的情况下,您拥有与 Jakarta 一起使用的所有正确组件(即 Jersey 3.0 和 Jett 11),但您只需要使用新的命名空间。请注意,所有 JAX-RS 导入现在也是 jakarta

关于java - Jersey 3 - 使用bindFactory配置绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66564662/

相关文章:

java - 皮尼乌斯。导入错误: DLL load failed: The specified module was not found

java - 需要一个RpcDispatcher的例子来进行远程方法调用

安卓错误 "android.app.Application does not implement dagger.android.HasActivityInjector"

java - NoSuchBeanException,即使定义了 Bean

java - 由 : java.net.NoRouteToHostException: No route to host 引起

java - RESTFul 服务器中的多态性

java - 在命令行的类路径中包含 jars(javac 或 apt)

java - JSP Unix 文件列表

java - 无法在 Rest Web 服务中调用 EJB

java - Jersey - 从 ResultSet 返回流