[cdi-dev] Producer#dispose(T instance) and similar
Mark Struberg
struberg at yahoo.de
Mon Dec 10 04:33:29 EST 2012
> My understanding of the spec is that an InjectionTarget is completely
> responsible for building and invoking interceptors and decorators.
That only got added in CDI-1.0. In CDI-1.0 it was _not_ defined.
My point is that this is technically not possible for a _portable_ Producer and InjectionTarget to get it right!
It would need to know exactly:
* how the proxies work, ASF, Javassist, BCEL, etc
* how to store the Interceptors and Decorators in the CreationalContext
* how to _retrieve_ the Interceptors and Decorators our of the CreationalContext again!
I don't think this can be done in a portable way. At least I found no solution so far...
An easy example: The produce(CC) method only has a CreationalContext parameter but not a BeanManager! So how would you e.g. resolve an @ApplicationScoped bean which contains the producer method?
The only solution I can think about is to define that setProducer and setInjectionTarget must only be used to _wrap_ the existing ones.
LieGrue,
strub
----- Original Message -----
> From: Jozef Hartinger <jharting at redhat.com>
> To: Mark Struberg <struberg at yahoo.de>
> Cc: Pete Muir <pmuir at redhat.com>; cdi-dev <cdi-dev at lists.jboss.org>
> Sent: Monday, December 10, 2012 10:23 AM
> Subject: Re: [cdi-dev] Producer#dispose(T instance) and similar
>
> My understanding of the spec is that an InjectionTarget is completely
> responsible for building and invoking interceptors and decorators. The
> produce() method can either return the target object (assuming there are
> no interceptors or decorators) or a proxy that handles interception.
> This is completely transparent to the container.
>
> The instance that the container retrieves from the produce() method is
> then passed to postConstruct(), preDestroy() and dispose() methods. Note
> that if the instance is a proxy it is a client proxy (creating client
> proxies is the container's job, not InjectionTarget's) but rather an
> interceptor/decorator enabling proxy which carries interceptor/decorator
> instances. Therefore, the CreationalContext is not necessary in those
> methods as the instance itself knows how to invoke interceptors/decorators.
>
> HTH,
>
> JH
>
> On 12/07/2012 10:56 PM, Mark Struberg wrote:
>>> 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.
>> I think that would end up being highly non-portable and we must revert this
> 'clarification' as it breaks a lot of stuff!
>>
>> Proxies are the core business of the cdi container! If we allow/force a
> pluggable Producer<T> to handle the interception proxying then this would
> not be possible without knowing implementation details of the respective
> container. This starts with the fact that we need to store the implicitly
> @Dependent scoped Interceptors and Decorators in our CreationalContexts but we
> do _not_ define an API to portably extract Interceptors and Decorators from them
> later.
>>
>>
>> Also this contradicts the need that some functionality like e.g. CDI events
> might be private methods. There is just no way to invoke a private method on a
> proxy whose internal structure you don't know. And doing the interceptors
> via subclassing instead of proxies would break both the EJB and the interceptors
> spec which define that only 'external' calls must get intercepted.
>>
>> LieGrue,
>> strub
>>
>>
>>
>> ----- Original Message -----
>>> From: Pete Muir <pmuir at redhat.com>
>>> To: Mark Struberg <struberg at yahoo.de>
>>> Cc: cdi-dev <cdi-dev at lists.jboss.org>
>>> Sent: Tuesday, December 4, 2012 5:46 PM
>>> Subject: Re: [cdi-dev] Producer#dispose(T instance) and similar
>>>
>>> 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!
>>>
>> _______________________________________________
>> cdi-dev mailing list
>> cdi-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>
More information about the cdi-dev
mailing list