[webbeans-dev] Re: @Supports

Gavin King gavin at hibernate.org
Mon Nov 24 10:57:34 EST 2008


I think @Generic is a better name for this, even though it has nothing
to do with Java generics.

Really we can think of this annotation as being something like the
opposite of @Specializes. So perhaps we should make it also a
web-bean-level construct for consistency, i.e.

* if a web bean is annotated @Generic, *all*
producer/disposal/observer methods are inherited by subclasses
* if a producer method is annotated @Generic, only that producer
method is inherited by subclasses

or maybe that's just confusing...

On Sun, Nov 23, 2008 at 11:39 AM, Gavin King <gavin at hibernate.org> wrote:
> An alternative solution to this problem would be to define the notion
> of a "prototype" producer:
>
>    @ApplicationScoped
>    public class QueueEndpoint  {
>        ...
>
>        @Prototype @Produces Queue getQueue() { ... }
>        @Prototype @Produces getQueueSession() { ... }
>        @Prototype @Produces getQueueSender() { ... }
>        @Prototype @Produces getQueueConnection() { ... }
>
>    }
>
> The effect of the @Prototype annotation would be to define a producer
> method for every Web Bean which has the implementation class
> QueueEndpoint or a subclass. (Without the @Prototype annotation, there
> is exactly one producer method declared.) Each of these producer
> methods would have the same deployment type and binding types as the
> Web Bean with which they are associated.
>
> For example, If I configure a Queue in XML:
>
>    <Queue>
>        <destination>java:/comp/env/jms/PriceQueue</destination>
>        <connectionFactory>...</connectionFactory>
>        <myapp:Prices/>
>    </Queue>
>
> Then I get four producer methods with binding type @Prices.
>
> If I add the following subclass:
>
>    @Staging @Special
>    public class MySpecialQueueEndpoint  extends QueueEndpoint {
>        ...
>    }
>
> Then there would be four new producer methods, each with deployment
> type @Staging and binding type @Special.
>
>
> The advantages of the approach are:
>
> * it avoids introducing a whole new first-level construct
> * it can also be applied to other "non-inherited" constructs (disposal
> and observer methods)
> * it avoids the problem of ambiguous method names
> * types other than interfaces are supported
> * the object returned by the producer method can have any scope
>
> On the downside:
>
> * I think it's slightly more difficult to explain
> * you can't typecast the client proxy between the various types
> * you don't inherit the interceptors of the "owning" Web Bean (good or bad?)
> * it's a bit less dynamic - the producer method is not called for
> every method invocation
> * potential problems when subtypes change the scope of the "owning" Web Bean
>
> On Fri, Nov 14, 2008 at 2:58 PM, Gavin King <gavin at hibernate.org> wrote:
>> I've been thinking about the problem of implementing re-usable
>> components like our JMS endpoints. What I'm trying to do is implement
>> the requirements of JMS endpoints as a simple Web Bean. To do that
>> today, I would need to create a class which implemented all the API
>> types:
>>
>>    @ApplicationScoped
>>    public class QueueEndpoint
>>        implements Queue, QueueSession, QueueSender, QueueConnection { ... }
>>
>> and I would have to go and implement every one of the operations of
>> each of those interfaces to delegate to the correct object. (A bunch
>> of tedious code.)
>>
>> However, if we assume that the client proxy is smart enough, we could
>> let the Web Bean manager automagically do that delegation for us. We
>> would need a new annotation that could be applied to fields or
>> methods, for example:
>>
>>    @ApplicationScoped
>>    public class QueueEndpoint  {
>>        ...
>>
>>        @Supports Queue getQueue() { ... }
>>        @Supports QueueSession getQueueSession() { ... }
>>        @Supports QueueSender getQueueSender() { ... }
>>        @Supports QueueConnection getQueueConnection() { ... }
>>
>>    }
>>
>> We no longer need to write all those annoying delegation methods! The
>> client proxy would just call the correct @Supports method when the
>> QueueEndpoint type did not define the method that was  invoked by the
>> client, and delegate the method to the returned object.
>>
>> To make this really work, we would need to say:
>>
>> * the set of API types of the Web Bean includes all types of @Supports
>> methods/fields
>> * if a certain method name appears on more than one @Supports
>> method/field type, it must also be implemented directly by the impl
>> class
>> * if a certain method name appears on more than one @Supports
>> method/field type, or on both the impl class and a @Supports
>> method/field type, it is always called on the impl class
>>
>> Therefore, close() would need to be implemented by QueueEndpoint:
>>
>>    @ApplicationScoped
>>    public class QueueEndpoint  {
>>        ...
>>
>>        @Supports Queue getQueue() { ... }
>>        @Supports QueueSession getQueueSession() { ... }
>>        @Supports QueueSender getQueueSender() { ... }
>>        @Supports QueueConnection getQueueConnection() { ... }
>>
>>        void close() { throw new UnsupportedOperationException(); }
>>
>>    }
>>
>> You're probably thinking that we can do all this with @Producer
>> methods, however, the semantics are not exactly the same, since the
>> association b/w the producer object and produced object is lost as
>> soon as the producer method returns. Furthermore, @Producer methods
>> aren't really appropriate for 3rd-party reusable objects, since the
>> XML configuration of a producer method is verbose.
>>
>> I don't believe that Web Beans 1.0 absolutely has to have this
>> feature, but I know its useful, and I know that we will implement it
>> in the RI, so I would prefer if it was portable. What do you guys
>> think? Useful? Too much magic? Let me know...
>>
>> Seam already has an extremely primitive/braindead version of this
>> feature, that I've found *extremely* useful when writing reusable
>> components:
>>
>> http://docs.jboss.com/seam/2.1.0.SP1/reference/en-US/html/concepts.html#d0e4283
>>
>> (@Factory is more or less like @Produces, whereas @Unwrap is a really
>> crappy version of @Supports.)
>>
>> --
>> Gavin King
>> gavin.king at gmail.com
>> http://in.relation.to/Bloggers/Gavin
>> http://hibernate.org
>> http://seamframework.org
>>
>
>
>
> --
> Gavin King
> gavin.king at gmail.com
> http://in.relation.to/Bloggers/Gavin
> http://hibernate.org
> http://seamframework.org
>



-- 
Gavin King
gavin.king at gmail.com
http://in.relation.to/Bloggers/Gavin
http://hibernate.org
http://seamframework.org



More information about the weld-dev mailing list