|
How to use Spring and EJB together
It is well documented that you can
use spring framework and EJBs in the same application. Let me quickly outline
how this is done:
As you can see in the figure
above,
- ALL the business methods are defined in a so called
business interface, which is a Plain Old Java Interface (POJI). This
interface is extended by both remote and local interfaces of the EJB and
hence the bean gets the business methods as EJB methods
- The bean also implements the business interface and
is forced to define implementation of all the business methods. Within the
implementation of the business methods, the bean class simply delegates
the method call to MyPOJO
- MyPOJO is a java class, which implements the business
interface and provides the implementations of the business methods. This
allows for easy testing of business methods by invoking POJO outside the
container
- The bean class maintains an instance variable of type
MyBizInterface. The underlying implementation (POJO) of this interface is
provided by spring. When a business method is invoked on the bean class,
the bean class delegates the method call to the POJO. Like this:
//
AbstractStatelessSessionBean is spring framework provided bean
MyBean extends
AbstractStatelessSessionBean implements MyBizInterface{
// instance variable of type business
interface (uses POJO at runtime)
private MyBizInterface myService;
// wire ejb bean with POJO on ejbCreate()
protected void onEJBCreate () throws
CreateException{
// try catch and other code ignored for
simplicity
// getBeanFactory() and getBean() are
defined in the super class
myService = (MyBizInterface)
getBeanFactory().getBean("ServiceNameDefinedInSpringFile");
}
// this method must be implemented because
the bean class implements the
// business interface
public void bizMethod (){
// delegate to POJO
myService.bizMethod();
}
}
The problems
When you add a business method,
you have to add it to both bean class and the POJO. There are two problems with
this approach as I see it:
- The bean class doesn't really need to implement the
business interface. The only purpose implementing the business interface
serves is that it forces the bean class to implement the business method.
This doesn't accomplish anything because you would have implemented all
business methods (and delegated to POJO) in the bean class anyway
- According to EJB specification, the business methods
defined in the remote interface must throw
java.rmi.RemoteException. The specification also states that the business
methods defined in the local interface must NOT throw
RemoteException. Since we use one business interface to define methods for
both local and remote interfaces, we cannot meet both the requirements.
Currently (in WebSphere), if you declare methods in the local interface to
throw RemoteException, you only get warning but it's still violation of
the specification
No problem when using EJB 3.0
specification
Per section 3.3 of simplified EJB
specification, "...the methods of the business interface should not
throw the java.rmi.RemoteException, even if the interface is a remote business
interface..." In this case, the business interface will simply need to
define the business methods (without any exceptions) and remote and local
interface need to extend the business interface.
|