Post Reply 
 
Thread Rating:
  • 1 Votes - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Implementing Stateless Session EJBs with Spring
02-06-2011, 09:11 AM
Post: #1
Implementing Stateless Session EJBs with Spring
Spring provides a abstract base classes you may derive from to make it easier to implement Stateless Session Beans. Aside from reducing the unwanted code you have to write, these classes encourage and actually implementing business logic in POJOs to which the EJBs delegate to, as opposed to in the EJBs themselves. These base classes are AbstractStatelessSessionBean.

This tip will explain you how to write Stateless Session Beans in Spring.

Let's look at the simplest example of Stateless Session Bean possible to be implemented by deriving from AbstractStatelessSessionBean:


public class TestEJB extends AbstractStatelessSessionBean {
}

AbstractStatelessSessionBean classes in the abstract base hierarchy provided by Spring implement all required Session Bean EJB lifecycle methods. In Spring It's necessary to override template methods and not the actual bean life- cycle methods because in the base class hierarchy implement the lifecycle callback methods themselves to provide configuration management. In Spring all the lifecycle methods would have been made final were it not for EJB restrictions.

Let's look at the superclass template methods and other methods that may be called or have to be implemented by your EJB implementation classes. From AbstractEnterpriseBean:

/**
* Subclasses must implement this method to do any cleanup
* they would otherwise have done in an ejbRemove() method.
* This implementation is empty, to be overridden in subclasses.
*/
protected void onEjbRemove() {
// empty
}

From AbstractSessionBean:

[color=#800000]/**
* Sets the session context.
* If overriding this method, be sure to invoke this form of it
* first.
*
*/
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}

protected final SessionContext getSessionContext() {
return sessionContext;
}


From AbstractStatelessSessionBean:


/**
* Subclasses must implement this method to do any initialization
* they would otherwise have done in an ejbCreate() method.
*/
protected abstract void onEjbCreate() throws CreateException;


Now lets look at a real EJB:


public class TestEJB extends AbstractStatelessSessionBean
implements TestService, SessionBean {

// --- statics
public static final String POJO_TEST_ID = "TestService";

protected TestService testService;

protected void onEjbCreate() throws CreateException {
testService= (TestService) getBeanFactory().getBean(POJO_TEST_ID);
}

public String check(String input) {
return testService.check(input);
}
public String check2(String input) {
return testService.check2(input);
}
public String check3(String input) {
return testService.check3(input);
}
}


This version implements the TestService business interface. However, rather than actually implementing business method functionality itself, it delegates method calls to a POJO implementation of that interface. Additionally, it may make migrating away from EJBs much easier because the client can be hooked up directly to the POJO, instead of going through the intermediary EJB. Decoupling business logic from any environmental API EJB or other is usually desirable to promote reusability and achieve a degree of future proofing

The POJO service implementation is obtained from an application context loaded by the base classes; application code simply calls getBeanFactory() to obtain the application context.In the default implementation, the value at the bean-specific JNDI location

java:comp/env/ejb/BeanFactory
Path is treated as the classpath location of an XML application context definition to load.
Let's look at our standard ejb-jar.xml:

<session>
<display-name>TestEJB</display-name>
<ejb-name>TestEJB</ejb-name>
<local-home>com.ejb.TestHomeLocal</local-home>
<local>com.ejb.TestLocal</local>
<ejb-class>com.ejb.TestEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<env-entry>
<env-entry-name>ejb/BeanFactoryPath</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>com/test/beans.xml</env-entry-value>
</env-entry>
</session>


In this definition, there is an EJB environment entry defined for the name ejb/BeanFactoryPath (which the bean will access as java:comp/env/ejb/BeanFactoryPath), with a value of com/test/beans.xml, the application context definition classpath location. Here's the actual definition:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="testService"
class="com.test.LoggingTestService"/>
</beans>


In this case, the only bean defined is the POJO implementation of TestService that the EJB is delegating to. So in the default setup, each EJB may specify its own unique application context definition location, or use the same definition location as another EJB does. However, regardless of where the definition comes from, each actual EJB instance remember that EJBs are pooled by the EJB container will still have its own unique application context instance created when the EJB itself is created.
Find all posts by this user
Quote this message in a reply
Post Reply 


Forum Jump:



Send your comments, Suggestions or Queries regarding this site at info@tutorials4u.net

Copyright © 2010 Tutorials4u.net All Rights Reserved