As J2EE containers, both Spring and EJB offer the developer powerful features for developing applications. Comparing the features:
Transaction management : EJB must use a JTA transaction manager and supports transactions that span remote method calls. Spring supports multiple transaction environment with JTA, Hibernate, JDO, JDBC, etc and does not support distributed transaction.
Declarative Transaction support : EJB can define transaction in deployment descriptor and can\'t derivatively define rollback behavior. Spring can define transaction in Spring configuration file and can declaratively define rollback behaviour per method and per exception type.
Persistence : EJB supports programmatic bean-managed persistence and declarative container managed persistence. Spring provides a framework for integrating with several persistence technologies, including JDBC, Hibernate, JDO, and iBATIS.
Declarative security : EJB supports declarative security through users and roles and configured in the deployment descriptor. In Spring, no security implementation out of the box. Acegi provides the declarative security framework built on the top of Spring.
Distributed computing : EJB provides container managed remote method calls. Spring provides proxying for remote calls via RMI, JAX-RPC, and web services.