[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [cdi-dev] Minimal CDI implementation questions
|
1) How does an
InjectionPoint handle an implicit dependency on an owner
class (container class)? For example, when you have a
non-static
Producer method, it can only be called after its owner class
is
instantiated. The Producer's parameters are injection
points, but my
framework also lists the owner class as an injection point,
representing
the "this" parameter that is implicitely needed for calling
a non-static
Producer method. For such an injection point, my
implementation returns
`null` for `getMember()` to indicate the injection point
represents the
owner class. How is this handled in CDI?
In CDI, a producer method/field has to be declared in a
CDI Bean.
And in order to invoke the non-static producer (i.e.
create the bean from it), CDI will need to first instantiate
the bean that it is declared in (the "owner class").
I don't fully follow the scenario you are trying to
describe, are you talking about self injection?
All I can tell is that `getMember()` isn't returning
`null` in any case - it should be either Field,Method or
Constructor (according to javadoc).
What I mean is, when the Producer method is called (I'm calling
Producers using Reflection) the framework supplies this method
with all necessary information to execute the call. In the case
of a non-static Producer method this would necessarily need to
include the instance of the owner class + any parameters.
Perhaps some code helps; this class calls the Producer when its
#create method is called, and the list of injections it receives
contains the instance of the owner class if it is a non-static
producer. The amount of parameters the Producer needs is
therefore the number of injections - 1.
public class MethodObjectFactory<T> implements
Constructable<T> {
private final Method method;
private final boolean isStatic;
public MethodObjectFactory(Method method) {
this.method = method;
this.isStatic = Modifier.isStatic(method.getModifiers());
method.setAccessible(true);
}
@Override
public T create(List<Injection> injections) {
Object[] values = new Object[injections.size() - (isStatic
? 0 : 1)]; // Parameters for method
Object instance = null; // remains null if the Producer
is static
int parameterIndex = 0;
for(Injection injection : injections) {
if(injection.getTarget() instanceof Method) {
values[parameterIndex++] = injection.getValue();
}
else {
instance = injection.getValue(); // injection without
a target, must be the instance for a non-static producer
}
}
return (T)method.invoke(instance, values);
}
}
I was just curious how CDI handles this dependency between a
Producer and its owner CDI Bean -- it doesn't seem to be visible
as an InjectionPoint, whereas in my implementation I saw no reason
to handle it differently -- as far as the framework is concerned,
the owner instance is just another dependency which can be
expressed as an InjectionPoint.
I think however I see that it is not necessary to expose this in
the specification as it is really more of an implementation detail
on how information about the owner instance is passed along when
calling a Producer. I can probably do it in a similar fashion and
align this part with how CDI exposes its InjectionPoints.
2) The BeanAttributes class has a `getQualifiers` method.
Does this
include qualifiers detected in any stereotypes it might be
annotated
with? What's the reasoning behind listing stereotypes
separately?
Similar question for `getScope` although I'm assuming there
that it must
be getting the scope from the stereotype (if present and not
overriden).
Yes, it includes those as well. And if I am not mistaken,
you'd even see any programmatically added annotations there
(i.e. added via extensions).
Yes, that would make sense, thanks for clarifying.
Think of BeanAttributes as a complete view of bean's
metadata.
The reason stereotypes are there is because they are also
a kind of metadata related to a bean and because they can
carry information about its bindings, qualifiers or scope.
And some of its information cannot be found elsewhere due
to inheritance rules - for instance a stereotype can declare
a scope such as @RequestScoped but the bean itself then
declares @ApplicationScoped.
The resulting scope (stored in BeanAttributes) is
@ApplicationScoped and you'd need to introspect the
stereotype to learn that there was some other scope.
Alright, so could you say that the StereoTypes themselves won't
influence decisions made by the injector itself (after the full
set of qualifiers and scope has been determined) -- it can just
look at the types, qualifers and scope for determining valid
candidates and for doing validation/consistency checks of all
detected beans.
The others answers were clear and not entirely unexpected, just
wanted to make sure. Thanks a lot :)
--John