Move classic aop-api chapter to appendix Move JMS 1.0.2 related documentation to appendix Remove references to Commons Annotations and source level metadata abstraction Fix program highlighting issue in beans.xml
454 lines
21 KiB
XML
454 lines
21 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
|
<appendix id="classic-spring">
|
|
<title>Classic Spring Usage</title>
|
|
|
|
<para>This appendix discusses some classic Spring usage patterns as a
|
|
reference for developers maintaining legacy Spring applications. These usage
|
|
patterns no longer reflect the recommended way of using these features and
|
|
the current recommended usage is covered in the respective sections of the
|
|
reference manual.</para>
|
|
|
|
<section id="classic-spring-orm">
|
|
<title>Classic ORM usage</title>
|
|
|
|
<para>This section documents the classic usage patterns that you might
|
|
encounter in a legacy Spring application. For the currently recommended
|
|
usage patterns, please refer to the <xref linkend="orm" /> chapter.</para>
|
|
|
|
<section id="classic-spring-hibernate">
|
|
<title>Hibernate</title>
|
|
|
|
<para>For the currently recommended usage patterns for Hibernate see
|
|
<xref linkend="orm-hibernate" /></para>
|
|
|
|
<section id="orm-hibernate-template">
|
|
<title>The <classname>HibernateTemplate</classname></title>
|
|
|
|
<para>The basic programming model for templating looks as follows, for
|
|
methods that can be part of any custom data access object or business
|
|
service. There are no restrictions on the implementation of the
|
|
surrounding object at all, it just needs to provide a Hibernate
|
|
<interfacename>SessionFactory</interfacename>. It can get the latter
|
|
from anywhere, but preferably as bean reference from a Spring IoC
|
|
container - via a simple
|
|
<methodname>setSessionFactory(..)</methodname> bean property setter.
|
|
The following snippets show a DAO definition in a Spring container,
|
|
referencing the above defined
|
|
<interfacename>SessionFactory</interfacename>, and an example for a
|
|
DAO method implementation.</para>
|
|
|
|
<programlisting language="xml"><beans>
|
|
|
|
<bean id="myProductDao" class="product.ProductDaoImpl">
|
|
<property name="sessionFactory" ref="mySessionFactory"/>
|
|
</bean>
|
|
|
|
</beans></programlisting>
|
|
|
|
<programlisting language="java">public class ProductDaoImpl implements ProductDao {
|
|
|
|
private HibernateTemplate hibernateTemplate;
|
|
|
|
public void setSessionFactory(SessionFactory sessionFactory) {
|
|
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
|
|
}
|
|
|
|
public Collection loadProductsByCategory(String category) throws DataAccessException {
|
|
return this.hibernateTemplate.find("from test.Product product where product.category=?", category);
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>The <classname>HibernateTemplate</classname> class provides many
|
|
methods that mirror the methods exposed on the Hibernate
|
|
<interfacename>Session</interfacename> interface, in addition to a
|
|
number of convenience methods such as the one shown above. If you need
|
|
access to the <interfacename>Session</interfacename> to invoke methods
|
|
that are not exposed on the <classname>HibernateTemplate</classname>,
|
|
you can always drop down to a callback-based approach like so.</para>
|
|
|
|
<programlisting language="java">public class ProductDaoImpl implements ProductDao {
|
|
|
|
private HibernateTemplate hibernateTemplate;
|
|
|
|
public void setSessionFactory(SessionFactory sessionFactory) {
|
|
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
|
|
}
|
|
|
|
public Collection loadProductsByCategory(final String category) throws DataAccessException {
|
|
return this.hibernateTemplate.execute(new HibernateCallback() {
|
|
|
|
public Object doInHibernate(Session session) {
|
|
Criteria criteria = session.createCriteria(Product.class);
|
|
criteria.add(Expression.eq("category", category));
|
|
criteria.setMaxResults(6);
|
|
return criteria.list();
|
|
}
|
|
};
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>A callback implementation effectively can be used for any
|
|
Hibernate data access. <classname>HibernateTemplate</classname> will
|
|
ensure that <interfacename>Session</interfacename> instances are
|
|
properly opened and closed, and automatically participate in
|
|
transactions. The template instances are thread-safe and reusable,
|
|
they can thus be kept as instance variables of the surrounding class.
|
|
For simple single step actions like a single find, load, saveOrUpdate,
|
|
or delete call, <classname>HibernateTemplate</classname> offers
|
|
alternative convenience methods that can replace such one line
|
|
callback implementations. Furthermore, Spring provides a convenient
|
|
<classname>HibernateDaoSupport</classname> base class that provides a
|
|
<methodname>setSessionFactory(..)</methodname> method for receiving a
|
|
<interfacename>SessionFactory</interfacename>, and
|
|
<methodname>getSessionFactory()</methodname> and
|
|
<methodname>getHibernateTemplate()</methodname>for use by subclasses.
|
|
In combination, this allows for very simple DAO implementations for
|
|
typical requirements:</para>
|
|
|
|
<programlisting language="java">public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao {
|
|
|
|
public Collection loadProductsByCategory(String category) throws DataAccessException {
|
|
return this.getHibernateTemplate().find(
|
|
"from test.Product product where product.category=?", category);
|
|
}
|
|
}</programlisting>
|
|
</section>
|
|
|
|
<section id="orm-hibernate-daos">
|
|
<title>Implementing Spring-based DAOs without callbacks</title>
|
|
|
|
<para>As alternative to using Spring's
|
|
<classname>HibernateTemplate</classname> to implement DAOs, data
|
|
access code can also be written in a more traditional fashion, without
|
|
wrapping the Hibernate access code in a callback, while still
|
|
respecting and participating in Spring's generic
|
|
<classname>DataAccessException</classname> hierarchy. The
|
|
<classname>HibernateDaoSupport</classname> base class offers methods
|
|
to access the current transactional
|
|
<interfacename>Session</interfacename> and to convert exceptions in
|
|
such a scenario; similar methods are also available as static helpers
|
|
on the <classname>SessionFactoryUtils</classname> class. Note that
|
|
such code will usually pass '<literal>false</literal>' as the value of
|
|
the <methodname>getSession(..)</methodname> methods
|
|
'<literal>allowCreate</literal>' argument, to enforce running within a
|
|
transaction (which avoids the need to close the returned
|
|
<interfacename>Session</interfacename>, as its lifecycle is managed by
|
|
the transaction).</para>
|
|
|
|
<programlisting language="java">public class HibernateProductDao extends HibernateDaoSupport implements ProductDao {
|
|
|
|
public Collection loadProductsByCategory(String category) throws DataAccessException, MyException {
|
|
Session session = getSession(false);
|
|
try {
|
|
Query query = session.createQuery("from test.Product product where product.category=?");
|
|
query.setString(0, category);
|
|
List result = query.list();
|
|
if (result == null) {
|
|
throw new MyException("No search results.");
|
|
}
|
|
return result;
|
|
}
|
|
catch (HibernateException ex) {
|
|
throw convertHibernateAccessException(ex);
|
|
}
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>The advantage of such direct Hibernate access code is that it
|
|
allows <emphasis>any</emphasis> checked application exception to be
|
|
thrown within the data access code; contrast this to the
|
|
<classname>HibernateTemplate</classname> class which is restricted to
|
|
throwing only unchecked exceptions within the callback. Note that you
|
|
can often defer the corresponding checks and the throwing of
|
|
application exceptions to after the callback, which still allows
|
|
working with <classname>HibernateTemplate</classname>. In general, the
|
|
<classname>HibernateTemplate</classname> class' convenience methods
|
|
are simpler and more convenient for many scenarios.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="classic-spring-jdo">
|
|
<title>JDO</title>
|
|
|
|
<para>For the currently recommended usage patterns for JDO see <xref
|
|
linkend="orm-jdo" /></para>
|
|
|
|
<section id="orm-jdo-template">
|
|
<title><classname>JdoTemplate</classname> and
|
|
<classname>JdoDaoSupport</classname></title>
|
|
|
|
<para>Each JDO-based DAO will then receive the
|
|
<interfacename>PersistenceManagerFactory</interfacename> through
|
|
dependency injection. Such a DAO could be coded against plain JDO API,
|
|
working with the given
|
|
<interfacename>PersistenceManagerFactory</interfacename>, but will
|
|
usually rather be used with the Spring Framework's
|
|
<classname>JdoTemplate</classname>:</para>
|
|
|
|
<programlisting language="xml"><beans>
|
|
|
|
<bean id="myProductDao" class="product.ProductDaoImpl">
|
|
<property name="persistenceManagerFactory" ref="myPmf"/>
|
|
</bean>
|
|
|
|
</beans></programlisting>
|
|
|
|
<programlisting language="java">public class ProductDaoImpl implements ProductDao {
|
|
|
|
private JdoTemplate jdoTemplate;
|
|
|
|
public void setPersistenceManagerFactory(PersistenceManagerFactory pmf) {
|
|
this.jdoTemplate = new JdoTemplate(pmf);
|
|
}
|
|
|
|
public Collection loadProductsByCategory(final String category) throws DataAccessException {
|
|
return (Collection) this.jdoTemplate.execute(new JdoCallback() {
|
|
public Object doInJdo(PersistenceManager pm) throws JDOException {
|
|
Query query = pm.newQuery(Product.class, "category = pCategory");
|
|
query.declareParameters("String pCategory");
|
|
List result = query.execute(category);
|
|
<lineannotation>// do some further stuff with the result list</lineannotation>
|
|
return result;
|
|
}
|
|
});
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>A callback implementation can effectively be used for any JDO
|
|
data access. <classname>JdoTemplate</classname> will ensure that
|
|
<classname>PersistenceManager</classname>s are properly opened and
|
|
closed, and automatically participate in transactions. The template
|
|
instances are thread-safe and reusable, they can thus be kept as
|
|
instance variables of the surrounding class. For simple single-step
|
|
actions such as a single <literal>find</literal>,
|
|
<literal>load</literal>, <literal>makePersistent</literal>, or
|
|
<literal>delete</literal> call, <classname>JdoTemplate</classname>
|
|
offers alternative convenience methods that can replace such one line
|
|
callback implementations. Furthermore, Spring provides a convenient
|
|
<classname>JdoDaoSupport</classname> base class that provides a
|
|
<literal>setPersistenceManagerFactory(..)</literal> method for
|
|
receiving a <classname>PersistenceManagerFactory</classname>, and
|
|
<methodname>getPersistenceManagerFactory()</methodname> and
|
|
<methodname>getJdoTemplate()</methodname> for use by subclasses. In
|
|
combination, this allows for very simple DAO implementations for
|
|
typical requirements:</para>
|
|
|
|
<programlisting language="java">public class ProductDaoImpl extends JdoDaoSupport implements ProductDao {
|
|
|
|
public Collection loadProductsByCategory(String category) throws DataAccessException {
|
|
return getJdoTemplate().find(
|
|
Product.class, "category = pCategory", "String category", new Object[] {category});
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>As alternative to working with Spring's
|
|
<classname>JdoTemplate</classname>, you can also code Spring-based
|
|
DAOs at the JDO API level, explicitly opening and closing a
|
|
<interfacename>PersistenceManager</interfacename>. As elaborated in
|
|
the corresponding Hibernate section, the main advantage of this
|
|
approach is that your data access code is able to throw checked
|
|
exceptions. <classname>JdoDaoSupport</classname> offers a variety of
|
|
support methods for this scenario, for fetching and releasing a
|
|
transactional <interfacename>PersistenceManager</interfacename> as
|
|
well as for converting exceptions.</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="classic-spring-jpa">
|
|
<title>JPA</title>
|
|
|
|
<para>For the currently recommended usage patterns for JPA see <xref
|
|
linkend="orm-jpa" /></para>
|
|
|
|
<section id="orm-jpa-template">
|
|
<title><classname>JpaTemplate</classname> and
|
|
<classname>JpaDaoSupport</classname></title>
|
|
|
|
<para>Each JPA-based DAO will then receive a
|
|
<interfacename>EntityManagerFactory</interfacename> via dependency
|
|
injection. Such a DAO can be coded against plain JPA and work with the
|
|
given <interfacename>EntityManagerFactory</interfacename> or through
|
|
Spring's <classname>JpaTemplate</classname>:</para>
|
|
|
|
<programlisting language="xml"><beans>
|
|
|
|
<bean id="myProductDao" class="product.ProductDaoImpl">
|
|
<property name="entityManagerFactory" ref="myEmf"/>
|
|
</bean>
|
|
|
|
</beans></programlisting>
|
|
|
|
<programlisting language="java">public class JpaProductDao implements ProductDao {
|
|
|
|
private JpaTemplate jpaTemplate;
|
|
|
|
public void setEntityManagerFactory(EntityManagerFactory emf) {
|
|
this.jpaTemplate = new JpaTemplate(emf);
|
|
}
|
|
|
|
public Collection loadProductsByCategory(final String category) throws DataAccessException {
|
|
return (Collection) this.jpaTemplate.execute(new JpaCallback() {
|
|
public Object doInJpa(EntityManager em) throws PersistenceException {
|
|
Query query = em.createQuery("from Product as p where p.category = :category");
|
|
query.setParameter("category", category);
|
|
List result = query.getResultList();
|
|
<lineannotation>// do some further processing with the result list</lineannotation>
|
|
return result;
|
|
}
|
|
});
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>The <interfacename>JpaCallback</interfacename> implementation
|
|
allows any type of JPA data access. The
|
|
<classname>JpaTemplate</classname> will ensure that
|
|
<interfacename>EntityManager</interfacename>s are properly opened and
|
|
closed and automatically participate in transactions. Moreover, the
|
|
<classname>JpaTemplate</classname> properly handles exceptions, making
|
|
sure resources are cleaned up and the appropriate transactions rolled
|
|
back. The template instances are thread-safe and reusable and they can
|
|
be kept as instance variable of the enclosing class. Note that
|
|
<classname>JpaTemplate</classname> offers single-step actions such as
|
|
find, load, merge, etc along with alternative convenience methods that
|
|
can replace one line callback implementations.</para>
|
|
|
|
<para>Furthermore, Spring provides a convenient
|
|
<classname>JpaDaoSupport</classname> base class that provides the
|
|
<literal>get/setEntityManagerFactory</literal> and
|
|
<methodname>getJpaTemplate()</methodname> to be used by
|
|
subclasses:</para>
|
|
|
|
<programlisting language="java">public class ProductDaoImpl extends JpaDaoSupport implements ProductDao {
|
|
|
|
public Collection loadProductsByCategory(String category) throws DataAccessException {
|
|
Map<String, String> params = new HashMap<String, String>();
|
|
params.put("category", category);
|
|
return getJpaTemplate().findByNamedParams("from Product as p where p.category = :category", params);
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>Besides working with Spring's
|
|
<classname>JpaTemplate</classname>, one can also code Spring-based
|
|
DAOs against the JPA, doing one's own explicit
|
|
<interfacename>EntityManager</interfacename> handling. As also
|
|
elaborated in the corresponding Hibernate section, the main advantage
|
|
of this approach is that your data access code is able to throw
|
|
checked exceptions. <classname>JpaDaoSupport</classname> offers a
|
|
variety of support methods for this scenario, for retrieving and
|
|
releasing a transaction <interfacename>EntityManager</interfacename>,
|
|
as well as for converting exceptions.</para>
|
|
|
|
<para><emphasis>JpaTemplate mainly exists as a sibling of JdoTemplate
|
|
and HibernateTemplate, offering the same style for people used to
|
|
it.</emphasis></para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="clasic-spring-mvc">
|
|
<title>Classic Spring MVC</title>
|
|
|
|
<para>...</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>JMS Usage</title>
|
|
|
|
<para>One of the benefits of Spring's JMS support is to shield the user
|
|
from differences between the JMS 1.0.2 and 1.1 APIs. (For a description of
|
|
the differences between the two APIs see sidebar on Domain Unification).
|
|
Since it is now common to encounter only the JMS 1.1 API the use of
|
|
classes that are based on the JMS 1.0.2 API has been deprecated in Spring
|
|
3.0. This section describes Spring JMS support for the JMS 1.0.2
|
|
deprecated classes. </para>
|
|
|
|
<sidebar>
|
|
<title>Domain Unification</title>
|
|
|
|
<para>There are two major releases of the JMS specification, 1.0.2 and
|
|
1.1.</para>
|
|
|
|
<para>JMS 1.0.2 defined two types of messaging domains, point-to-point
|
|
(Queues) and publish/subscribe (Topics). The 1.0.2 API reflected these
|
|
two messaging domains by providing a parallel class hierarchy for each
|
|
domain. As a result, a client application became domain specific in its
|
|
use of the JMS API. JMS 1.1 introduced the concept of domain unification
|
|
that minimized both the functional differences and client API
|
|
differences between the two domains. As an example of a functional
|
|
difference that was removed, if you use a JMS 1.1 provider you can
|
|
transactionally consume a message from one domain and produce a message
|
|
on the other using the same
|
|
<interfacename>Session</interfacename>.</para>
|
|
|
|
<note>
|
|
<para>The JMS 1.1 specification was released in April 2002 and
|
|
incorporated as part of J2EE 1.4 in November 2003. As a result, common
|
|
J2EE 1.3 application servers which are still in widespread use (such
|
|
as BEA WebLogic 8.1 and IBM WebSphere 5.1) are based on JMS
|
|
1.0.2.</para>
|
|
</note>
|
|
</sidebar>
|
|
|
|
<section>
|
|
<title>JmsTemplate</title>
|
|
|
|
<para>Located in the package
|
|
<literal>org.springframework.jms.core</literal> the class
|
|
<classname>JmsTemplate102</classname> provides all of the features of
|
|
the <classname>JmsTemplate</classname> described the JMS chapter, but is
|
|
based on the JMS 1.0.2 API instead of the JMS 1.1 API. As a consequence,
|
|
if you are using JmsTemplate102 you need to set the boolean property
|
|
<property>pubSubDomain</property> to configure the
|
|
<classname>JmsTemplate</classname> with knowledge of what JMS domain is
|
|
being used. By default the value of this property is false, indicating
|
|
that the point-to-point domain, Queues, will be used.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Asynchronous Message Reception </title>
|
|
|
|
<para><link
|
|
linkend="jms-receiving-async-message-listener-adapter">MessageListenerAdapter's</link>
|
|
are used in conjunction with Spring's <link linkend="jms-mdp">message
|
|
listener containers</link> to support asynchronous message reception by
|
|
exposing almost any class as a Message-driven POJO. If you are using the
|
|
JMS 1.0.2 API, you will want to use the 1.0.2 specific classes such as
|
|
<classname>MessageListenerAdapter102</classname>,
|
|
<classname>SimpleMessageListenerContainer102</classname>, and
|
|
<classname>DefaultMessageListenerContainer102</classname>. These classes
|
|
provide the same functionality as the JMS 1.1 based counterparts but
|
|
rely only on the JMS 1.0.2 API. </para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Connections</title>
|
|
|
|
<para>The <classname>ConnectionFactory</classname> interface is part of
|
|
the JMS specification and serves as the entry point for working with
|
|
JMS. Spring provides an implementation of the
|
|
<classname>ConnectionFactory</classname> interface,
|
|
<classname>SingleConnectionFactory102</classname>, based on the JMS
|
|
1.0.2 API that will return the same <classname>Connection</classname> on
|
|
all <methodname>createConnection</methodname> calls and ignore calls to
|
|
<methodname>close</methodname>. You will need to set the boolean
|
|
property <property>pubSubDomain</property> to indicate which messaging
|
|
domain is used as <classname>SingleConnectionFactory102</classname> will
|
|
always explicitly differentiate between a
|
|
<classname>javax.jms.QueueConnection</classname> and a
|
|
<classname>javax.jmsTopicConnection</classname>.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Transaction Management</title>
|
|
|
|
<para>In a JMS 1.0.2 environment the class
|
|
<classname>JmsTransactionManager102</classname> provides support for
|
|
managing JMS transactions for a single Connection Factory. Please refer
|
|
to the reference documentation on <link linkend="jms-tx">JMS Transaction
|
|
Management</link> for more information on this functionality.</para>
|
|
</section>
|
|
</section>
|
|
</appendix>
|