Внедрение зависимостей с аргументами конструктора
-
26-12-2019 - |
Вопрос
У меня есть EJB следующим образом:
public class Bar() {
private String s;
public Bar() {
this.s = "bar";
}
@Inject public Bar(String s) {
this.s = s;
}
}
Как я могу ввести этот компонент, используя arg-конструктор в другой
Foo
класс?Затем я определяю
Foo
класс как EJB, с целью выполнения DI перевести его в другой класс (например, WebServlet).Как я могу ввестиFoo
экземпляр класса, передаваяString
для правильной настройкиBar
arg-конструктор как внутренняя зависимость?Есть ли лучший способ определить
Bar
для того, чтобы достичь вышеуказанных результатов?
Решение
Внедрение аннотированного конструктора сообщает CDI, что всякий раз, когда кто-либо запрашивает ввод экземпляра Bar, он должен использовать конструктор, помеченный символом @Inject .
Затем контейнер CDI пытается получить экземпляры для всех требуемых параметров конструктора и завершается неудачей, поскольку он не может обработать "Строку".Он просто не знает, какую Строку вы имеете в виду.
Вы должны помочь контейнеру разрешить зависимость, используя Producer и квалификатор, чтобы сообщить ему, какая строка вам нужна.Я просто даю вам здесь самое простое из возможных решений:
public class Bar {
@Inject
public Bar(@Named("myString") String s) {
this.s = s;
}
}
А затем другой класс (не обязательно должен быть другим классом, но он гораздо более читабелен):
public class MyStringProducer {
@Produces
@Named("myString")
public String getMyString() {
return ...; // whatever you want ... read JSON, parse properties, randomize ...
}
}
Другие советы
@Inject
работает только тогда, когда вы делаете инъекцию "managed
" объекты.Строка не является управляемым объектом, поэтому это не сработает.
Однако следующий пример должен сработать (здесь я использовал spring.Используйте код инициализации DI в соответствии с используемой библиотекой):
@Named
public class Foo {
@Inject
Bar bar;
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext("com.pkg1");
Foo foo = (Foo)ctx.getBean("foo");
System.out.println(foo.bar.getString());
}
}
@Named
public class Bar {
private String s;
public Bar() {
this.s = "bar";
}
@Inject
public Bar(Bar1 bar1) {
this.s = bar1.getS();
}
public String getString() {
return s;
}
}
@Named
class Bar1 {
private String s="bar1";
public String getS() {
return s;
}
}