There are lots of standards and frameworks which define their own custom injection points via annotations. Here's a few off the top of my head; I'm sure there's many more out there...
JSR 250 & EJB3 defines @Resouce for injecting objects from JNDI JPA defines @PersistenceContext for injecting JPA resources usually prebound to a transaction context etc JAX-RS defines a number of them such as @PathParam, @HeaderParam, @Context etc WebBeans defines @In Spring defines @Autowired and a few others Stripes defines @SpringBean Apache Camel defines @EndpointInject and @Produces Now you could just say, heck we should scrap all those specs and frameworks and just use Guice for everything!! :) But being able to use Guice as the DI framework for any of the above would be very cool IMHO. Now with the recent Constructor Interceptor code... http://code.google.com/p/google-guice/issues/detail?id=78 its possible for any framework to implement these injection points themselves; however each framework will end up re-implementing the same kinda code that Guice already does (walking through all the fields/methods looking for injection points and then doing the reflection stuff etc); plus this would be kinda outside of Guice's knowledge of the bindings & injection points so one day tooling/validation in Guice wouldn't be aware of these custom injection points and the handling & reporting of errors would probably be inconsistent across the various frameworks. So I've been wondering about adding a *small* SPI hook in Guice to allow framework developers to create custom annotation based injection points. i.e. registering in the Binder that an annotation creates a custom injection point on a member (field/method). Then other frameworks can just reuse the Guice injection mechanism; plus then Guice is aware of all of the injection points in its model. I've taken a stab at creating a patch; it turned out to be relatively easy - I've just modified InjectionPoint ever so slightly to be aware of both the standard @Inject injection points and custom injection points. I'll just walk through how it all works - comments most welcome. Firstly to create a custom injection point you create an implementation of a new SPI interface called AnnotationProviderFactory; this class is then annotated with the annotation type that is used as the custom injection point (which allows us to setup the injection points before we start injecting anything which avoids recursive injection etc). For example here's an implementation of @Resource from JSR 250... @InjectionAnnotation(Resource.class) public class ResourceProviderFactory<T> implements AnnotationProviderFactory<T> { private final Context context; @Inject public ResourceProviderFactory(Context context) { this.context = context; } public Provider<T> createProvider(AnnotatedElement member) { Resource resource = member.getAnnotation(Resource.class); Objects.nonNull(resource, "@Resource is missing!"); String name = getJndiName(resource, member); return new Provider<T>() {...} } } Then if this class is bound into a Binder, Guice will detect that this is an AnnotationProviderFactory and associate it with all fields and methods annotated with @Resource and then use the AnnotationProviderFactory's Provider to create instances from the member. The nice thing is, the AnnotationProviderFactory can be injected itself using the regular Guice approach - in the above case a JNDI context is injected. There are cases where frameworks try and integrate with Guice doing some of the injections themselves and guice doing the rest; I'm hoping through this approach we can just let Guice do all of the injections in a single, consistent way with Guice being aware of all of the injection points for tooling/validation/reporting purposes. This can also solve issues that arise on the join between the IoC framework and the underlying framework - e.g. with JAX-RS doing constructor injection with some injections being Guice and others being JAX-RS based injections. The same is true in other JSR 250/Spring/EJB3/JPA style situations too. Here's the first cut of a patch... http://code.google.com/p/google-guice/issues/detail?id=258 in terms of code changes its fairly simple; we just pass in another parameter (the custom injection points) to a number of InjectionPoint related methods - and then the InjectionPoint can now store an optional AnnotationProviderFactory if it defines a custom injection point (as opposed to being a regular @Inject injection point). Folks who just use 'vanilla' guice probably won't see what all the fuss is about this patch; but folks who want to work with JSR 250 / EJB3 / JPA / JAX-WS / JAX-RS / Spring beans / Stripes / Camel will find this patch really useful (I know I do :); making it super simple to add to a Binder custom injection points to implement most annotation based specifications and frameworks around today easily in Guice with minimal coding. Thoughts? -- James ------- http://macstrac.blogspot.com/ Open Source Integration http://open.iona.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/google-guice?hl=en -~----------~----~----~----~------~----~------~--~---
