[cdi-dev] Bean<T> that only qualifies super types?

Martin Kouba mkouba at redhat.com
Fri Aug 7 07:48:40 EDT 2015


Dne 7.8.2015 v 11:43 arjan tijms napsal(a):
> Hi,
>
> On Fri, Aug 7, 2015 at 11:27 AM, Martin Kouba <mkouba at redhat.com> wrote:
>> I believe the bean class should not be abstract. It's not clearly defined
>> but there are some indirect suggestions: abstract class is not a managed
>> bean -> Bean.getBeanClass() returns the bean class of the managed bean...
>> etc.
>
> Hmmm, but it can be an interface right? And the difference between an
> interface and a "pure" abstract class (abstract class with only
> abstract methods) is rather minimal.
>
> The instance that is returned is not abstract (of course), but both a
> producer and a Bean<T> can have interfaces as their "declared"  bean
> Type if I understood correctly.
>
> E.g.
>
> @Produces
> public Interface produce() {
>     return new InterfaceImpl();
> }

No, an interface may be a bean type but not a bean class of a managed 
bean. For producer methods, the getBeanClass() returns the bean class of 
the bean that declares the producer method.

The bean class is defacto an implementation class.

>
> There's nothing wrong with that, is it?
>
> So by extension, is this wrong then?
>
> @Produces
> public Foo produce() {
>     return new FooImpl();
> }

This is OK. But the bean class of this producer is not Foo as mentioned 
above.

>
>
>
>> No, this is not possible. Qualifiers are tied to a bean definition, not to a
>> bean type.
>
> So this would possibly be an enhancement or new feature request then.
>
>
> I did found a workaround though, which seems to work because the Type
> I'd like to hide happens to have generic parameters:
>
> private static class Dummy {}
>
> @Override
> public Set<Type> getTypes() {
>      return new HashSet<Type>(asList(Foo.class,
> ParameterizedTypeImpl(Map.class, new Type[]{Dummy.class,
> Dummy.class})));
> }
>
> With those types the proxy that's generated contains methods for both
> Foo and Map, but because the generic parameters are the private class,
> the client application can never declare an injection point for this
> (certain not accidentally).
>
> Another possible workaround I thought of is using a second Bean<T>
> that only has Foo as its type and is @Dependent scoped, which then
> asks the bean manager for an instance of a qualified Foo (qualifier is
> of a private type). If I'm not mistaken the first Bean<T> would then
> be called and an @RequestScoped proxy would be returned, which the
> second Bean<T> can then return from its create() method.
>
> What do you think, any of these methods have potential unforeseen
> side-effects or are they safe to use?
>
> Kind regards,
> Arjan
>
>
>
>
>
>
>
>>
>>
>>>
>>> Kind regards,
>>> Arjan Tijms
>>> _______________________________________________
>>> cdi-dev mailing list
>>> cdi-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>>>
>>> Note that for all code provided on this list, the provider licenses the
>>> code under the Apache License, Version 2
>>> (http://www.apache.org/licenses/LICENSE-2.0.html). For all other ideas
>>> provided on this list, the provider waives all patent and other intellectual
>>> property rights inherent in such information.
>>>
>>
>> --
>> Martin Kouba
>> Software Engineer
>> Red Hat, Czech Republic

-- 
Martin Kouba
Software Engineer
Red Hat, Czech Republic


More information about the cdi-dev mailing list