A lot has happened in the last 5 years in the Java EE world. Developing EJB 2 applications was really hard and as a result a lot of opensource projects appeared addressing these problems. In particular, Spring and Hibernate had a lot of influence.
Spring initially had a clear philosophy of using dependency injection/inversion of control instead of using lookups and singletons (the (in)famous JNDI in EJB2), and of separating the platform from the implementation of the functionality. I.e. no longer tying business functionality to platform interfaces such as SessionBean and EntityBean.
Hibernate on the other hand solved a lot of problems with entity beans, allowing a more object-oriented style of development supporting persistence of (almost) arbitrary structures of objects. Together, Spring and Hibernate identified a lot of pain points in EJB 2 and greatly improved testability and productivity in Java EE.
Now, Java EE standardisation has incorporated many ideas like using dependency injection and Java Persistence API, the latter of which is basically the standardized Hibernate and Toplink API.
Unfortunately, it remains to be seen whether the situation has now really improved. In particular, Spring has become sort of a one-stop-shop for applications and has become a big utility library. In practice, many companies are now really tied to the Spring framework since they use it almost everywhere for everything.
In the Java EE standard there is now EJB 3 which adds dependency injection through some annotations and (optional) XML configuration. Nevertheless, this is also not such a big improvement. In particular, testability of session beans in a standalone environment (one of the main triggers for what happened in the last 5 years) is problematic. Also, from a maintenance point of view, it is difficult to get a grasp of a given EJB 3 application because it requires looking through a lot of different source files to see how the application is tied together. Spring in this regard is more explicit but this quickly leads to a big XML configuration that is also difficult to understand.
Taking a step back, Spring and EJB 3 are trying to solve the same problem of programming to interfaces. In other words, at a particular place in the software I want to use an interface without knowing the implementation and the framework somehow injects the implementation where the interface is expected. This is a generic problem that is also being attacked by other IOC containers like pico container and Guice.
Some of these frameworks have big marketing engines behind them, such as google’s guice, and as a result that framework is also gaining some popularity. Admittedly, Guice and picocontainer are a lot simpler than Spring and a lot more focused in the problems they solve. The unfortunate thing is that these frameworks all work well with a singleton type of approach where, for a given interface, there is precisely one implementation.
Trends, component based development
In parallel, however, it looks like OSGI is gaining a lot of popularity. In particular, there is now a spring source application server based on it, Jonas uses an OSGI kernel, Glassfish v3 will be based on OSGI, IBM Websphere 6.1 uses OSGI, BEA is also using OSGI for some of its products and is investigating integration in its application server, and JBoss is also going in that direction. Not to mention of course Eclipse which is built on Equinox, an OSGI R4 implementation.
I like the component idea. Basically, a component provides a number of interfaces an requires a number of interfaces. Then in a given running system, the provided and required interfaces must be linked together to form an application. A component in this case might be realised through various objects. For example if a component provides two interfaces, then these interfaces can be provided by two distinct objects that are part of the component. As a special degenerate case, supported by existing IOC containers, this corresponds to a single object that implements both interfaces.
Of course, OSGI also allows different versions of the same component to be deployed at a given time in a system. This concept provides a lot more flexibility than an all Guice or all Spring application. In particular, subsystems can be realised as Guice or Spring applications but exposed at a higher level through OSGI bundles or components. In this way, a big monolitic approach where an application has to be all Spring or all Guice can be avoided and this reopens the possibility of traditional software architecture where a system is decomposed into smaller subsystems.
My guess is that an approach like this will eliminate the need for frameworks such as Spring and Guice alltogether since hand-wiring a few objects together in a few lines of code is easy. In my view, frameworks such as Spring and Guice only help if you are creating a big monolithic application.
For this reason, I am currently experimenting with a small IOC container of my own that implements this component concept. Frameworks such as Spring, Guice, and picocontainer do not offer this component concept since they focus on objects and not on components.
At this point I am already using this component concept in my own projects to avoid a Spring nightmare where loads of XML files are loaded in one big application context. As a result, I can now more easily reuse existing Spring configurations as components that are connected to each other through interfaces and not through application contexts. One application of it is testing persistence out of the container which has now become very easy. The next step is diving deep into OSGI and providing an integration of this component concept with OSGI.