
POJO Application Frameworks: Spring Vs. EJB 3.0
Pages: 1, 2
Declarative Services
Spring and EJB 3.0 wire runtime services (such as transaction, security, logging, messaging, and profiling services) to applications. Since those services are not directly related to the application's business logic, they are not managed by the application itself. Instead, the services are transparently applied by the service container (i.e., Spring or EJB 3.0) to the application at runtime. The developer (or administrator) configures the container and tells it exactly how/when to apply services.
EJB 3.0 configures declarative services using Java annotations, while Spring uses XML configuration files. In most cases, the EJB 3.0 annotation approach is the simpler and more elegant way for this type of services. Here is an example of applying transaction services to a POJO method in EJB 3.0.
public class Foo {
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public bar () {
// do something ...
}
}
You can also declare multiple attributes for a code segment and apply multiple services. This is an example of applying both transaction and security services to a POJO in EJB 3.0.
@SecurityDomain("other")
public class Foo {
@RolesAllowed({"managers"})
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public bar () {
// do something ...
}
}
Using XML to specify code attributes and configure declarative
services could lead to verbose and unstable configuration files.
Below is an example of XML elements used to apply a very simple
Hibernate transaction to the Foo.bar()
method in a
Spring application.
<!-- Setup the transaction interceptor -->
<bean id="foo"
class="org.springframework.transaction
.interceptor.TransactionProxyFactoryBean">
<property name="target">
<bean class="Foo"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">
<ref bean="attributeSource"/>
</property>
</bean>
<!-- Setup the transaction manager for Hibernate -->
<bean id="transactionManager"
class="org.springframework.orm
.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<!-- you need to setup the sessionFactory bean in
yet another XML element -- omitted here -->
<ref bean="sessionFactory"/>
</property>
</bean>
<!-- Specify which methods to apply transaction -->
<bean id="transactionAttributeSource"
class="org.springframework.transaction
.interceptor.NameMatchTransactionAttributeSource">
<property name="properties">
<props>
<prop key="bar">
</props>
</property>
</bean>
The XML complexity would grow geometrically if you added more
interceptors (e.g., security interceptors) to the same POJO.
Realizing the limitations of XML-only configuration files, Spring
supports using Apache Commons metadata to specify transaction
attributes in the Java source code. In the latest Spring 1.2, JDK-1.5-style annotations are also supported. To use the transaction
metadata, you need to change the above
transactionAttributeSource
bean to an
AttributesTransactionAttributeSource
instance and add
additional wirings for the metadata interceptors.
<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy
.DefaultAdvisorAutoProxyCreator"/>
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor
.AttributesTransactionAttributeSource"
autowire="constructor"/>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor
.TransactionInterceptor"
autowire="byType"/>
<bean id="transactionAdvisor"
class="org.springframework.transaction.interceptor
.TransactionAttributeSourceAdvisor"
autowire="constructor"/>
<bean id="attributes"
class="org.springframework.metadata.commons
.CommonsAttributes"/>
The Spring metadata simplifies the
transactionAttributeSource
element when you have many
transactional methods. But it does not solve the fundamental
problems with XML configuration files--the verbose and
fragile transaction interceptor, transactionManager
,
and transactionAttributeSource
are all still
needed.
Dependency Injection
A key benefit of middleware containers is that they enable developers to build loosely coupled applications. The service client only needs to know the service interface. The container instantiates service objects from concrete implementations and make them available to clients. This allows the container to switch between alternative service implementations without changing the interface or the client-side code.
The Dependency Injection pattern is one of best ways to implement loosely coupled applications. It is much easier to use and more elegant than older approaches, such as dependency lookup via JNDI or container callbacks. Using DI, the framework acts as an object factory to build service objects and injects those service objects to application POJOs based on runtime configuration. From the application developer's point of view, the client POJO automatically obtains the correct service object when you need to use it.
Both Spring and EJB 3.0 provide extensive support for the DI pattern. But they also have some profound differences. Spring supports a general-purpose, but complex, DI API based upon XML configuration files; EJB 3.0 supports injecting most common service objects (e.g., EJBs and context objects) and any JNDI objects via simple annotations.
The EJB 3.0 DI annotations are extremely concise and easy to
use. The @Resource
tag injects most common service
objects and JNDI objects. The following example shows how to inject
the server's default DataSource
object from the JNDI
into a field variable in a POJO. DefaultDS
is the
JNDI name for the DataSource
. The myDb
variable is automatically assigned the correct value before its
first use.
public class FooDao {
@Resource (name="DefaultDS")
DataSource myDb;
// Use myDb to get JDBC connection to the database
}
In addition to direct field variable injection, the
@Resource
annotation in EJB 3.0 can also be used to
inject objects via a setter method. For instance, the following
example injects a session context object. The application never
explicitly calls the setter method--it is invoked by the
container before any other methods are called.
@Resource
public void setSessionContext (SessionContext ctx) {
sessionCtx = ctx;
}
For more complex service objects, special injection annotations
are defined. For instance, the @EJB
annotation is used
to inject EJB stubs and the @PersistenceContext
annotation is used to inject EntityManager
objects,
which handle database access for EJB 3.0 entity beans. The
following example shows how to inject an EntityManager
object into a stateful session bean. The
@PersistenceContext
annotation's type
attribute specifies that the injected EntityManager
has an extended transaction context--it does not automatically
commit with the JTA transaction manager, and hence it can be used in
an application transaction that spans across multiple threads in a
session.
@Stateful
public class FooBean implements Foo, Serializable {
@PersistenceContext(
type=PersistenceContextType.EXTENDED
)
protected EntityManager em;
public Foo getFoo (Integer id) {
return (Foo) em.find(Foo.class, id);
}
}
The EJB 3.0 specification defines server resources that can be injected via annotations. But it does not support user-defined application POJOs to be injected into each other.
In Spring, you first need to define a setter method (or constructor with arguments) for the service object in your POJO. The following example shows that the POJO needs a reference to the Hibernate session factory.
public class FooDao {
HibernateTemplate hibernateTemplate;
public void setHibernateTemplate (HibernateTemplate ht) {
hibernateTemplate = ht;
}
// Use hibernateTemplate to access data via Hibernate
public Foo getFoo (Integer id) {
return (Foo) hibernateTemplate.load (Foo.class, id);
}
}
Then, you can specify how the container gets the service object
and wire it to the POJO at runtime through a chain of XML elements.
The following example shows the XML element that wires a data
source to a Hibernate session factory, the session factory to a
Hibernate template object, and finally, the template object to the
application POJO. Part of the reason for the complexity of the
Spring code is the fact that we need to inject the
underlying Hibernate plumbing objects manually, where the EJB
3.0 EntityManager
is automatically managed and
configured by the server. But that just brings us back to the
argument that Spring is not as tightly integrated with services
as EJB 3.0 is.
<bean id="dataSource"
class="org.springframework
.jndi.JndiObjectFactoryBean">
<property name="jndiname">
<value>java:comp/env/jdbc/MyDataSource</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm
.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="hibernateTemplate"
class="org.springframework.orm
.hibernate.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="fooDao" class="FooDao">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate"/>
</property>
</bean>
<!-- The hibernateTemplate can be injected
into more DAO objects -->
Although the XML-based Dependency Injection syntax in Spring is complex, it is very powerful. You can inject any POJO, including the ones defined in your applications, to another POJO. If you really want to use Spring's DI capabilities in EJB 3.0 applications, you can inject a Spring bean factory into an EJB via the JNDI. In some EJB 3.0 application servers, the vendor might define extra non-standard APIs to inject arbitrary POJOs. A good example is the JBoss MicroContainer, which is even more generic than Spring, as it handles Aspect-Oriented Programming (AOP) dependencies.
Conclusions
Although Spring and EJB 3.0 both aim to provide enterprise services to loosely coupled POJOs, they use very different approaches to archive this goal. Dependency Injection is a heavily used pattern in both frameworks.
With EJB 3.0, the standards-based approach, wide use of annotations, and tight integration with the application server all result in greater vendor independence and developer productivity. With Spring, the consistent use of dependency injection and the centralized XML configuration file allow developers to construct more flexible applications and work with several application service providers at a time.
Acknowledgments
The author would like to thank Stephen Chambers, Bill Burke, and Andy Oliver for valuable comments.
Resources
- The Spring framework (see also CodeZoo: Spring)
- EJB 3.0
- JBoss EJB 3.0
- Oracle Application Server EJB 3.0 Preview
Michael Juntao Yuan specializes in lightweight enterprise / web application, and end-to-end mobile application development.
Return to ONJava.com.

-
oranges and mortgages
2008-12-04 05:53:42 simbo1905 [View]
-
And then came the POJO Application Server
2008-06-17 07:58:42 Gate_Crasher [View]
-
Spring AOP vs EJB 3.0 Interceptors
2007-05-23 13:51:53 DenverDeveloper [View]
-
Spring ROCKS
2007-01-12 08:39:37 kurtrisser [View]
-
POJO is not EJB, but EJB is POJO?
2005-12-08 15:01:14 why_pojo [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-11-01 11:39:07 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:55:03 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:53:03 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:51:05 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:50:04 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:49:05 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:48:03 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:47:04 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:45:09 [View]
- Trackback from http://vmsfconf/display/DBAE/Guide+to+Hibernate+integration
Guide to Hibernate integration
2005-10-31 19:45:05 [View]
-
silver bullets
2005-09-04 14:32:44 henderson_mk [View]
- Trackback from http://blog.csdn.net/shiningstone/archive/2005/08/17/456274.aspx
POJO应用框架:Spring Vs. EJB 3.0(翻译文章,原创)
2005-08-16 10:08:04 [View]
- Trackback from http://d.hatena.ne.jp/nobusue/20050808#p2
[IT]POJO Application Frameworks: Spring Vs. EJB 3.0(from OnJava)
2005-08-07 20:17:14 [View]
-
annotation better than XML file?!
2005-07-25 14:07:38 timjowers [View]
-
Comments from a Friend of Michael's
2005-07-19 06:55:06 JTigger [View]
-
opinion piece veiled as objective article
2005-07-14 21:00:04 TrevorS [View]
-
opinion piece veiled as objective article
2006-02-22 07:28:10 steve--o [View]
-
opinion piece veiled as objective article
2008-01-10 11:53:22 Rick010 [View]
-
opinion piece veiled as objective article
2008-05-06 22:50:02 HumbleMan [View]
-
opinion piece veiled as objective article
2005-07-15 06:51:38 MichaelYuan [View]
-
opinion piece veiled as objective article
2005-07-26 19:59:47 TrevorS [View]
-
Fatally Flawed Article
2005-07-12 00:32:15 rodmac [View]
-
Fatally Flawed Article
2005-07-12 00:56:43 MichaelYuan [View]
-
But yet you work for JBoss?
2005-07-08 02:31:59 komatiberry [View]
-
But yet you work for JBoss?
2005-07-09 23:17:58 MichaelYuan [View]
-
Spring and EJB3.0. share commonality but they are not the same thing.
2005-07-07 11:32:43 TS133T [View]
-
Spring and EJB3.0. share commonality but they are not the same thing.
2005-08-17 10:56:07 pankajtandon [View]
- Trackback from http://blog.csdn.net/imperman/archive/2005/07/05/414951.aspx
POJO Application Frameworks: Spring Vs. EJB 3.0
2005-07-05 06:16:24 [View]
- Trackback from http://blogs.application-servers.com/roller/page/moussaud/20050704#ejb3_vs_spring_la_suite
EJB3 vs Spring...la suite
2005-07-05 00:47:47 [View]
-
Spring and/or EJB3
2005-07-02 21:49:36 markstg [View]
-
Spring and/or EJB3
2005-07-03 22:39:02 MichaelYuan [View]
-
Spring and/or EJB3
2006-10-05 11:27:24 mrpantsuit [View]
-
Misses the mark on Spring
2005-07-02 18:09:57 RHassel [View]
-
Misses the mark on Spring
2005-07-03 22:49:17 MichaelYuan [View]
-
Misses the mark on Spring
2006-10-05 11:37:52 mrpantsuit [View]
- Trackback from http://sbserve/DotText/walterr/archive/0001/01/01/6984.aspx
POJO Application Frameworks: Spring Vs. EJB 3.0
2005-06-30 14:44:26 [View]
- Trackback from http://sbserve/DotText/walterr/archive/2005/07/01/6984.aspx
POJO Application Frameworks: Spring Vs. EJB 3.0
2005-06-30 14:43:38 [View]
-
A bit on the diagonal ...
2005-06-30 12:57:02 Bill Siggelkow |[View]
-
A bit on the diagonal ...
2005-06-30 21:53:49 MichaelYuan [View]
-
Another benefit of EJB 3.0
2005-06-30 10:15:03 whartung [View]
-
Another benefit of EJB 3.0
2005-06-30 22:00:02 MichaelYuan [View]
-
Wrong
2005-06-30 08:04:59 yetanotherchristypedude [View]
-
Wrong
2005-06-30 09:30:07 MichaelYuan [View]
-
Will EJB 3.0 run in any Servlet Container?
2005-06-30 06:22:59 Julian-Garcia [View]
