Non riesco a comprendere l'effettivo ciclo di vita di un bean con scope @Dependent
in CDI 1.0 e CDI 1.1. I miei esperimenti finora mi hanno portato alle seguenti conclusioni:Quando viene distrutto un bean CDI con scope @Dependent, se si ottiene quel bean tramite Provider.get()?
- Un bean con scope non è proxy.
- No
@PreDestroy
metodo invocato quando un bean@Dependent
viene distrutto. Provider.get()
crea sempre una nuova istanza di un bean@Dependent
.- Con JBoss 6/1.0 CDI, un
@Dependent
fagiolo che viene creato da un campo@ApplicationScoped
beanProvider<>
viene "rubato", perché ancora "appartiene" alProvider
. - Non ho visto alcuna prova (ancora!) Di
@Dependent
fagioli che sono stati persi da similiProvider
s quando si utilizza WELD 2.1.2.Final/CDI 1.1. (Anche se questo potrebbe essere perché questi particolari@Dependent
fagioli sono creati da@Produces
metodi ...!)
vedo che CDI 1.1 ha aggiunto un metodo destroy()
a Instance<>
, presumibilmente per affrontare la perdita di memoria in CDI 1.0 . Ma che dire di Provider<>
- fa ancora una perdita in CDI 1.1? (E se lo fa, allora come si suppone di utilizzare Provider.get()
?)
Fondamentalmente, ho diverse @ApplicationScoped
fagioli/@Singleton
EJB che I @Inject
Provider
campi in, e sto provando ad usare Provider.get()
come fabbriche per entrambi @Dependent
e @RequestScoped
fagioli "helper". Io sicuramente non vogliono questi fagioli a "appartengono" ai loro Provider
campi, come ho bisogno i fagioli da garbage collection in seguito:
public void updateStuff() {
Helper helper = helperProvider.get();
// use helper...
}
Per la mia applicazione CDI 1.0, stavo pensando di fissare il perdita di memoria da "falsificare" le mie Provider
s con codice come questo:
provider = new Provider<MyBean>() {
@Override
public MyBean get() {
return getReferenceFor(MyBean.class);
}
};
private <T> T getReferenceFor(Class<T> type) {
Bean<?> bean = beanManager.resolve(beanManager.getBeans(type));
CreationalContext<?> context = beanManager.createCreationalContext(bean);
try {
return (T) beanManager.getReference(bean, bean.getBeanClass(), context);
} finally {
// Destroy this context - which I don't want to exist anyway.
// I only need a strong reference to a fully @Inject-ed bean!
context.release();
}
}
MyBean
è un @Dependent
con scope di fagioli con nessun metodo @PreDestroy
che ha solo bisogno di essere garbage collection quando I'v e finito con esso. Tuttavia, non riesco a trovare molte informazioni su Provider
s, e quindi non posso dire se sto armando una specie di bomba a tempo facendo questo.
Alcuni dei miei fagioli con ambito @Dependent
(che ottengo ancora tramite Provider.get()
, btw) sono creati dai metodi @Produces
. Sono ancora in pericolo di essere trapelati?
Qualcuno mi può consigliare, per favore?
Grazie,
Chris
Ho anche avuto questo problema. Ho verificato in JVisualVM che tutti i bean dipendenti dal mio bean ApplicationScoped non ricevono mai garbage collection perché dipendono dal bean ApplicationScoped. Ho finito per fare una cosa simile come hai fatto tu. CDI 1.1 risolve questo problema con la classe CDI come ha detto Martin, ma io sono su 1.0 in EE6, quindi ho dovuto usare il BeanManager. – user12722