[jboss-cvs] JBossAS SVN: r111014 - projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Mar 24 01:11:36 EDT 2011


Author: marius.bogoevici
Date: 2011-03-24 01:11:34 -0400 (Thu, 24 Mar 2011)
New Revision: 111014

Modified:
   projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US/Migration_Guide.xml
   projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US/Spring_On_JBoss_Best_Practices.xml
Log:
More content

Modified: projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US/Migration_Guide.xml
===================================================================
--- projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US/Migration_Guide.xml	2011-03-24 01:23:02 UTC (rev 111013)
+++ projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US/Migration_Guide.xml	2011-03-24 05:11:34 UTC (rev 111014)
@@ -5,17 +5,337 @@
 %BOOK_ENTITIES;
 ]>
 <chapter id="Migration_Guide">
-  <title>Migrating examples</title>
+  <title>Migrating applications to JBoss EAP and EWP</title>
 
+  <para>Spring applications that have been designed to run in a servlet
+  container such as Tomcat and Jetty will find an ideal running environment in
+  JBoss Enterprise Web Server. At the same time, more sophisticated
+  environments such as JBoss Enterprise Application Platform and JBoss
+  Enterprise Web Platform offer a wider variety of middleware services such as
+  transaction management, messaging or web service integration. </para>
+
   <para>In this chapter we will illustrate how Spring applications which have
-  been originally designed to run on servlet containers such as Tomcat or
-  Jetty can be migrated to take advantage of the JBoss middleware service
-  support and infrastructure. In order to do so, we will use the sample
-  applications provided by the Spring framework.</para>
+  been originally developed for servlet containers can be migrated to take
+  advantage of the JBoss middleware service support and infrastructure. In
+  order to do so, we will use a few sample applications provided by the Spring
+  framework.</para>
 
   <section>
+    <title>General migration mechanics</title>
+
+    <para>Migrating applications from a servlet container to one of the
+    enterprise platforms is a fairly simple process, which addresses two
+    distinct concerns:</para>
+
+    <itemizedlist>
+      <listitem>
+        <para>ensuring that the applications are compatible with the
+        requirements of the Java EE 5 standard;</para>
+      </listitem>
+
+      <listitem>
+        <para>enabling integration with the middleware services provided by
+        the container;</para>
+      </listitem>
+
+      <listitem>
+        <para>avoiding the inclusion of libraries that are already provided by
+        the application server.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>Except for special situations, migrating applications does not
+    involve changes to the Java code, and the Spring bean configuration
+    definitions that define the business logic of the application: bean
+    wiring, aspect definitions, controllers, etc. The definitions that in
+    almost every case are the ones that relate to the infrastructure:
+    datasources, session factories, entity managers and entity manager
+    factories, connection factories and transaction managers.</para>
+
+    <simplesect>
+      <title>Migrating datasource definitions</title>
+
+      <para>Almost all servlet containers support the usage of JNDI-bound
+      resources, and binding Datasources in JNDI allows for managing
+      connectivity parameters such as URLs, credentials and pool sizes
+      independently from the application code. However, it is quite typical
+      for Spring applications to rely on independent connection pool bean
+      definitions, such as the ones used by commons-dbcp or c3po (see example
+      <xref linkend="dbcp-ref" />).</para>
+
+      <example>
+        <title id="dbcp-def">Example commons-dbcp DataSource definition in a
+        servlet container</title>
+
+        <programlisting>&lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
+  &lt;property name="driverClassName" value="org.postgresql.Driver" /&gt;
+  &lt;property name="url" value="jdbc:postgresql://exampleHost/exampleDatabase" /&gt;
+  &lt;property name="username" value="user" /&gt;
+  &lt;property name="password" value="password" /&gt;
+&lt;/bean&gt;</programlisting>
+
+        <para>JBoss provides simple and efficient way of deploying and
+        maintaining managed datasources (see section <xref
+        linkend="managed_ds" /> for more details and the JBoss EAP 5
+        administration guide on how to deploy the,) which are JNDI-accessible.
+        In order to replace the above defined datasource with a managed,
+        JNDI-accessible datasource, you need to replace the bean definition
+        with a JNDI object reference as in <xref linkend="???" />.</para>
+      </example>
+
+      <example>
+        <title>Using a JBoss managed datasource in Spring</title>
+
+        <programlisting>&lt;jee:jndi-lookup id="dataSource" jndi-name="java:/ExampleDsJndiName" expected-type="javax.sql.DataSource"/&gt;</programlisting>
+
+        <para>Preserving the bean id is important for the case when the bean
+        is injected by name, whereas indicating the expected type specifically
+        is important for @Autowired scenarios.</para>
+      </example>
+    </simplesect>
+
+    <simplesect>
+      <title>Migrating Hibernate SessionFactories to JTA</title>
+
+      <para>Applications running on the JBoss enterprise platforms are
+      encouraged to use JTA for transaction management. In such cases, the
+      infrastructure changes consist of altering the session factory
+      definition to allow for JTA-backed session context and replacing the
+      local Spring-based transction manager with a
+      HibernateTransactionManager.</para>
+
+      <para>Listing <xref linkend="hibernate_sf" /> contains typical bean
+      definitions for the SessionFactory and the transaction manager when used
+      in a servlet container with local Hibernate-based transactions
+      enabled.</para>
+
+      <example>
+        <title>SessionFactory and transaction manager definitions in a servlet
+        environment</title>
+
+        <programlisting>&lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt;
+    &lt;property name="dataSource" ref="dataSource"/&gt;
+    &lt;property name="mappingLocations" value="classpath:**/*.hbm.xml"/&gt;
+    &lt;property name="hibernateProperties"&gt;
+        &lt;value&gt;
+              hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+              hibernate.show_sql=true
+        &lt;/value&gt;
+    &lt;/property&gt;
+&lt;/bean&gt;
+
+&lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;
+    &lt;property name="sessionFactory" ref="sessionFactory"/&gt;
+&lt;/bean&gt;
+</programlisting>
+
+        <para>These definitions can be migrated to use JTA (the datasource is
+        assumed to be a managed datasource, as shown previously).</para>
+      </example>
+
+      <example>
+        <title>JTA-based SessionFactory and transaction manager</title>
+
+        <programlisting>&lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt;
+        &lt;property name="dataSource" ref="dataSource"/&gt;
+        &lt;property name="mappingLocations" value="classpath:**/*.hbm.xml"/&gt;
+        &lt;property name="hibernateProperties"&gt;
+           &lt;value&gt;
+              hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+              hibernate.show_sql=true
+              hibernate.current_session_context_class=jta
+              hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup
+              hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
+           &lt;/value&gt;
+        &lt;/property&gt;
+    &lt;/bean&gt;
+
+&lt;tx:jta-transaction-manager id="transactionManager"/&gt;
+</programlisting>
+
+        <para>Please note the the definitions of the 'sessionFactory' bean is
+        virtually unchanged - the only difference is the addition of the
+        properties required for setting up the JTA-based context management
+        and the transaction manager change.</para>
+      </example>
+    </simplesect>
+
+    <simplesect>
+      <title>Migrating JPA-based applications</title>
+
+      <para>The most important aspect that needs to be taken into account in
+      the case of JPA is that full fledged Java EE 5 environments have certain
+      restrictions regarding what is deployable by the container and what
+      isn't. More specifically, a persistence unit definition contained in a
+      META-INF/persistence.xml file will be automatically deployed by the
+      container, cannot declare a RESOURCE_LOCAL transaction type and must
+      include a JTA datasource reference. </para>
+
+      <para>On the other hand, it is quite common for applications that are
+      deployed in a servlet container to use RESOURCE_LOCAL transactions as
+      shown in example <xref linkend="jpa-servlet-container" />, or even not
+      specify any transaction type (which is equivalent to setting a JTA
+      transaction type, but is ignored when the persistence unit is
+      initialized by Spring and a resource-local model will be used instead).
+      As well, it is atypical for servlet-container based applications to use
+      JTA datasources, as seen in the same example <xref
+      linkend="jpa-servlet-container" />.</para>
+
+      <example id="jpa-servlet-container">
+        <title>A sample persistence unit definition for a servlet-container
+        based application</title>
+
+        <programlisting>&lt;persistence-unit name="examplePU" transaction-type="RESOURCE_LOCAL"&gt;
+      &lt;provider&gt;org.hibernate.ejb.HibernatePersistence&lt;/provider&gt;
+      &lt;properties&gt;
+         &lt;property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/&gt;
+         &lt;property name="hibernate.show_sql" value="true"/&gt;
+         &lt;property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/&gt;
+      &lt;/properties&gt;
+&lt;/persistence-unit&gt;</programlisting>
+      </example>
+
+      <para>A servlet container will not deploy a persistence unit
+      automatically, as a Java EE 5 application server would, therefore Spring
+      applications using JPA will rely on Spring to create the persistence
+      unit by using one of its JPA support factory beans. Furthermore, while
+      in a Java EE 5 application server enrollment in JTA transactions is a
+      requirement, Spring applications running outside Java EE have to set up
+      a resource-local transaction manager as described in example <xref
+      linkend="???" />.</para>
+
+      <example>
+        <title>JPA EntityManagerFactory and transaction setup in a
+        servlet-container based application</title>
+
+        <programlisting>&lt;bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
+      p:dataSource-ref="dataSource"&gt;    
+    &lt;property name="jpaVendorAdapter"&gt;
+      &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
+        p:database="${jpa.database}" p:showSql="${jpa.showSql}"/&gt;
+    &lt;/property&gt;
+&lt;/bean&gt;
+
+
+&lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
+   p:entityManagerFactory-ref="entityManagerFactory"/&gt;
+</programlisting>
+      </example>
+
+      <para>This persistence unit definition, as laid out above, is not
+      compatible with the requirements of Java EE 5 for application containers
+      and will lead to the a deployment failure if found in the typical
+      META-INF/persistence.xml location.</para>
+
+      <para>So, there are a couple of solution for turning this into a an
+      application that can be deployed in JBoss:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>renaming the persistence unit definition file;</para>
+        </listitem>
+
+        <listitem>
+          <para>leaving persistence-unit deployment to JBoss and using JNDI
+          lookup for retrieving entity managers and entity manager
+          factories;</para>
+        </listitem>
+      </itemizedlist>
+
+      <para>When renaming the persistence unit, the alternate location can be
+      provided as a property to the LocalContainerEntityManagerFactoryBean as
+      described in example <xref linkend="jpa-pu-with-alternate-pxml" />. For
+      details using the LocalContainerEntityManagerFactoryBean in JBoss and
+      its implications please refer to the previous chapter.</para>
+
+      <example>
+        <title>LocalContainerEntityManagerFactoryBean with alternate
+        persistence.xml location</title>
+
+        <programlisting id="jpa-pu-with-alternate-pxml">&lt;bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
+   &lt;property name="persistenceXmlLocation" value="classpath*:META-INF/jpa-persistence.xml"/&gt;
+   &lt;!-- other properties (ommitted) --&gt;
+&lt;/bean&gt;</programlisting>
+
+        <para>A more effective approach is converting the persistence.xml
+        definition to a JTA-based model and using JNDI lookup for retrieving
+        the entity manager. For this, you must convert the persistence unit
+        definition as in the following example (please note that it is not
+        necessary to provide values for both 'jboss.entity.manager.jndi.name'
+        and 'jboss.entity.manager.factory.jndi.name', but at least the entity
+        manager or the entity manager factory </para>
+      </example>
+
+      <example>
+        <title>Changing the persistence.xml definition to be Java EE
+        5-compatible</title>
+
+        <programlisting>&lt;persistence-unit name="examplePU"&gt;
+      &lt;jta-data-source&gt;java:/ExampleDsJndiName&lt;/jta-data-source&gt;
+      &lt;properties&gt;
+         &lt;property name="hibernate.show_sql" value="true"/&gt;
+         &lt;property name="jboss.entity.manager.jndi.name" value="java:/example/EntityManager"/&gt;
+         &lt;property name="jboss.entity.manager.factory.jndi.name" value="java:/example/EntityManagerFactory"/&gt;
+      &lt;/properties&gt;
+&lt;/persistence-unit&gt;</programlisting>
+
+        <para>Now, the EntityManagerFactory and or a JTA-synchronized
+        EntityManager can be retrieved from JNDI as follows:<example>
+            <title>EntityManager retrieved by JNDI lookup and JTA transaction
+            manager (works with @Autowired)</title>
+
+            <programlisting>&lt;jee:jndi-lookup id="entityManager" jndi-name="java:/example/EntityManager" expected-type="javax.persistence.EntityManager"/&gt;
+
+
+&lt;tx:jta-transaction-manager/&gt;</programlisting>
+
+            <para>If the original application relied on Spring to inject the
+            EntityManager using the @PersistenceContext annotation into
+            services and DAOs, then going the EntityManager route will require
+            changing the annotation to @Autowired (as the bean is an
+            EntityManager). In such cases, it may be preferrable to look up
+            for the EntityManagerFactory instead, and leave Spring to create
+            the EntityManager.</para>
+
+            <para>A particular concern when migrating JPA-based application is
+            the choice of a JPA provider. While servlet-container-based
+            applications have to include a JPA implementation and specify the
+            nature of the provider explicitely, JBoss EAP uses Hibernate as a
+            JPA provider. <example>
+                <title>EntityManagerFactory retrieved by JNDI lookup and JTA
+                transaction manager (works with @PersistenceContext)</title>
+
+                <programlisting>&lt;jee:jndi-lookup id="entityManager" jndi-name="java:/example/EntityManager" expected-type="javax.persistence.EntityManager"/&gt;
+
+
+&lt;tx:jta-transaction-manager/&gt;</programlisting>
+
+                <para>If the original application relied on Spring to inject
+                the EntityManager using the @PersistenceContext annotation
+                into services and DAOs, then going the EntityManager route
+                will require changing the annotation to @Autowired (as the
+                bean is an EntityManager). In such cases, it may be
+                preferrable to look up for the EntityManagerFactory instead,
+                and leave Spring to create the EntityManager.</para>
+
+                <para>A particular concern when migrating JPA-based
+                application is the choice of a JPA provider. While
+                servlet-container-based applications have to include a JPA
+                implementation and specify the nature of the provider
+                explicitely, JBoss EAP uses Hibernate as the unique JPA
+                provider. In such cases, using an application-server deployed
+                persistence unit will greatly simplify the process.</para>
+              </example></para>
+          </example></para>
+      </example>
+    </simplesect>
+  </section>
+
+  <section>
     <title>Spring's PetClinic</title>
 
+    <para>The PetClinic application is one </para>
+
     <para>The migration of the default Petclinic example to JBoss is fairly
     simple and involves the following steps:</para>
 

Modified: projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US/Spring_On_JBoss_Best_Practices.xml
===================================================================
--- projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US/Spring_On_JBoss_Best_Practices.xml	2011-03-24 01:23:02 UTC (rev 111013)
+++ projects/docs/enterprise/WFK/Spring_Developer_Guide/en-US/Spring_On_JBoss_Best_Practices.xml	2011-03-24 05:11:34 UTC (rev 111014)
@@ -47,7 +47,7 @@
       </listitem>
     </itemizedlist>
 
-    <section>
+    <section id="managed_ds">
       <title>Database access through managed datasources</title>
 
       <para>On JBoss we recommend using managed datasources, which are
@@ -64,7 +64,7 @@
       <example>
         <title>Managed datasource configuration</title>
 
-        <programlisting>&lt;datasources&gt;
+        <programlisting language="xml">&lt;datasources&gt;
    &lt;local-tx-datasource&gt;
 
       &lt;jndi-name&gt;ExampleDsJndiName&lt;/jndi-name&gt;
@@ -82,7 +82,7 @@
       <example>
         <title>Defining a managed datasource Spring bean</title>
 
-        <programlisting lang="xml">&lt;jee:jndi-lookup id="dataSource" jndi-name="java:/ExampleDsJndiName"/&gt;</programlisting>
+        <programlisting lang="xml">&lt;jee:jndi-lookup id="dataSource" jndi-name="java:/ExampleDsJndiName" expected-type="javax.sql.DataSource"/&gt;</programlisting>
       </example>
 
       <para>Such a datasource bean can be injected in any regular Spring bean
@@ -213,9 +213,11 @@
       <para>In general, for implementing transaction-aware components (for
       example a service that delegates to multiple DAOs which have to be
       enrolled in the same transaction), it is not typical to access
-      EntityManagerFactories directly. Rather, components should access the
-      JNDI-bound EntityManager, as it is JTA-synchronized and will be shared
-      with non-Spring components that use JPA as well (e.g. EJBs).</para>
+      EntityManagerFactories directly, even if Spring supports injection into
+      fields annotated with @PersistenceContext if an EntityManagerFactory
+      provided. Rather, components should access the JNDI-bound EntityManager,
+      as it is JTA-synchronized and will be shared with non-Spring components
+      that use JPA as well (e.g. EJBs).</para>
 
       <para>A comprehensive example of using JPA-driven data access in
       Spring-based applications can be found in the Sportsclub demo
@@ -224,12 +226,13 @@
       <para>One important limitation of working with JNDI-bound EntityManagers
       and EntityManagerFactories is the lack of support for read-only
       transactions in Spring. When declaring transactions, Spring applications
-      may specify that the transaction is intended to be read-only:</para>
+      may specify that the transaction is intended to be read-only as in
+      example</para>
 
-      <example>
-        <title>A Spring class declaring a read-only transaction</title>
+      <example id="transactional-method-read-only">
+        <title>A Spring method declaring a read-only transaction</title>
 
-        <programlisting>@Transaction(readOnly = true)
+        <programlisting language="java">@Transaction(readOnly = true)
 public List&lt;Account&gt; getAllAccounts() {
     return entityManager.createQuery("SELECT a FROM Account").getResultList();
 }</programlisting>
@@ -385,7 +388,7 @@
     </section>
   </section>
 
-  <section>
+  <section id="messaging_integration">
     <title>Messaging (JMS) integration</title>
 
     <para>Spring applications have two distinct mechanisms of integrating with
@@ -407,7 +410,8 @@
     linkend="listing-message-driven-pojo" />.</para>
 
     <example id="listing-message-driven-pojo">
-      <title>A message-driven POJO is a simple Java class</title>
+      <title>A message-driven POJO is a simple Java class with a
+      single-argument method</title>
 
       <programlisting>
 public class MessageDrivenPojo
@@ -425,10 +429,10 @@
     <para>Spring provides two dfferent types of MessageListenerContainers:
     'native' JMS and JCA-based. On JBoss AS we recommend using the JCA
     MessageListenerContainer, due to the better integration with the
-    container, in what concerns message delivery and session, connection, and
-    message consumer management. In order to minimize the amount of
-    proprietary code, you can use Snowdrop's namespace support for JMS/JCA
-    integration (see Snowdrop documentation for details).</para>
+    application server in what concerns message delivery and session,
+    connection, and message consumer management. In order to minimize the
+    amount of proprietary code, you can use Snowdrop's namespace support for
+    JMS/JCA integration (see Snowdrop documentation for details).</para>
 
     <example>
       <title>Using the JCA message listener containers and namespace support
@@ -461,32 +465,30 @@
   <section>
     <title>Transaction management</title>
 
-    <para>Transactions are central to data integrity, and using transactions
-    is critical for implementing a robust and reliable applications. The
-    Spring framework In addition to, the transaction manager included with
-    JBoss provides a performance close to native JDBC in single-resource
-    database access scenarios and being XA-capable in multiple-resource
-    scenarios (such as, for example mixing JMa. One of the significant
-    advantages of JTA is integration with other components of the application
-    stack - such as EJBs and third-party components.</para>
-
     <para>Spring provides a declarative transaction model including
     transaction propagation semantics, so that applications can declare
-    various methods as being automatically enrolled in a transaction. We
-    provided an example of doing this in the previous chapter and a more
-    extensive example can be found in the Sportsclub user guide. The model is
-    the same regardless whether the transactions being used are local
-    transactions or JTA transactions. This makes the switch to JTA fairly
-    easy, as the core of the application is the same, the only component that
-    changes being the transaction manager type.</para>
+    transaction boundaries around specific methods either through annotation
+    or via XML. An example using annotations can be found in example <xref
+    linkend="transactional-method-read-only" /> and, more extensively in the
+    Sportsclub demo application (also, consult the user guide). It is
+    important to note that the model is the same regardless whether the
+    transactions being used are local transactions or JTA transactions -
+    Spring will wrap components in a transactional proxy which will delegate
+    to a transaction manager, which is declared separately, as a Spring bean.
+    Through its PlatformTransactionManager abstraction, Spring lets developers
+    to choose between using resource-local transactions or delegating to the
+    transaction manager provided by the application server.</para>
 
-    <para>For JTA in a Spring application, you can simply use the standard
-    Spring JTA transaction manager definition.</para>
+    <para>Transaction support in JBoss Enterprise Application Platform is
+    provided by JBoss Transaction Service, a highly configurable and
+    performant transaction manager. For using the JBoss Transaction Service in
+    a Spring application, you can simply use the standard Spring JTA
+    transaction manager definition.</para>
 
     <example>
       <title>JTA transaction manager definition in Spring</title>
 
-      <programlisting lang="xml">&lt;tx:jta-transaction-manager/&gt;</programlisting>
+      <programlisting lang="xml">&lt;tx:jta-transaction-manager id="transactionManager"/&gt;</programlisting>
     </example>
 
     <para>The use of this transaction manager allows Spring to create JTA
@@ -495,15 +497,233 @@
     use of managed datasources, JTA-integrated session factories or
     container-deployed persistence units and ensures that the underlying
     database connections, sessions and persistence contexts are managed
-    transparently and shared with other components.</para>
+    transparently and shared with other components. One of the strongest
+    arguments in favour of using JTA across the application is that it ensures
+    that all resources involved in a complex operation are enrolled in the
+    same transaction.</para>
 
-    <para>Please note that in the case of message-driven beans, the message
-    handling invocations are already enrolled in a JTA transaction.</para>
+    <simplesect>
+      <title>JTA and database persistence</title>
+
+      <para></para>
+    </simplesect>
+
+    <simplesect>
+      <title>JTA and messaging integration</title>
+
+      <para>As described in <xref linkend="messaging_integration" />, the
+      recommended integration method for receiving JMS messages is through a
+      JCA-endpoint based MessageListenerContainer. The processing of a message
+      (i.e. during the call to the message handling method) is wrapped in a
+      JTA transaction. As a result, any other JTA-aware resources
+      (datasources, entity manager factories, session factories, JMS sessions)
+      will participate in the same transaction.</para>
+
+      <para>Spring's JMS utility classes such as JmsTemplate and even the
+      DefaultMessageListenerContainer support injection with a Spring
+      transaction manager abstraction. By injecting them with the JTA-based
+      implementation defined as previously described, you can ensure that the
+      JMS-based operations are enrolled in JTA transactions as well.</para>
+    </simplesect>
   </section>
 
   <section>
     <title>EJB integration</title>
 
-    <para></para>
+    <para>Although there is a great deal of overlap between EJB and Spring,
+    mixing the two component models together is a frequently encountered
+    scenario. It consists of having components of one type delegating
+    functionality to components of the other type. The best practice is to
+    provide the delegate components via injection, which can happen in any
+    direction (Spring to EJB and EJB to Spring).</para>
+
+    <section>
+      <title>Injecting Spring beans into EJBs</title>
+
+      <para>For JBoss EAP 5 there are two major options of injecting Spring
+      beans into EJBs:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>Using Spring's native support for EJB integration</para>
+        </listitem>
+
+        <listitem>
+          <para>Using Snowdrop</para>
+        </listitem>
+      </itemizedlist>
+
+      <simplesect>
+        <title>Using Spring's native support for EJB integration</title>
+
+        <para>Spring supports injection into EJBs through its
+        SpringBeanAutowiringInterceptor, which honours the @Autowired
+        annotation.</para>
+
+        <example>
+          <title>Injecting a Spring Bean into EJBs using Spring's native
+          support</title>
+
+          <programlisting>@Stateless
+ at Interceptors(SpringBeanAutowiringInterceptor.class)
+public class InjectedEjbImpl implements InjectedEjb {
+
+    @Autowired
+    private SpringBean springBean;
+  
+}</programlisting>
+        </example>
+
+        <para>The injected Spring beans are retrieved from an
+        ApplicationContext located using a ContextSingletonBeanFactoryLocator,
+        which uses a two-step method for locating contexts. It relies on the
+        existence of one or more files named beanRefContext.xml on the
+        classpath (otherwise said, it performs a
+        'classpath*:beanRefContext.xml' lookup), which contains a single
+        application context definition. Example <xref linkend="???" />
+        contains the definition of such a file. </para>
+
+        <example>
+          <title>Simple beanRefContext.xml file used by a
+          ContextSingletonBeanFactoryLocator and the corresponding
+          simpleContext.xml</title>
+
+          <programlisting>&lt;beans&gt;
+    &lt;bean class="org.springframework.context.support.ClassPathXmlApplicationContext"&gt;
+        &lt;constructor-arg value="classpath*:simpleContext.xml" /&gt;
+    &lt;/bean&gt;
+&lt;/beans</programlisting>
+
+          <programlisting>&lt;beans&gt;
+  &lt;bean id="springBean" class="example.SpringBean"/&gt;
+&lt;/beans&gt;</programlisting>
+
+          <para>For more details, including how to customize the behaviour of
+          SpringBeanAutowiringInterceptor, please consult the Spring Framework
+          reference documentation.</para>
+        </example>
+      </simplesect>
+
+      <simplesect>
+        <title>Using Snowdrop</title>
+
+        <para>Snowdrop is a package of JBoss-specific extensions to Spring,
+        which is included with WFK. This section will provide a succint
+        overview on how to inject Spring beans into EJBs using Snowdrop
+        support, for more details and a more elaborate example, please consult
+        the Snowdrop user guide and the Sportsclub demo application.</para>
+
+        <para>Snowdrop supports the bootstrapping of Spring application
+        contexts through its JBoss-specific Spring deployer, which will
+        identify Spring bean configuration files (regular application context
+        XML definitions) which are deployed in the META-INF directory of a
+        deployable module (EAR, WAR, or EJB-JAR) and match a specific pattern
+        (by default, *-spring.xml), will bootstrap ApplicationContexts which
+        are further registered in JNDI under a name which can be configured
+        from within the context definition. </para>
+
+        <example id="spring-deployer-xml">
+          <title>Spring beans configuration file (example-spring.xml)</title>
+
+          <programlisting>&lt;beans&gt;
+  &lt;description&gt;BeanFactory=(MyApp)&lt;/description&gt;
+  &lt;bean id="springBean" class="example.SpringBean"/&gt;
+&lt;/beans&gt;</programlisting>
+        </example>
+
+        <para>Example <xref linkend="spring-deployer-xml" /> contains a
+        minimal Spring bean definition file. The Spring deployer will
+        bootstrap a context that contains a 'springBean' bean and will
+        register it in JNDI under the 'MyApp' name.</para>
+
+        <para>Beans defined in such contexts can be injected into EJBs, by
+        using the Snowdrop-specific SpringLifecycleInterceptor and @Spring
+        annotation.</para>
+
+        <example>
+          <title>Injecting a Spring bean into an EJB using Snowdrop</title>
+
+          <para><programlisting>@Stateless
+ at Interceptors(SpringLifecycleInterceptor.class)
+public class InjectedEjbImpl implements InjectedEjb
+{
+ @Spring(bean = "springBean", jndiName = "MyApp")
+ private SpringBean springBean;
+
+ /* rest of the class definition ommitted */
+}</programlisting></para>
+        </example>
+      </simplesect>
+    </section>
+
+    <section>
+      <title>Accessing EJBs from Spring beans</title>
+
+      <para>Injecting stateless EJBs in Spring components is also possible.
+      There are two possible ways of achieving this:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>EJB reference bean definitions</para>
+        </listitem>
+
+        <listitem>
+          <para>using the @EJB annotation in SpringA</para>
+        </listitem>
+      </itemizedlist>
+
+      <para>EJB references can be defined as Spring beans using the
+      <code>&lt;jee:local-slsb&gt;<code></code>&lt;jee:remote-slsb&gt;</code>
+      elements, as in example </para>
+
+      <example>
+        <title>Definiting an EJB reference as a Spring bean</title>
+
+        <programlisting>&lt;beans xmlns="http://www.springframework.org/schema/beans"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xmlns:jee="http://www.springframework.org/schema/jee"
+   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"&gt;
+
+  &lt;jee:local-slsb id="ejbReference" jndi-name="ejb/exampleEjb"
+      business-interface="example.ExampleEjb/&gt;
+
+  &lt;bean id="consumerBean" class="example.ConsumerBean"/
+
+&lt;/beans&gt;</programlisting>
+
+        <para>The EJB references are regular Spring beans and can be injected
+        as any other Spring beans would.</para>
+      </example>
+
+      <example>
+        <title>Injecting an EJB reference defined as a Spring bean</title>
+
+        <programlisting>public class ConsumerBean {
+
+    @Autowire ExampleEjb exampleEJB;
+
+}</programlisting>
+
+        <para>Spring also supports injection directly with EJB references, as
+        in the following example:</para>
+      </example>
+
+      <example>
+        <title>Injecting an EJB using annotations</title>
+
+        <programlisting>public class ConsumerBean {
+
+    @EJB(mappedName="ejb/exampleEJB")
+    ExampleEjb exampleEJB;
+
+}</programlisting>
+
+        <para>Unlike @EJB references in EJBs, which may not specify a name or
+        mappedName relying upon the container to resolve the reference
+        automatically, @EJB references in Spring beans must specify the JNDI
+        location where the EJB is expected to be found.</para>
+      </example>
+    </section>
   </section>
 </chapter>



More information about the jboss-cvs-commits mailing list