Vertx & HK2 - 启动应用程序(依赖注入)

Vertx & HK2 - Launching the application (dependency injection)

我正在尝试使用 Vert.x 和 HK2 扩展构建应用程序以进行依赖注入。然而,我似乎无法找到任何向我展示全貌的示例。

请注意,我对依赖注入完全陌生。

我做了 this example 中所示的操作,但是在启动应用程序时我收到了 NoSuchMethodException,因为它试图访问 Verticle class (SimpleVerticle) 中的默认无参数构造函数,它确实不存在。

在我的 build.gradle 中,mainClassName 设置为 'io.vertx.core.Launcher',在 shadowJar 清单属性中,"Main-Verticle" 设置为示例中的 SimpleVerticle。

肯定是我遗漏了什么地方。谁能告诉我我遗漏了什么或指出一些最新的完整示例?

build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }
}

plugins {
    id 'java'
    id 'application'
    id 'com.github.johnrengelman.shadow' version '1.2.3'
    id 'java-library'
    id 'eclipse'
    id 'idea'
    id 'maven'
    id 'groovy'
    id 'jacoco'
}


group 'example'
version "${buildVersion}"

repositories {
    mavenCentral()
}

sourceCompatibility = '1.8'
targetCompatibility = '1.8'

dependencies {
    compile('io.vertx:vertx-core:3.4.2')
    compile('io.vertx:vertx-web:3.4.2')
    compile('javax.json:javax.json-api:1.1')
    compile('org.glassfish:javax.json:1.0.4')
    compile('log4j:log4j:1.2.17')
    compile('io.vertx:vertx-web-client:3.4.2')
    compile('com.englishtown.vertx:vertx-hk2:2.5.0')
    testCompile "junit:junit:4.12"
    testCompile "io.vertx:vertx-unit:3.3.3"
    testCompile "com.jayway.restassured:rest-assured:2.4.0"
    testImplementation 'junit:junit:4.12'
}

mainClassName = 'io.vertx.core.Launcher'

shadowJar {
    classifier = 'fat'
    baseName = 'aggregator-api'
    manifest {
        attributes "Main-Verticle": 'example.startup.StartupVerticle'
    }
    mergeServiceFiles {
        include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
    }
}

StartupVerticle:

package example.startup;

import example.config.ConfigReader;
import io.vertx.core.AbstractVerticle;

import javax.inject.Inject;

public class StartupVerticle extends AbstractVerticle {

    private final ConfigReader configReader;

    @Inject
    public StartupVerticle(final ConfigReader configReader) {
        this.configReader = configReader;
    }

    @Override
    public void start() throws Exception {
        if(this.configReader == null) throw new IllegalStateException("ConfigReader was not injected!");

        super.start();
        System.out.println("Started verticle using DI");
    }

}

配置绑定器:

package example.binder;

import example.config.ConfigReader;
import example.config.ConfigReaderImpl;
import org.glassfish.hk2.utilities.binding.AbstractBinder;

public class ConfigBinder extends AbstractBinder {

    @Override
    protected void configure() {
        this.bind(ConfigReaderImpl.class).to(ConfigReader.class);
    }

}

配置读取器:

package example.config;

import io.vertx.core.json.JsonObject;

public interface ConfigReader {

    JsonObject getConfig();

}

ConfigReaderImpl:

package example.config;

import io.vertx.core.json.JsonObject;

public class ConfigReaderImpl implements ConfigReader {

    private final JsonObject config;

    ConfigReaderImpl(JsonObject config) {
        this.config = config;
    }

    @Override
    public JsonObject getConfig() {
        return this.config;
    }

}

在我看来,您需要在某处实际创建 ServiceLocator。像这样:

private void startServiceLocator() {
  ServiceLocatorUtilities.bind("MyServiceLocator", new ConfigBinder());
}

有关详细信息,请参阅 bind

另请参阅有关如何启动 hk2 的更多信息:Getting Started

设法修复它。

我切换到 Guice 我缺少一些用于 ConfigReaderImpl 的 JsonObject 注入的东西 class

新的 ConfigBinder:

public class ConfigBinder extends AbstractModule {

    private final String CONFIG_PATH = "config";

    @Override
    protected void configure() {
        this.bind(ConfigReader.class).to(ConfigReaderImpl.class).in(Scopes.NO_SCOPE);
        this.bindConfig(Vertx.currentContext().config(), this.CONFIG_PATH);
    }

    private void bindConfig(JsonObject config, String path) {
        this.bind(JsonObject.class).annotatedWith(Names.named(path)).toInstance(config);
    }

}

我还缺少 ConfigReaderImpl 中的注释 class:

public class ConfigReaderImpl implements ConfigReader {

    private final JsonObject config;

    @Inject
    private ConfigReaderImpl(@Named("config") final JsonObject config) {
        this.config = config;
    }

    @Override
    public JsonObject getConfig() {
        return this.config;
    }

}

我设法部署了一个依赖注入的 Verticle:

Injector injector = Guice.createInjector(new ConfigBinder());
Verticle verticle = injector.getInstance(SomeVerticle.class);
this.getVertx().deployVerticle(verticle);