You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.
Work in progress list of enhancements to javax.enterprise.inject and javax.enterprise.context for the CDI 1.0 maintenance release and CDI 1.1.
The spec should mention that @ScopeType annotations should not have annotation members. Perhaps this should be a definition error. javax.inject.Scope already mentions this.
Injection for static members has a couple of problems:
Nevertheless, there are a couple of great usecases for this:
So we do need to support something here. Perhaps it would be enough to say:
Currently CDI is extremely dependent upon the use of qualifiers for resolving ambiguous dependencies. This is not a bad thing, since too much implicit behavior can result in difficult to trace bugs. However, we should discuss the following:
We can allow a bean to be defined by annotating a constructor @Produces, for example:
@Produces @SessionScoped @Special
Foo(@Special Bar bar) { ... }
A class with a @Producer constructor might not have a normal bean constructor.
An abstract method or interface method could define an alias
for a bean:
@Produces @Foo Baz foo(@Bar Baz bar);
is a shortcut for @Produces @Foo Baz foo(@Bar Baz bar) { return bar; }. And:
@Produces @Foo Baz foo();
is a shortcut for @Produces @Foo Baz foo(@New Baz bar) { return bar; }.
We could allow certain packages/classes to be excluded from bean discovery using globs in beans.xml.
Currently, producers may specialize producers, and regular beans may specialize regular beans. We should allow a producer to specialize a regular bean. The following options seem to work out:
Option 1:
Add a value() to @Specializes.
@Specializes(Foo.class)
@Produces Foo foo(@New Foo foo) { ..... }
Option 2:
Support @Specializes on any injection point annotated @New.
@Produces Foo foo(@Specializes @New Foo foo) { .... }
Currently we allow injected dependent objects to inject an InjectionPoint. We should also allow beans to inject their own Bean (and Module?), and, in the case of dependent objects, the Bean of the object to which they belong (not all dependent objects are injected).
The spec says that you can't have a type variable be a bean type. But we can in theory use InjectionPoint to overcome Java's lack of reified generics, to allow the following:
@Produces @Parameter("")
<T> T getParameter(FacesContext fc, InjectionPoint ip) {
Class<T> type = (Class<T>) ip.getType();
String paramName = ip.getAnnotated().getAnnotation(Parameter.class).value();
//get the parameter value and convert it to the right type
...
}
Note that we would have to think extra-hard before relaxing the complementary restriction that an injection point type may not be a type variable (since then you would need the whole stack of InjectionPoints).
Gavin, last time we discussed injection into entities you considered logger injection as use case. :-) Can we now use this great use case to consider adding injection into entities?
Cheers, RafaĆ
Logging is not enough to justify adding non-static injection to entities, since there are plenty of other ways to get a logger that don't involve messing with the whole already-complex entity lifecycle.
Non-static injection for entities has lots of problems, since entities are not truly container-managed objects:
However, it seems to me that static injection neatly solves some of these problems. So the cost/benefit analysis is quite different. And entities are a third good usecase for static injection. Thanks for noticing this.
Learn more about Weld...
Is it safe to assume you can't inject a value into a static final field? I'm guessing it's a fundamental limitation of Java.
I have a lot of scenarios where I want a semi-constant. I have values I want to expose to static helper methods that will never change once deployed, but we don't necessarily want to have a different compile job for each environment.
For example:
public final MyProjectConstants{ /** Password Based Encryptor w/ 256-bit SHA and 256-bit AES via Bouncy Castle */ public static final String ENCRYPTION_ALGORITHM = "PBEWITHSHA256AND256BITAES-CBC-BC"; }Users may think they want to change the encryption standard based on which environment the war has been deployed to. It would be very unwise on their part, but they are paying the bills and as a result, we must appease them. Essentially, many customers would like to have the power to change properties that really should be static.
Right now, in Spring, I do:
@Component public final MyProjectConstants{ @Autowired public final MyProjectConstants(@Qualifier(name="encryptionAlgorithm") String encryptionAlgorithm){ this.encryptionAlgorithm=encryptionAlgorithm; } public final String encryptionAlgorithm; }...and just don't use static helper methods. TMK, the only alternative is to inject a reference to the MyProjectConstants object into static variable and hope it is never called in a JVM that hasn't initialized my IOC container.
I'm expecting there is no solution to this because Java doesn't have the notion of final static variables that can be initialized on startup instead of compile time, such as with values in a Weld container.
I think the story goes like this: You can set the value of a final field using reflection if you first call setAccessible(true). But since the JVM can inline static finals, it might not actually have the effect you want - some code will keep using the old field value.
See here.
Learn more about Weld...