Overall approach
The simplest way to have dependency injection with Apache Sling, and the one used throughout the codebase, is to use the maven-scr-plugin .
You can annotate your java classes and then at build time invoke the SCR plugin, either as a Maven plugin, or as an Ant task.
For instance, to register a servlet you could do the following:
@Component // signal that it's OSGI-managed
@Service(Servlet.class) // register as a Servlet service
public class SampleServlet implements Servlet {
@Reference SlingRepository repository; // get a reference to the repository
}
Specific answers
How do declarative services compare to "traditional" DI like Guice or Spring? Do they solve the same problem or are they geared towards different problems?
They solve the same problem - dependency injection. However (see below) they are also built to take into account dynamic systems where services can appear or disappear at any time.
All OSGI specific solutions I've seen so far lack the concept of scopes for DI. For example, Guice + guice-servlet has request scoped dependencies which makes writing web applications really clean and easy. Did I just miss that in the docs or are these concerns not covered by any of these frameworks?
I haven't seen any approach in the SCR world to add session-scoped or request-scoped services. However, SCR is a generic approach, and scoping can be handled at a more specific layer.
Since you're using Sling I think that there will be little need for session-scoped or request-scoped bindings since Sling has builtin objects for each request which are appropriately created for the current user.
One good example is the JCR session. It is automatically constructed with correct privileges and it is in practice a request-scoped DAO. The same goes for the Sling resourceResolver.
If you find yourself needing per-user work the simplest approach is to have services which receive a JCR Session
or a Sling ResourceResolver
and use those to perform the work you need. The results will be automatically adjusted for the privileges of the current user without any extra effort.
Are JSR 330 and OSGI based DI two different worlds? iPOJO for example brings its own annotations and Felix SCR Annotations seem to be an entirely different world.
Yes, they're different. You should keep in mind that although Spring and Guice are more mainstream, OSGi services are more complex and support more use cases. In OSGi bundles ( and implicitly services ) are free come and go at any time.
This means that when you have a component which depends on a service which just became unavailable your component is deactivated. Or when you receive a list of components ( for instance, Servlet implementations ) and one of them is deactivated, you are notified by that. To my knowledge, neither Spring nor Guice support this as their wirings are static.
That's a great deal of flexibility which OSGi gives you.
Does anybody have experience with building OSGI based systems and DI? Maybe even some sample code on github?
There's a large number of samples in the Sling Samples SVN repository . You should find most of what you need there.
Does anybody use different technologies like Guice and iPOJO together or is that just a crazy idea?
If you have frameworks which are configured with JSR 330 annotations it does make sense to configure them at runtime using Guice or Spring or whatever works for you. However, as Neil Bartlett has pointed out, this will not work cross-bundles.