[cdi-dev] Producer#dispose(T instance) and similar

Pete Muir pmuir at redhat.com
Tue Dec 4 11:46:23 EST 2012


Hi Mark, I'll try to answer inline, but I'm missing a bit of background about what you are doing...

On 4 Dec 2012, at 14:20, Mark Struberg wrote:

> Another problem probably being an interceptor on the @Disposes method itself.
> Where does the Proucer#dispose(T instance) get the interceptor from?
> 
> LieGrue,
> strub
> 
> 
> 
> 
> ----- Original Message -----
>> From: Mark Struberg <struberg at yahoo.de>
>> To: cdi-dev <cdi-dev at lists.jboss.org>
>> Cc: 
>> Sent: Tuesday, December 4, 2012 3:16 PM
>> Subject: [cdi-dev] Producer#dispose(T instance) and similar
>> 
>> Hi!
>> 
>> I'm currently stumbling over implementing 
>> 
>> Producer#dispose(T instance) properly
>> 
>> The Producer#produce(CreationalContext)
>> 
>> has the CreationalContext parameter but the dispose

Right, it would have been good to have included it here. I'm not sure why it wasn't, however I don't believe that it causes a problem with the CDI 1.0 spec, but just limits us going forward.

>> and others do not have it.

Yes.

>> 
>> Problem here is that a Producer could probably get exchanged via a portable 
>> extension via ProcessProducer#setProducer(Producer)

Yes, this is definitely supported

>> so it could be from a 
>> foreign source which must not know anything about container implementation 
>> details.

Yes.

I think the critical part of the spec to understand this is 11.2. I'm quoting here from the CDI 1.1 spec, into which we have add the clarification that "The instance returned by produce() may be a proxy.". The part about building interceptors and decorators is there in CDI 1.0.

> For a Producer that represents a class:
> 
> 	• produce() calls the constructor annotated @Inject if it exists, or the constructor with no parameters otherwise, as defined in [instantiation], and returns the resulting instance. If the class has interceptors,produce() is responsible for building the interceptors and decorators of the instance. The instance returned by produce() may be a proxy.
> 
> 	• dispose() does nothing.

and

> For a Producer that represents a producer method or field:
> 
> 	• produce() calls the producer method on, or accesses the producer field of, a contextual instance of the bean that declares the producer method, as defined in [methods].
> 
> 	• dispose() calls the disposer method, if any, on a contextual instance of the bean that declares the disposer method, as defined in [methods], or performs any additional required cleanup, if any, to destroy state associated with a resource.

Now, let me start to break down your sentence :-)

>> 
>> What now about having an interceptor on @PreDestroy?

For a start, it's worth remembering interceptors can only be associated with beans defined by a class. If the bean is a producer, then you can't intercept the instance produced (only the invocation of the producer).

>> This is what you get if 
>> your interceptor has a at PreDestroy method himself as per the interceptors and EJB 
>> specs. That would mean that the instance passed to dispose() whould be the 
>> proxy? That purely sounds wrong to me.

Based on my comment from above, I think it's clear that dispose() should never try to invoke predestroy methods. That is the job of InjectionTarget.preDestroy(). I would expect a proxy to be passed to preDestroy().

> 
> 
>> 
>> Another issue being InjectionTarget#postConstruct() only having the instance T 
>> as well. Now what about @PostConstruct interceptors as defined in the 
>> interceptors spec?

Again, I would expect a proxy to be passed to postConstruct(). Anyway, I'm not sure why you need access to the creational context in the postConstruct()? Here you should just invoke the postConstruct callback, which should create any new dependent objects.

>> Currently we have a dirty hack in OWB to pass over the CreationalContext which 
>> contains the dependent scoped interceptors for our own Producers and 
>> InjectionTargets. But I have no clue yet how that should get implemented if one 
>> plugs in a portable Producer via an Extension ^^
>> 
>> Who is responsible of performing the interception? The Producer? Or must the 
>> instance being handed into already be a Proxy?

The instance returned from produce() should have interceptors and decorators applied.

Please let me know if above makes sense, it took me a while to work out whether what was defined was sane. After quite a lot of thinking + talking to Jozef and Stuart I came to the conclusion it was, but  if you can poke holes then please do!


More information about the cdi-dev mailing list