Removed EJB 2.x implementation class hierarchy (ejb.support package)
This commit is contained in:
@@ -265,136 +265,6 @@ public void setMyComponent(MyComponent myComponent) {
|
||||
<section xml:id="ejb-implementation">
|
||||
<title>Using Spring's EJB implementation support classes</title>
|
||||
|
||||
<section xml:id="ejb-implementation-ejb2">
|
||||
<title>EJB 2.x base classes</title>
|
||||
<para>
|
||||
Spring provides convenience classes to help you implement EJBs.
|
||||
These are designed to encourage the good practice of putting business
|
||||
logic behind EJBs in POJOs, leaving EJBs responsible for transaction
|
||||
demarcation and (optionally) remoting.
|
||||
</para>
|
||||
<para>
|
||||
To implement a Stateless or Stateful session bean, or a Message Driven
|
||||
bean, you need only derive your implementation class from
|
||||
<classname>AbstractStatelessSessionBean</classname>,
|
||||
<classname>AbstractStatefulSessionBean</classname>, and
|
||||
<classname>AbstractMessageDrivenBean</classname>/<classname>AbstractJmsMessageDrivenBean</classname>,
|
||||
respectively.
|
||||
</para>
|
||||
<para>
|
||||
Consider an example Stateless Session bean which actually delegates
|
||||
the implementation to a plain java service object. We have the business
|
||||
interface:
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[public interface MyComponent {
|
||||
public void myMethod(...);
|
||||
...
|
||||
}]]></programlisting>
|
||||
<para>We also have the plain Java implementation object:</para>
|
||||
<programlisting language="java"><![CDATA[public class MyComponentImpl implements MyComponent {
|
||||
public String myMethod(...) {
|
||||
...
|
||||
}
|
||||
...
|
||||
}]]></programlisting>
|
||||
<para>And finally the Stateless Session Bean itself:</para>
|
||||
<programlisting language="java"><![CDATA[public class MyFacadeEJB extends AbstractStatelessSessionBean
|
||||
implements MyFacadeLocal {
|
||||
|
||||
private MyComponent myComp;
|
||||
|
||||
/**
|
||||
* Obtain our POJO service object from the BeanFactory/ApplicationContext
|
||||
* @see org.springframework.ejb.support.AbstractStatelessSessionBean#onEjbCreate()
|
||||
*/
|
||||
protected void onEjbCreate() throws CreateException {
|
||||
myComp = (MyComponent) getBeanFactory().getBean(
|
||||
ServicesConstants.CONTEXT_MYCOMP_ID);
|
||||
}
|
||||
|
||||
// for business method, delegate to POJO service impl.
|
||||
public String myFacadeMethod(...) {
|
||||
return myComp.myMethod(...);
|
||||
}
|
||||
...
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
The Spring EJB support base classes will by default create and load
|
||||
a Spring IoC container as part of their lifecycle, which is then available
|
||||
to the EJB (for example, as used in the code above to obtain the POJO
|
||||
service object). The loading is done via a strategy object which is a subclass of
|
||||
<classname>BeanFactoryLocator</classname>. The actual implementation of
|
||||
<classname>BeanFactoryLocator</classname> used by default is
|
||||
<classname>ContextJndiBeanFactoryLocator</classname>, which creates the
|
||||
ApplicationContext from a resource locations specified as a JNDI
|
||||
environment variable (in the case of the EJB classes, at
|
||||
<literal>java:comp/env/ejb/BeanFactoryPath</literal>). If there is a need
|
||||
to change the BeanFactory/ApplicationContext loading strategy, the default
|
||||
<classname>BeanFactoryLocator</classname> implementation used may be overridden
|
||||
by calling the <literal>setBeanFactoryLocator()</literal> method, either
|
||||
in <literal>setSessionContext()</literal>, or in the actual constructor of
|
||||
the EJB. Please see the Javadocs for more details.
|
||||
</para>
|
||||
<para>
|
||||
As described in the Javadocs, Stateful Session beans expecting to be
|
||||
passivated and reactivated as part of their lifecycle, and which use a
|
||||
non-serializable container instance (which is the normal case) will have
|
||||
to manually call <literal>unloadBeanFactory()</literal> and
|
||||
<literal>loadBeanFactory()</literal> from <literal>ejbPassivate()</literal>
|
||||
and <literal>ejbActivate()</literal>, respectively, to unload and reload the
|
||||
BeanFactory on passivation and activation, since it can not be saved by
|
||||
the EJB container.
|
||||
</para>
|
||||
<para>
|
||||
The default behavior of the
|
||||
<classname>ContextJndiBeanFactoryLocator</classname> class is to load an
|
||||
<classname>ApplicationContext</classname> for use by an EJB, and is
|
||||
adequate for some situations. However, it is problematic when the
|
||||
<classname>ApplicationContext</classname> is loading a number of beans,
|
||||
or the initialization of those beans is time consuming or memory
|
||||
intensive (such as a Hibernate <classname>SessionFactory</classname>
|
||||
initialization, for example), since every EJB will have their own copy.
|
||||
In this case, the user may want to override the default
|
||||
<classname>ContextJndiBeanFactoryLocator</classname> usage and use
|
||||
another <classname>BeanFactoryLocator</classname> variant, such as the
|
||||
<classname>ContextSingletonBeanFactoryLocator</classname> which can load
|
||||
and use a shared container to be used by multiple EJBs or other clients.
|
||||
Doing this is relatively simple, by adding code similar to this to the
|
||||
EJB:
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[ /**
|
||||
* Override default BeanFactoryLocator implementation
|
||||
* @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
|
||||
*/
|
||||
public void setSessionContext(SessionContext sessionContext) {
|
||||
super.setSessionContext(sessionContext);
|
||||
setBeanFactoryLocator(ContextSingletonBeanFactoryLocator.getInstance());
|
||||
setBeanFactoryLocatorKey(ServicesConstants.PRIMARY_CONTEXT_ID);
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
You would then need to create a bean definition file named <literal>beanRefContext.xml</literal>.
|
||||
This file defines all bean factories (usually in the form of application contexts) that may be used
|
||||
in the EJB. In many cases, this file will only contain a single bean definition such as this (where
|
||||
<literal>businessApplicationContext.xml</literal> contains the bean definitions for all business
|
||||
service POJOs):
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[<beans>
|
||||
<bean id="businessBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
|
||||
<constructor-arg value="businessApplicationContext.xml" />
|
||||
</bean>
|
||||
</beans>]]></programlisting>
|
||||
<para>
|
||||
In the above example, the <literal>ServicesConstants.PRIMARY_CONTEXT_ID</literal> constant
|
||||
would be defined as follows:
|
||||
</para>
|
||||
<programlisting language="java"><![CDATA[public static final String ServicesConstants.PRIMARY_CONTEXT_ID = "businessBeanFactory";]]></programlisting>
|
||||
<para>
|
||||
Please see the respective Javadocs for the <classname>BeanFactoryLocator</classname> and
|
||||
<classname>ContextSingletonBeanFactoryLocator</classname> classes for more information on
|
||||
their usage.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="ejb-implementation-ejb3">
|
||||
<title>EJB 3 injection interceptor</title>
|
||||
<para>
|
||||
|
||||
Reference in New Issue
Block a user