Injeção de dependência com argumentos de construtor
-
26-12-2019 - |
Pergunta
Eu tenho um EJB do seguinte modo:
public class Bar() {
private String s;
public Bar() {
this.s = "bar";
}
@Inject public Bar(String s) {
this.s = s;
}
}
Como posso injetar esse feijão usando o construtor arg em outro
Foo
aula?Então, defino o
Foo
classe como EJB, com o objetivo de realizar o DI transferi-lo para outra classe (por exemplo, um WebServlet).Como posso injetar umFoo
instância de classe passando umString
para configurar corretamenteBar
arg-construtor como dependência interna?Existe uma maneira melhor de definir
Bar
para alcançar os pontos acima?
Solução
A injeção do construtor anotado informa ao CDI que sempre que alguém solicitar que uma instância de Bar seja injetada, ele deverá usar o construtor marcado com @Inject.
O contêiner CDI então tenta obter instâncias para todos os parâmetros necessários do construtor e falha, porque não consegue lidar com "String".Ele simplesmente não sabe qual String você quer dizer.
Você tem que ajudar o contêiner a resolver a dependência usando um Produtor e um Qualificador para dizer a ele qual String você deseja.Acabei de lhe dar a solução mais simples possível aqui:
public class Bar {
@Inject
public Bar(@Named("myString") String s) {
this.s = s;
}
}
E depois outra classe (não precisa ser uma classe diferente, mas é muito mais legível):
public class MyStringProducer {
@Produces
@Named("myString")
public String getMyString() {
return ...; // whatever you want ... read JSON, parse properties, randomize ...
}
}
Outras dicas
@Inject
só funciona quando você está injetando "managed
"objetos.String não é um objeto gerenciado, portanto não funcionará.
No entanto, o exemplo a seguir deve funcionar (usei spring aqui.Utilize o código de inicialização DI de acordo com a biblioteca que você está utilizando):
@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;
}
}