Dropwizard 石英作业不适用于 Guicey

Dropwizard quartz jobs won't work with Guicey

我正在使用 dropwizard 1.0.5、dropwizard-guicey 4.0.1 (https://github.com/xvik/dropwizard-guicey), spinscale quartz implementation 3.0.0 (https://github.com/spinscale/dropwizard-jobs)。

我希望能够将我的依赖项注入到 quartz/spinscale 创建的作业实例中。为此,我尝试加载以下库 https://github.com/spinscale/dropwizard-jobs/tree/master/dropwizard-jobs-guice

这个问题是,当创建 Guice dropwizard 作业包时,Guice 注入器尚未初始化,所以我得到一个 NPE。

示例: MyApplication.java

  @Override
  public void initialize(Bootstrap<MyConfiguration> bootstrap) {

    // Initialize Guice for dependency injection

    GuiceBundle guiceBundle = GuiceBundle.builder()
            .bindConfigurationInterfaces()
            .enableAutoConfig(getClass().getPackage().getName())
            .modules(new MyModule(bootstrap.getMetricRegistry()))
            .build();
    bootstrap.addBundle(guiceBundle);

    bootstrap.addBundle(new GuiceJobsBundle(guiceBundle.getInjector()));

异常:

Exception in thread "main" java.lang.NullPointerException: Guice not initialized
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:226)

为了解决这个问题,我尝试创建自己的 GuiceJobsBundle 版本,它接受 GuiceBundle 并且在调用 bundle.run() 之前不设置注入器。但是,我还是得到了 NPE。

MyApplication

  @Override
  public void initialize(Bootstrap<MyConfiguration> bootstrap) {
    // Substitute environment variable references in the configuration file
    bootstrap.setConfigurationSourceProvider(new SubstitutingSourceProvider(
        bootstrap.getConfigurationSourceProvider(),
        new EnvironmentVariableSubstitutor(false, true)
    ));

    // Initialize Guice for dependency injection

    GuiceBundle guiceBundle = GuiceBundle.builder()
            .bindConfigurationInterfaces()
            .enableAutoConfig(getClass().getPackage().getName())
            .modules(new MyModule(bootstrap.getMetricRegistry()))
            .build();
    bootstrap.addBundle(guiceBundle);

    bootstrap.addBundle(new GuiceyJobsBundle(guiceBundle));
  }

GuiceyJobsBundle

public class GuiceyJobsBundle extends JobsBundle {

    private GuiceBundle guiceBundle;

    public GuiceyJobsBundle(GuiceBundle guiceBundle) {
        this.guiceBundle = guiceBundle;
    }

    @Override
    public void run(Environment environment) {
        JobManager jobManager = new GuiceJobManager(guiceBundle.getInjector());
        environment.lifecycle().manage(jobManager);
    }
}

什么时候调用包的 run() 方法?有人为此找到了可行的解决方案吗?

上次修复几乎是正确的,只是忘记绑定配置 jobManager.configure(configuration)(这就是抛出 NPE 的原因)。

但是您完全可以在没有捆绑包的情况下进行集成。我看到您已经使用类路径扫描,所以只需将这些扩展放在某处即可:

@Singleton
public class JobsManager extends GuiceJobManager {

    @Inject
    public JobsManager(Injector injector, JobsAppConfiguration configuration) {
        super(injector);
        configure(configuration);
    }
}

这将被识别为托管 bean 并且将 start/stop 石英上下文。它在内部搜索已注册的 guice bindngs 中的工作(使用 dropwizard-jobs 逻辑)。

public class JobsInstaller implements FeatureInstaller<Job>, TypeInstaller<Job> {

    private final Reporter reporter = new Reporter(JobsInstaller.class, "jobs =");

    @Override
    public boolean matches(Class<?> type) {
        return FeatureUtils.is(type, Job.class);
    }

    @Override
    public void install(Environment environment, Class<Job> type) {
        // here we can also look for class annotations and show more info in console
        // (omitted for simplicity)
        reporter.line("(%s)", type.getName());
    }

    @Override
    public void report() {
        reporter.report();
    }
}

此安装程序只是将所有作业绑定到 guice 上下文,因此 JobsManager 可以安装它们(只是为了避免手动作业绑定)。

我将竞争示例添加到 guicey-examples 回购:https://github.com/xvik/dropwizard-guicey-examples/tree/master/dropwizard-jobs