Использование Assisted Inject с FactoryModuleBuilder в подсказке - Фабричное внедрение не выполняется
Я новичок, пытающийся выяснить, как внедрить вспомогательную инъекцию с помощью FactoryModuleBuilder. Я обратился к руководству по Java для реализации FactoryModuleBuilder.
Я сделал все именно так, как сказано в документах. Его не вводят на заводе. Я ссылался на этот вопрос переполнения стека: Guice AssistedInject не будет внедрять фабрику, которая имела ту же проблему. В нем говорится о введении поля до задачи инжектора конструктора. Я последовал за этим, и я пытаюсь вызвать класс Parent, используя класс вызывающего, но я все еще получаю исключение нулевого указателя. Что здесь не так?
Класс звонящего
public class MAIN {
@Inject private static MyFactory factory;
public static void main(String[] args){
ParentClass newbie = new ParentClass(factory);
}
}
Я все еще получаю исключение:
Exception in thread "main" java.lang.NullPointerException
at com.pkg.ParentClass.<init>(ParentClass.java:19)
at com.pkg.MAIN.main(MAIN.java:10)
Родительский класс
public class ParentClass {
private final Foo test;
@Inject
public ParentClass(MyFactory factory){
test = factory.create(new HashMap<String,Object>());
}
}
Реализация модуля: ParentModule
public class ParentModule extends AbstractModule{
@Override
protected void configure() {
install(new FactoryModuleBuilder()
.implement(Foo.class, FooImpl.class)
.build(MyFactory.class));
}
}
Заводской интерфейс: MyFactory
public interface MyFactory {
Foo create(Map<String,Object> map);
}
Интерфейс класса: Foo
public interface Foo{
}
Класс:FooImpl
public class FooImpl implements Foo {
private final Map<String,Object> mapA;
@AssistedInject
public FooImpl(@Assisted Map<String,Object> map){
mapA=map;
}
}
1 ответ
У вас есть две проблемы здесь.
Первое и самое важное, вы не создаете Injector
в любом месте. Очевидно, без инжектора ничего не получится. Вы должны создать экземпляр инжектора, используя ваш модуль:
Injector injector = Guice.createInjector(new ParentModule());
Ваша вторая проблема заключается в том, что вы хотите внедрить свою фабрику в статическое поле:
@Inject private static MyFactory factory;
Хотя Guice может работать со статическими полями, если вы укажете это явно, это считается очень плохой практикой. Никогда не вставляйте в статические поля, если вы не работаете с устаревшим кодом.
Что вы действительно хотите, это что-то вроде этого:
public class Main {
@Inject
private MyFactory factory;
public void run() {
ParentClass newbie = new ParentClass(factory);
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new ParentModule());
Main main = injector.getInstance(Main.class);
main.run();
}
}
Обратите внимание, что точка входа в программу (main
) теперь создает инжектор, а затем использует его для создания экземпляра Main
класс, в который будет вставлено его поле автоматически. И тогда это вызывает метод run()
на экземпляр, который выполняет фактическую работу.
Обратите внимание, однако, что все это действительно действительно только в иллюстративных целях для вспомогательной инъекции. Вы не должны структурировать свой реальный код таким образом. Например, вы используете new
оператор для создания классов, чьи конструкторы помечены @Inject
, Никогда не делай этого! Если вы пометите некоторый класс (т.е. его конструкторы или поля) как @Inject
В состоянии, то этот класс следует использовать только с помощью инъекций. Ваш Main
код может быть сокращен до следующего:
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new ParentModule());
ParentClass newbie = injector.getInstance(ParentClass.class);
}
}
Вот newbie
автоматически получит экземпляр MyFactory
в его конструктор, так как он помечен @Inject
,
И я уже писал о статике.