I am struggling to understand the effective lifecycle of a @Dependent scoped bean in both CDI 1.0 and CDI 1.1. My experiments so far have lead me to the following conclusions:
- A
@Dependentscoped bean is not proxied. - No
@PreDestroymethod is invoked when a@Dependentbean is destroyed. Provider.get()always creates a new instance of a@Dependentbean.- With JBoss 6/CDI 1.0, a
@Dependentbean that is created by an@ApplicationScopedbean'sProvider<>field is "leaked", because it still "belongs" to theProvider. - I have seen no evidence (yet!) of
@Dependentbeans being leaked by similarProviders when using WELD 2.1.2.Final/CDI 1.1. (Although this might be because these particular@Dependentbeans are created by@Producesmethods...!)
I see that CDI 1.1 has added a destroy() method to Instance<>, presumably to address the memory leak in CDI 1.0. But what about Provider<> - does that still leak in CDI 1.1? (And if it does, then how are you supposed to use Provider.get()?)
Basically, I have several @ApplicationScoped beans / @Singleton EJBs that I @Inject Provider fields into, and I am trying to use Provider.get() as factories for both @Dependent and @RequestScoped "helper" beans. I definitely do not want these beans to "belong" to their Provider fields, as I need the beans to be garbage collected afterwards:
public void updateStuff() {
Helper helper = helperProvider.get();
// use helper...
}
For my CDI 1.0 application, I was thinking of fixing the memory leak by "faking" my Providers with code like this:
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 is a @Dependent scoped bean with no @PreDestroy method that only needs to be garbage collected when I've finished with it. However, I can't find a lot of information about Providers, and so can't tell if I'm arming some kind of time-bomb by doing this.
Some of my @Dependent scoped beans (which I still obtain via Provider.get(), btw) are created by @Produces methods. Are they still in danger of being leaked?
Can anyone advise me, please?
Thanks,
Chris