Better Faster Lighter Java [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Better Faster Lighter Java [Electronic resources] - نسخه متنی

Justin Gehtland; Bruce A. Tate

نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
تنظیمات قلم


اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
لیست موضوعات
افزودن یادداشت
افزودن یادداشت جدید

8.2 Pet Store: A Counter-Example

The J2EE Pet Store application is an

infamous programming example
gone bad. It taught thousands of J2EE developers to build poorly
designed, poor-performing code. It was also the center of a
benchmarking controversy. A respected consulting company called The
Middleware Company worked on a benchmark comparing J2EE with
Microsoft's .NET platform. As a foundation for the
benchmark, they chose the J2EE version of Pet Store. Though they
worked hard to tune it, the J2EE version lost badly to the Microsoft
.NET version and many criticized the design. I don't
intend to lay any blame for this fiasco. Instead, I offer a different
interpretation. It's my firm opinion that J2EE,
especially EJB, makes it hard to develop clean, high-performance
code. Put another way, the Pet Store benchmark was a symptom of a
larger problem.

After the benchmarking uproar, a number of people showed how to
implement Pet Store with easier, simpler technologies. One of the
strongest and simplest implementations, by Clinton Begin, used a DAO
framework called iBatis instead of full entity beans. Rod
Johnson's team converted that application to Spring,
and now distributes it with the Spring framework. Here are some of
the details:

The Spring jPetStore application comes with Spring Versions M4 and

It's a data-driven application with a JDBC DAO layer.

It provides alternative frontends for Struts, and the Spring MVC

It provides two different models. The simplest uses a single database
and simple JDBC transactions. The other uses JTA transaction
management across multiple data stores.

In the following sections, I'll work through the
version of the application with the MVC web frontend and simple
transactions across one database. I'll focus on the
domain model, the single-database DAO layer, simple transactions, and
the Spring MVC frontend. Outstanding resources are available at the
Spring web site for those who want to dive deeper.

8.2.1 The Configuration

When learning a Spring

start with the configuration file; it shows you the major beans and
how the application fits together. A Spring configuration file
defines the beans in an application context. Think of the context as
a convenient collection of named resources for an application.

Many J2EE applications keep track of application resources such as
connections and the like with singletons. When you think about it, a
singleton used in this way is not much different from a global
variable; many Java developers lean on this crutch too often.
J2EE's alternative is a directory service called
JNDI, but it's overkill for many common uses.
Spring, instead, uses an application context. Initially, you specify
it in a simple XML file, although you can extend Spring to accept
other kinds of configuration as well. Here are some of the things
that might go into an application context:

Data sources

A Java class that manages connections, usually in a pool.

DAO layers

If your applications use a database, you probably want to isolate the
database access to one layer, the DAO. You can access this layer
through the application context.

Persistence managers

Every persistence

framework has an object or factory
that the application uses to access its features. With Hibernate,
it's the session and the session factory. With JDO,
it's the persistence manager factory and persistence

Transaction policies

You can explicitly declare the

that you want to participate in transactions and the transaction
manager that you want to use to enforce that strategy.

Transaction managers

There are many different transaction management strategies within
J2EE. For single database applications, Spring lets you use the
database's transaction management. For multiple
databases or transaction sources, Spring allows JTA instead. You can
keep the transaction manager in the application context.

Validation logic

The Spring framework

a validation framework similar to Struts. Spring lets you configure
validation logic like any other business component.

Views and controllers

The Spring framework lets you specify the controllers for a view and
helps you configure the navigation path through them.

The jPetStore application uses the Spring
application context for a data source, the DAO layer, and a
transaction strategy. You define what goes into a context within an
XML document that lists a series of beans. Each XML configuration
file will have a <beans> heading, followed
by a series of <bean> components, and a
</beans> footer, like this:

<bean id="MyFirstBean" class="package.MyFirstBeanClass">
<property name="myField" ref local="MySecondBean"/>
<bean id="MySecondBean" class="package.MySecondBeanClass">

These are the beans that make up an application context. They
represent the top-level beans of an application. (They may create
other objects or beans that do not appear in the configuration file.)
In this case, you create two beans named
MyFirstBean and MySecondBean.
Then, you wire them together by specifying
MySecondBean as the value for the field
myField. When Spring starts, it creates both
objects and sets the value of myField. You have
access to both of these objects by name whenever you need them
through the application context.

Let's look at a more concrete example. The
jPetStore application has three configuration
files for the business logic, the data layer, and the user interface,
as in Figure 8-2. A separate Spring configuration
file describes each one.

Figure 8-2. The jPetStore application has Spring application contexts to match its three distinct layers

These configuration files specify the context for the domain model,
the data layer, and the presentation layer. Example 8-1 shows part of the application context for the
business logic of the jPetStore application. Note
that I've shortened the package name from
org.springframework.samples.jpetstore... to
jpetstore for simplicity.

Example 8-1. applicationContext.xml

<bean id="accountValidator" class="jpetstore.domain.logic.AccountValidator"/>
[2] <bean id="orderValidator" class="jpetstore.domain.logic.OrderValidator"/>
[3] <bean id="petStoreTarget" class="jpetstore.domain.logic.PetStoreImpl"/>
[4] <property name="AccountDao"><ref bean="accountDao"/></property>
<property name="categoryDao"><ref bean="categoryDao"/></property>
<property name="productDao"><ref bean="productDao"/></property>
<property name="itemDao"><ref bean="itemDao"/></property>
<property name="orderDao"><ref bean="orderDao"/></property>
[5] <bean id="petStore" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"><ref bean="petStoreTarget"/></property>
<property name="transactionAttributes">
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>

Here's an explanation of the annotated lines:

[1] Business logic. This section (which
includes all bold code) has the core business logic. Validation and
the domain model are both considered business components.

[2] Validators. This is the validator
for Order. Spring calls it whenever a user submits the Order form and
routes to the error page or an order completion page, as required.

[3] Core business implementation. This
class contains the core implementation for the persistent domain
model. It contains all of the DAO objects that
you'll see below.

[4] Properties. Each of your beans has
individual properties that may refer to beans you define elsewhere.
In this case, the bean properties are individual DAO. Each of these
beans is defined in another Spring configuration file.

[5] Transaction declarations. This bean
specifies the transaction strategy for the application. In this case,
the application uses a transaction manager specified in another
Spring configuration file. It declares the methods that should be
propagated as transactions. For example, all methods beginning with
insert should be propagated as transactions.

In short, this configuration file serves as the glue that holds the
business logic of the application together. In the file, you see some
references to beans that are not in the configuration file itself,
such as the DAO objects. Later on, you'll see two
other configuration files that define some of the missing beans. One
specifies the data access objects with the transaction manager. The
other specifies the beans needed by the user interface.
It's often better to break configuration files into
separate layers, allowing you to configure individual layers as
needed. For example, you may want to change strategies for your user
interface (say, from Spring MVC web to Struts) or for data access
(say, from DAO with one database to DAO spanning two databases with
JTA transactions).

If you want to instantiate a bean from your XML context file,
it's easy. For example, in order to access a bean
called myCustomer of type
Customer from a file called
context.xml, take the following three steps:

Get an input stream for the XML file with your configuration:

InputStream stream = getClass( ).getResourceAsStream("context.xml");

Create a new Spring bean factory using the input stream:

XmlBeanFactory beanFactory = new XmlBeanFactory(stream);

Use the factory to create one of the objects defined in your
.xml file:

Customer cust = (Customer)beanFactory.getBean(myCustomer);

Or, if you want Spring to initialize a context and then grab, for
example, your session façade, you'd use
code like this:

protected static final String CONTEXT_FILE = "WEB-INF/applicationContext.xml";
Biz biz; // session façade
FileSystemXmlApplicationContext ctx =
new FileSystemXmlApplicationContext(CONTEXT_FILE);
biz = (Biz) ctx.getBean("biz");

It's often better to let go of that control.
Usually, you won't have to access the application
context directly. The framework does that for you. For example, if
you're using servlets, the Spring framework provides
a context for each servlet and a catch-all context for servlets. From
there, you can usually get the appropriate context information, as
you'll see later. Now that you've
seen a configuration file representing the
jPetStore application, it's time
to see

how to build the individual

/ 111