Spring and EJB3
On the surface it may seem that EJB 3.0 (in particular session beans) covers the same area as Spring’s Lightweight Container. However, when you look closer, you’ll notice some important differences with regards to the two, both in terms of focus and capabilities.
EJB3 provides dependency injection for JNDI objects. All referenced objects need to be managed by the application server in JNDI. This is only appropriate for coarse-grained facades, as there is no value in letting the application server manage every single internal object of your application. Essentially, EJB3’s dependency injection capabilities are targeted at making JNDI lookups more convenient, but do not go beyond that.
In contrast to the above, Spring is designed for managing fine-grained application objects in a local fashion, without making the application server aware of each and every object. You can link in objects from JNDI if you need to, but most of your application objects are not (nor should be) managed by the server. Furthermore, Spring supports prototypes, constructor injection, factory methods, simple property values, value placeholders (variable configuration properties sourceable from external locations), control over bean lifecycle (lazy-init, disposal, pooling), and bean autowiring.
The most important difference is that Spring can seamlessly manage application objects in any environment, while EJB3 just allows you to run them in an EJB container. In a test environment or standalone environment, the best you can do with EJB3 is instantiate the session beans yourself. With Spring, you’ll just select a different context implementation, typically sourced from the same XML bean definitions. This means you can reuse configuration metadata across environments with minimal hassel.
Beyond those basic IoC capabilities, Spring offers full support for proxy-based AOP with prebuilt and custom interceptors, while EJB3 offers its fixed set of interceptors (transaction, security). Furthermore, Spring’s declarative transactions are backed by various transaction strategies (DataSource/JDBC, Hibernate, JTA, JOTM), working outside of J2EE too. There’s also support for a wide variety of data access strategies (JDO, OJB, JDBC, all using a consistent programming model, while EJB3 just integrates a single strategy). If you haven’t guessed by now, Spring’s mantra is, “it’s all about choice”.
We’ve not even touched Spring’s web support yet, which range from basic web application context support to its own web MVC and web flow framework and prebuilt Struts/JSF integrations, all able to seamlessly reference middle tier beans. There’s also support for lightweight remoting with various strategies (Hessian, HTTP Invoker, Burlap, JAX-RPC, JMX) using a common service export facility, rather than the (unknown?) set of protocols that a particular EJB server implementation may offer.
Spring in an EJB3 Scenario
In many respects, Spring and EJB 3.0 complement each other more than they compete. Like it currently does for EJB 2.x, Spring will be able to link in EJB3 session beans seamlessly (local or remote), and will provide internal contexts for EJB3 session and message-driven bean implementations (holding a Spring bean factory within an EJB).
In such an EJB3 scenario, Spring manages the application objects in the web tier (no matter which web MVC framework is being used), accessing coarse-grainded EJB facades when necessary, and potentially also finer-grained objects behind those facades (for example, business logic strategies and DAOs, using JDBC, JDO, Hibernate, etc). Spring still acts as the glue for the entire application, just now with EJB3 session beans thrown into the mix.
Beyond EJB3 session beans, Spring will also support the new persistence API defined by JSR-220 (formerly known as EJB3 entity beans), as a further O/R mapping strategy, in addition to the current support for Hibernate, JDO, OJB, and iBATIS SQL Maps. Note: this will be completely
independent from the rest of EJB3–you could easily manage your entire middle tier with Spring, using a JSR-220 persistence implementation in standalone.
EJB3 in a Spring Scenario
I hope the above answers why it still adds value to use Spring in an EJB3 scenario. Of course, we can also turn the question around: What value is added by EJB3 session beans to a Spring scenario? (JSR-220 persistence is a different matter: It’s an alternative to Hibernate and JDO, not to Spring.)
In principle, Spring covers all capabilities of EJB3 session beans today, offering more flexible and more sophisticated management and deployment options. The main benefit with modelling components as EJBs is that you’re able to export remote services through your J2EE server (to support load balancing and failover).
For purely local needs, there appears no compelling reason to choose EJB3 session beans over Spring-managed POJOs, except for one specific
scenario: You might want to deploy some of your components in a separate class loader within an EAR, making them accessible to multiple web applications. In such a case, using local EJBs as facades makes sense, possibly with fine-grained networks of Spring-managed application objects behind them.
Juergen Hoeller, co-lead, The Spring Framework