On Apr 8, 2010, at 3:17 PM, Sergiu Dumitriu wrote:
On 04/08/2010 02:21 PM, Vincent Massol wrote:
Hi devs,
Since the JSR330 is now accepted as final and thus as a standard, I'd like to propose
that we modify our component annotations to use it.
+1
Rationale
========
The advantages of using it are:
* Be standard, ie:
** Our components will be able to be re-used by injectors other than ours (Guice for
example)
** Since IDEs will support JSR330 they'll be able to offer features for our code
(auto complete, graph, etc), for ex
http://blogs.jetbrains.com/idea/tag/dependency-injection/
Proposed Changes
===============
Note: JSR330 doesn't specify how components should be bound, hence the need to keep
xwiki-specific metadata for the bindings.
* @Component and @ComponentRole stay unchanged
Except that the package changes, right?
Nope, we keep our annotations for the bindings part since it's not part of the JSR330
spec.
* Deprecate
@Requirement, replaced by @Inject
* Use @Named or application-specific annotations (based on @Qualifier) instead of hints
specified in the @Requirement annotation
* Add new @Role(Class) to specify a dependency role in the case of collections (since
generics are not available using reflection in Java)
@Role will kind of break the "be standard, so supported by other
injectors" motivation. Are you sure there's no way for doing this? Maybe
we should have commented during the standardization process.
Not really, binding is out of scope for JSR330. Here's what they say:
"
This package provides dependency injection annotations that enable portable classes, but
it leaves external dependency configuration up to the injector implementation. Programmers
annotate constructors, methods, and fields to advertise their injectability (constructor
injection is demonstrated in the examples above). A dependency injector identifies a
class's dependencies by inspecting these annotations, and injects the dependencies at
run time. Moreover, the injector can verify that all dependencies have been satisfied
atbuild time. A service locator, by contrast, cannot detect unsatisfied dependencies until
run time.
Injector implementations can take many forms. An injector could configure itself using
XML, annotations, a DSL (domain-specific language), or even plain Java code. An injector
could rely on reflection or code generation. An injector that uses compile-time code
generation may not even have its own run time representation. Other injectors may not be
able to generate code at all, neither at compile nor run time. A "container",
for some definition, can be an injector, but this package specification aims to minimize
restrictions on injector implementations.
"
* Deprecate
@InstantiationStrategy, replaced by @Singleton. We don't need to introduce any other
scope annotations for now.
* Note that the default scope in the JSR330 spec is "per lookup". Since our
default is singleton, we'll need to add @Singleton annotations everywhere we used to
not have anything.
This (@Singleton everywhere) is the biggest inconvenience, but we'll manage.
Yep it'll be a pain.
We also need to update the component tutorial.
Yes, and the Module doc too.
Example
before:
@Component("html")
public class HTMLMacro extends AbstractMacro<HTMLMacroParameters>
{
...
@Requirement
private HTMLCleaner htmlCleaner;
...
@Requirement("xhtmlmacro/1.0")
private PrintRendererFactory xhtmlRendererFactory;
...
@Requirement(role = Transformation.class)
private List<Transformation> transformations = new
ArrayList<Transformation>();
Same example after the change:
@Component("html")
public class HTMLMacro extends AbstractMacro<HTMLMacroParameters>
{
...
@Inject
private HTMLCleaner htmlCleaner;
...
@Inject
@Named("xhtmlmacro/1.0")
private PrintRendererFactory xhtmlRendererFactory;
...
@Inject
@Role(Transformation.class)
private List<Transformation> transformations = new
ArrayList<Transformation>();
Right?
yes (same for Maps).
For the record, note that in Guice the binding is done like this:
bind(new TypeLiteral<Map<GeneticOperator, Double>>() {}).to(...);
See also
http://code.google.com/p/google-guice/source/browse/trunk/src/com/google/in…
Thanks
-Vincent