Errore nell'accesso privato della classe esterna iniettata CDI dalla classe interna statica
-
21-12-2019 - |
Domanda
Ho (in una versione minimalista) i seguenti fagioli gestiti CDI in JBoss EAP 6.0.1
@ApplicationScoped
public class Outer {
private final List<String> values = new ArrayList<String>();
public void printValues() {
System.out.println("Values: " + values);
}
private void addValue(String value) {
values.add(value);
}
public static class Inner {
@Inject
private Outer outer;
public void addFoo() {
outer.addValue("foo");
}
}
}
.
E il seguente codice per testare questo (non mettere in discussione perché. È solo per questa vetrina.):
@Inject
Outer outer;
@Inject
Outer.Inner inner;
public void test() {
inner.addFoo();
outer.printValues();
}
.
ottengo un'uscita di:
Values: {}
.
Dove mi sarei aspettato il valore foo.
Ulteriori indagini hanno rivelato che la chiamata a private void addValue
accede a una versione dell'Attributo values
che vive in un proxy generato da Outer
generato da Generato, mentre la chiamata a public void printValues
accede all'attributo reale dell'istanza del fagiolo gestito reale.
Per rendere le cose ancora più confuse: se cambio il livello di accesso di addValue
a uno dei package
, protected
o public
, tutto funziona come previsto.
Ma lo scopo della classe interiore nel mio caso era di facilitare il metodo per essere privato in modo che altri client CDI di esterni non possano chiamare il metodo. E ora è l'unica cosa che non funziona: D
Qualche idea Cosa c'è che non va? È un bug in saldatura?
Soluzione
Attualmente tutti i provider di CDI utilizzano i proxy (non è richiesto dalla specifica, ma è il modo in cui tutti e tre l'impleziona sono stati eseguiti) per iniettare oggetti non pseudo-scoped.Se esterno era @DependantScoped
sono abbastanza sicuro che avrebbe funzionato come vuoi.I proxy creati sono naturalmente sottoclassi delle tue classi, quindi chiamare un metodo privato su un oggetto iniettato non funzionerà.Onestamente sono sorpreso che non soffia.