Я пытаюсь заставить DI с Guice работать, делая (как мне кажется) именно то, что есть в руководстве .
Я не могу объяснить проблему, потому что я действительно не понимаю ее - все кажется очень логичным и должно работать ... но это не так. Итак, я могу только прикрепить код и трассировку стека:
public class Runner {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new TestModule());
//next line throws the exception
JMeterComponent jMeterComponent =
injector.getInstance(JMeterComponent.class);
....
}
}
Как видите, я пытаюсь создать экземпляр объекта класса JMeterComponent
. Его конструктор (как вы увидите позже) принимает 3 аргумента: все они также должны быть созданы IoC и внедрены.
А вот TestModule
с конфигурацией этих 3 аргументов:
public class TestModule extends AbstractModule {
@Override
protected void configure() {
bind(Callable.class).annotatedWith(Names.named("JMeter"))
.to(JMeterTask.class);
bind(Processor.class).annotatedWith(Names.named("JMeter"))
.to(JMeterResultsProcessor.class);
bind(Renderer.class).annotatedWith(Names.named("JMeter"))
.to(JMeterResultsWikiRenderer.class);
}
}
Теперь давайте рассмотрим эти конкретные реализации - JMeterTask
, JMeterResultsProcessor
и JMeterResultsWikiRenderer
(для простоты у всех есть поддельные тела):
public class JMeterTask implements Callable<JMeterRawResults> {
public JMeterRawResults call() throws Exception {
return new JMeterRawResults();
}
}
public class JMeterResultsProcessor implements
Processor<JMeterRawResults, JMeterResults> {
public JMeterResults process(JMeterRawResults raw) {
return new JMeterResults();
}
}
public class JMeterResultsWikiRenderer implements Renderer<JMeterResults> {
public Map<String, String> render(JMeterResults jMeterResults) {
Map<String, String> results = Maps.newHashMap();
...
return results;
}
}
А теперь давайте посмотрим на класс JMeterComponent
, конструкция которого является целью всего, что связано с DI, здесь:
public class JMeterComponent extends AbstractComponent<String, String> {
@Inject
public JMeterComponent(@Named("JMeter") Callable<String> task,
@Named("JMeter")Processor<String, String> processor,
@Named("JMeter")Renderer<String> renderer) {
super(task, processor, renderer);
}
}
А вот и трассировка стека:
Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:
1) No implementation for stat.domain.Processor<java.lang.String, java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter) was bound.
while locating stat.domain.Processor<java.lang.String, java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter)
for parameter 1 at stat.components.jmeter.JMeterComponent.<init>(JMeterComponent.java:18)
while locating cstat.components.jmeter.JMeterComponent
2) No implementation for stat.domain.Renderer<java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter) was bound.
while locating stat.domain.Renderer<java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter)
for parameter 2 at stat.components.jmeter.JMeterComponent.<init>(JMeterComponent.java:18)
while locating stat.components.jmeter.JMeterComponent
3) No implementation for java.util.concurrent.Callable<java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter) was bound.
while locating java.util.concurrent.Callable<java.lang.String> annotated with @com.google.inject.name.Named(value=JMeter)
for parameter 0 at stat.components.jmeter.JMeterComponent.<init>(JMeterComponent.java:18)
while locating stat.components.jmeter.JMeterComponent
Некоторые дополнительные факты:
- я использую guice-2.0 (с
featured
этикетка)
- Нет больше аннотации из пакета
com.google.inject
в любом другом классе в коде
- Интерфейсы
Processor
и Renderer
размещены в одном модуле, а их jmeter
-реализации (JMeterResultsProcessor
и другие) и JMeterComponent
класса размещены в другом модуле.
Это почти все, что можно сказать об этом.
Извините за такой длинный пост и спасибо за ваше терпение, чтобы прочитать его до конца.
Есть идеи, почему произошла ошибка и как ее исправить?