[cdi-dev] RequestScoped and Injection Points
John D. Ament
john.d.ament at gmail.com
Sat Sep 10 05:14:33 EDT 2011
Well, I think my issue as that it worked the exact way I needed it to work,
so I figured I was fine :-) . Obviously though, I ran into some limitations
with it.
So just to bounce some ideas off you guys; what would be the correct
approach in this case? Assuming that I want it to be taken into account when
resolving injection points, do I need to gather metadata around injection
points and dynamically build producer method impl's that are generated at
deployment type via an extension that did something like:
1. Scan for any injection points that match the type(s) as well as
qualifier(s) that I am interested in.
2. Also understand the scope of the object they are being injected into.
However, it seems like producers are the one thing that you cannot register
at runtime/deployment time. Is this a case where I would need to create
bean instances instead of producer instances?
Thanks for the help guys
John
On Thu, Sep 8, 2011 at 3:25 PM, Pete Muir <pmuir at redhat.com> wrote:
> As Mark says ;-) But from the way I read your comment, I think you've got
> @Nonbinding the wrong way up completely.
>
> On 8 Sep 2011, at 14:54, Mark Struberg wrote:
>
> > @Nonbinding is pretty easy to explain:
> >
> > when comparing Annotations e.g.
> >
> >
> > public Car @Produces @RequestScoped @Status(color="red", quality=3)
> getCarInfo() { return ...
> >
> > and the injection point
> >
> > private @Inject @Status(color="green", quality=3) Car myCar;
> >
> >
> > then all the members of the 2 annotations (color and quality) will be
> checked on equality!
> >
> > But if you mark some of your annotations members with @Nonbinding, then
> they will simply get ignored in the comparison!
> > So if you only like to carry payload data, then use @Nonbinding.
> >
> >
> >
> > This is not only handy for @Qualifier annotations but also e.g. for
> Interceptors and Decorators!
> >
> > It is for example very useful when it comes to InterceptorBindings:
> >
> > Imagine the following annotation:
> >
> > @InterceptorBinding ...
> >
> > public @interface Transactional {
> > javax.ejb.TransactionAttributeType transactionAttributeType;
> > }
> >
> >
> > And since the transactionAttributeType is NOT annotated @Nonbinding, the
> following InterceptorBindings are NOT equals!
> >
> > @Transactional(transactionAttributeType=REQUIRES_NEW)
> > @Transactional(transactionAttributeType=NEVER)
> >
> >
> > Which means that you would need to provide 1 interceptor implementation
> per transactionAttributeType!
> >
> >
> > But if you add @Nonbinding and write
> >
> > @InterceptorBinding ...
> >
> > public @interface Transactional {
> > @Nonbinding javax.ejb.TransactionAttributeType
> transactionAttributeType;
> > }
> >
> > , then 1
> > @Interceptor
> > @Transactional
> > public class MyOnlyOneTransInterceptor {...
> >
> > is perfectly enough.
> >
> > got me?
> >
> > LieGrue,
> > strub
> >
> >
> >> ________________________________
> >> From: John D. Ament <john.d.ament at gmail.com>
> >> To: Pete Muir <pmuir at redhat.com>
> >> Cc: cdi-dev at lists.jboss.org
> >> Sent: Thursday, September 8, 2011 8:21 PM
> >> Subject: Re: [cdi-dev] RequestScoped and Injection Points
> >>
> >>
> >> Pete,
> >>
> >> So, I've always treated Nonbinding as not binding against the parameter,
> treating separate values as separate qualifiers. When using a producer, you
> end up needing separate producers for each value that you want to support.
> This thought is roughly what I was trying to dive through.
> >>
> >> John
> >>
> >>
> >> On Thu, Sep 8, 2011 at 12:19 PM, Pete Muir <pmuir at redhat.com> wrote:
> >>
> >> Oh yes, let me redo it ;-)
> >>>
> >>>
> >>> @Retention(RUNTIME)
> >>> @interface Foo {
> >>>
> >>> String bar();
> >>>
> >>> }
> >>>
> >>> And use it:
> >>>
> >>> @RequestScoped
> >>> class A {
> >>>
> >>> /// Illegal
> >>> @Inject InjectionPoint ip;
> >>>
> >>> }
> >>>
> >>> class B {
> >>>
> >>> @Inject @Foo(bar="baz") A a;
> >>>
> >>> }
> >>>
> >>> class C {
> >>>
> >>> @Inject @Foo(bar="qux") A a;
> >>>
> >>>
> >>> }
> >>>
> >>> And then let's say we have:
> >>>
> >>> @RequestScoped
> >>> class D {
> >>>
> >>> @Inject C c;
> >>> @Inject B b;
> >>>
> >>> }
> >>>
> >>>
> >>> On 8 Sep 2011, at 12:15, John D. Ament wrote:
> >>>
> >>>> I think something's wrong with your example, but I think I get what
> you mean.
> >>>>
> >>>> My point is that if Foo were a qualifier and not just an annotation,
> should they really be the same injected instance?
> >>>
> >>> If "bar" was binding, it would be a different instance, if bar was non
> binding, it would be the same instance.
> >>>
> >>>
> >>>> It seems like @Nonbinding when used in @RequestScoped is irrelevant,
> >>>
> >>> It's not really relevant or irrelevant, it's just orthogonal.
> @Nonbinding affects type bean resolution, which is an orthogonal concept to
> scoping of beans.
> >>>
> >>> But a non binding attribute is still non binding when used with
> @RequestScoped.
> >>>
> >>>
> >>>> but i'm not sure the spec makes this clear (though in actuality I'm
> against that idea that it wouldn't work).
> >>>
> >>> I think we still have a mismatch in understanding here, as really
> @Nonbinding has nothing to do with scoping, which is why the spec doesn't
> call this out.
> >>>
> >>>
> >>>>
> >>>> On Thu, Sep 8, 2011 at 11:59 AM, Pete Muir <pmuir at redhat.com> wrote:
> >>>> No.
> >>>>
> >>>> Continuing my example, I introduce some new annotation (not a
> qualifier):
> >>>>
> >>>> @Retention(RUNTIME)
> >>>> @interface Foo {
> >>>>
> >>>> String bar();
> >>>>
> >>>> }
> >>>>
> >>>> And use it:
> >>>>
> >>>> @RequestScoped
> >>>> class A {
> >>>>
> >>>> /// Illegal
> >>>> @Inject InjectionPoint ip;
> >>>>
> >>>> }
> >>>>
> >>>> class B {
> >>>>
> >>>> @Inject @Bar("baz") A a;
> >>>>
> >>>> }
> >>>>
> >>>> class C {
> >>>>
> >>>> @Inject @Bar("qux") A a;
> >>>>
> >>>> }
> >>>>
> >>>> And then let's say we have:
> >>>>
> >>>> @RequestScoped
> >>>> class D {
> >>>>
> >>>> @Inject C c;
> >>>> @Inject B b;
> >>>>
> >>>> }
> >>>>
> >>>> The *same* instance of A will be injected into B & C when D is
> accessed. The injection points allow access to the Annotated, which reflects
> two different injection points.
> >>>>
> >>>> Not gonna work ;-)
> >>>>
> >>>>
> >>>> On 8 Sep 2011, at 11:40, John D. Ament wrote:
> >>>>
> >>>>> Pete, Mark,
> >>>>>
> >>>>> So I get there is no single injection point, however it should be the
> case that every injection point is declared the same way, no? E.g. they're
> the "same" in the sense that the line of code is the same, but different in
> that they exist in different areas.
> >>>>>
> >>>>> John
> >>>>>
> >>>>> On Wed, Sep 7, 2011 at 8:38 AM, Pete Muir <pmuir at redhat.com> wrote:
> >>>>> For a request scoped bean there is not a single injection point, like
> there is for dependent beans. Say I have a request scoped bean, Bean A.
> >>>>>
> >>>>> I have two other beans, of any scope, Bean B and Bean C.
> >>>>>
> >>>>> If both beans B and C inject A in the same request, then the
> injection point for A is both Bean B and Bean C.
> >>>>>
> >>>>> Furthermore, client proxies mean that bean A is instantiated lazily,
> to solve the circular injection problem, and so has no knowledge of it's
> injection point when actually created.
> >>>>>
> >>>>> On 7 Sep 2011, at 01:10, John D. Ament wrote:
> >>>>>
> >>>>>> CDI Experts
> >>>>>>
> >>>>>> Was wondering if you could help me understand rationale. In request
> scoped objects, when you create a producer method that creates request
> scoped instances, why is there no access to the underlying injection point?
> >>>>>>
> >>>>>> Let's say that you have a qualifier with a single String value
> attribute that is nonbinding; let's say @JmsDestination. You have the
> following injection points:
> >>>>>>
> >>>>>> @Inject @JmsDestination("jms/MyQueue") MessageProducer
> queueProducer;
> >>>>>> @Inject @JmsDestination("jms/MyTopic") MessageProducer
> topicProducer;
> >>>>>>
> >>>>>> In this case, two distinct MessageProducers should be injected. The
> CDI container should be able to differentiate the two, since they have
> different values on the qualifier. However, CDI disallows this since the
> producer methods used to create them would not have access to the injection
> point. If a second injection point is found, CDI should return the same
> instance.
> >>>>>>
> >>>>>> I hope it doesn't sound like I'm babbling, but I wanted to put the
> question out there to see if it's something that could be addressed.
> >>>>>>
> >>>>>> Regards,
> >>>>>>
> >>>>>> John
> >>>>>> _______________________________________________
> >>>>>> cdi-dev mailing list
> >>>>>> cdi-dev at lists.jboss.org
> >>>>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>>>>
> >>>>>
> >>>>
> >>>>
> >>>
> >>>
> >>
> >> _______________________________________________
> >> cdi-dev mailing list
> >> cdi-dev at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>
> >>
> >>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/cdi-dev/attachments/20110910/42ee63d6/attachment-0001.html
More information about the cdi-dev
mailing list