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

时间:2017-10-16 09:22:54

标签: java gradle dependency-injection vert.x hk2

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

请注意,我对依赖注入完全不熟悉。

我在this example中显示,但是我在启动应用程序时遇到NoSuchMethodException,因为它尝试访问Verticle类(SimpleVerticle)中的默认无参数构造函数,该构造函数不存在。

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

当然,我在某处丢失了某些东西。任何人都可以告诉我我错过了什么或者向我指出一些最新的完整示例吗?

  • Vert.x版本:3.4.2
  • Vert.x HK2版本:2.5.0

的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");
    }

}

ConfigBinder:

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);
    }

}

ConfigReader:

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;
    }

}

2 个答案:

答案 0 :(得分:0)

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

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

有关详细信息,请参阅bind

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

答案 1 :(得分:0)

管理修复它。

我切换到Guice我为JigObject注入ConfigReaderImpl类时遗漏了一些东西

新的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类中也缺少一个注释:

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