The Spring PetClinic Application
Introduction
The Spring Framework is a collection of small, well-focused, loosely coupled Java frameworks that can be used independently or collectively to build industrial strength applications of many different types. The PetClinic sample application is designed to show how the Spring application frameworks can be used to build simple, but powerful database-oriented applications. It will demonstrate the use of Spring's core functionality:
- JavaBeans based application configuration using Inversion-Of-Control
- Model-View-Controller web Presentation Layer
- Practical database access through JDBC, Hibernate, or Java Persistence API
- Application monitoring based on JMX
- Declarative Transaction Management using AOP
- Data Validation that supports but is not dependent on the Presentation Layer
The Spring frameworks provide a great deal of useful infrastructure to simplify the tasks faced by application developers. This infrastructure helps developers to create applications that are:
- concise by handling a lot of the complex control flow that is needed to use the Java API's, such as JDBC, JNDI, JTA, RMI, and EJB.
- flexible by simplifying the process of external application configuration through the use of Reflection and JavaBeans. This allows the developer to achieve a clean separation of configuration data from application code. All application and web application objects, including validators, workflow controllers, and views, are JavaBeans that can be configured externally.
- testable by supplying an interface based design to maximize pluggability. This facilitates unit testing of Business Logic without requiring the presence of application or live database servers.
- maintainable by facilitating a clean separation of the application layers. It most importantly helps maintain the independence of the Business Layer from the Presentation layer. PetClinic demonstrates the use of a Model-View-Controller based web presentation framework that can work seamlessly with many different types of view technologies. The Spring web application framework helps developers to implement their Presentation as a clean and thin layer focused on its main missions of translating user actions into application events and rendering model data.
It is assumed that users of this tutorial will have a basic knowledge of object-oriented design, Java, Servlets, JSP, and relational databases. It also assumes a basic knowledge of the use of a Java EE web application container.
Since the purpose of the sample application is tutorial in nature, the implementation presented here will of course provide only a small subset of the functionality that would be needed by a real world version of a PetClinic application.
PetClinic Sample Application Requirements
The application requirement is for an information system that is accessible through a web browser. The users of the application are employees of the clinic who in the course of their work need to view and manage information regarding the veterinarians, the clients, and their pets. The sample application supports the following:
Use Cases
- View a list of veterinarians and their specialties
- View information pertaining to a pet owner
- Update the information pertaining to a pet owner
- Add a new pet owner to the system
- View information pertaining to a pet
- Update the information pertaining to a pet
- Add a new pet to the system
- View information pertaining to a pet's visitation history
- Add information pertaining to a visit to the pet's visitation history
Business Rules
- An owner may not have multiple pets with the same case-insensitive name.
PetClinic Sample Application Design & Implementation
Server Technology
The sample application should be usable with any Java EE web application container that is compatible with the Servlet 2.4 and JSP 2.0 specifications. Some of the deployment files provided are designed specifically for Apache Tomcat. These files specify container-supplied connection-pooled data sources. It is not necessary to use these files. The application has been configured by default to use a data source with connection pooling. Configuration details are provided in the Developer Instructions section. The view technologies that are to be used for rendering the application are Java Server Pages (JSP) along with the Java Standard Tag Library (JSTL).
Database Technology
The sample application uses a relational database for data storage. Support has been provided for a choice of 1 of 2 database selections, MySql or HypersonicSQL. HypersonicSQL version 1.8.0 is the default choice. It is possible to easily configure the application to use either database. Configuration details are provided in the Developer Instructions section.
Development Environment
A copy of the Spring runtime library jar file is provided with the sample application along with some of the other required jar files. The developer will need to obtain the following tools externally, all of which are freely available:
- Java SDK 1.5.x
- Maven 2.0.10+
- Ant 1.7.1 (for executing scripts, if needed, against the in-memory database)
- Tomcat 6.x.x, or some other Java Servlet container
- (Optional) MySQL 5.x with MySQL Connector/J 5.x
NOTE: The version numbers listed are those that were used in the development of the PetClinic application. Other versions of the same tools may or may not work.
Download links for the various tools needed are provided in the Developer Instructions section.
PetClinic Database
The following is an overview of the database schema used in PetClinic. Detailed field descriptions can be found in the "initDB.txt" SQL script files in the database-specific "db" sub-directories. All "id" key fields are of Java type int.
TABLE: owners
PRIMARY KEY id
TABLE: types
PRIMARY KEY id
TABLE: pets
PRIMARY KEY id
FOREIGN KEY type_id
references the types
table id field
FOREIGN KEY owner_id
references the owners
table id field
TABLE: vets
PRIMARY KEY id
TABLE: specialties
PRIMARY KEY id
TABLE: vet_specialties -
a link table for vets
and their specialties
FOREIGN KEY vet_id
references the vets
table id field
FOREIGN KEY specialty_id
references the specialties
table id field
TABLE: visits
PRIMARY KEY id
FOREIGN KEY pet_id
references the pets
table id field
Directory Structure
d-- indicates a directory holding source code, configuration files, etc.
D-- indicates a directory that is created by the build script
d-- petclinic:
the root directory of the project contains build related files
d-- src: contains
Java source code files and ORM configuration files
d-- war: contains
the web application resource files
d-- html: contains
tutorial files
D-- docs: contains
Javadoc files
d-- web-inf:
contains web application configuration files and application context
files
d-- jsp:
contains Java Server Page files
D-- lib:
contains application dependencies
d-- test: contains
testing related
Java source code files
d-- db: contains
database SQL scripts and other related files/directories
d-- hsqldb:
contains files related to HSQL, contains scripts and a Tomcat
context definition file
d-- mysql:
contains files related to MySQL, contains scripts and a Tomcat context
definition file
D-- .classes:
contains compiled Java class files
D-- .testclasses:
contains compiled testing related Java class files
D-- junit-reports:
contains generated xml-formatted test reports
D-- reports/html:
contains generated html-formatted test reports
D-- dist: contains
packaged archives of files
PetClinic Application Design
Logging
Spring supports the use of the Apache Commons Logging API. This API provides the ability to use Java 1.4 loggers, the simple Commons loggers, and Apache log4j loggers. PetClinic uses log4j to provide sophisticated and configurable logging capabilities. The file, src/main/resources/log4j.properties configures the definition of log4jloggers.
Business Layer
The Business Layer consists of a number of basic JavaBean classes representing the application domain objects and associated validation objects that are used by the Presentation Layer. The validation objects used in PetClinic are all implementations of the org.springframework.validation.Validator interface.
- org.springframework.samples.petclinic.Entity is a simple JavaBean superclass used for all persistable objects.
- org.springframework.samples.petclinic.NamedEntity is an extension of Entity that adds a name property.
- org.springframework.samples.petclinic.Specialty is an extension of NamedEntity.
- org.springframework.samples.petclinic.PetType is an extension of NamedEntity.
- org.springframework.samples.petclinic.Person is an extension of Entity that provides a superclass for all objects that implement the notion of a person.
- org.springframework.samples.petclinic.Vet is an extension of Person that implements a veterinarian. It holds a List of specialties that the Vet is capable of.
- org.springframework.samples.petclinic.Owner is an extension of Person that implements a pet owner. It holds a List of pets owned.
- org.springframework.samples.petclinic.Pet is an extension of NamedEntity that implements a pet. It holds a List of visits made concerning the pet.
- org.springframework.samples.petclinic.Visit is a simple JavaBean that implements the notion of a clinic visit for a pet.
- org.springframework.samples.petclinic.util.EntityUtils provides utility methods for handling entities.
- org.springframework.samples.petclinic.validation.OwnerValidator is a Spring Validator that verifies correct data entry for the Add and Edit Owner forms.
- org.springframework.samples.petclinic.validation.PetValidator is a Spring Validator that verifies correct data entry for the Add and Edit Pet forms.
- org.springframework.samples.petclinic.validation.VisitValidator is a Spring Validator that verifies correct data entry for the AddVisit form.
Business / Persistence Layer
Since the PetClinic application is all about database access and there is very little business logic in the application outside of that, there is no separation of the primary Business and Persistence Layer API's. While this design technique should not be used for an application with more complex business logic, it is acceptable here because all of the non-persistence related business rules have been implemented in business objects and have not leaked into the Persistence Layer. The most important facet of the design is that the Business and Persistence Layers are COMPLETELY independent of the Presentation Layer.
The Persistence Layer can be configured to use either HSQL or MySQL with any one of the following data access technologies aided by infrastructure provided by Spring:
- JDBC
- Hibernate 3
- Java Persistence API
NOTE: Spring also provides infrastructure for using other Object/Relational Mapping frameworks such as JDO and iBATIS SqlMaps, but these are not demonstrated in PetClinic. (See the 'jpetstore' sample application that ships with the full Spring Framework distribution for an example of using iBatis and Spring.)
One of the key elements provided by Spring is the use of a common set of meaningful data access exceptions that can be used regardless of which database or access strategy is used. All of these exceptions derive from org.springframework.dao.DataAccessException. Since most exceptions encountered during database access are indicative of programming errors, DataAccessException is an abstract RuntimeException whose derivatives only need to be caught by application code to handle recoverable errors when it makes sense to do so. This greatly simplifies application code compared to, for example, code using JDBC directly where SqlExceptions must be caught and database specific error codes must be decoded. Examination of the PetClinic source code will show that the persistence-oriented code is completely focused on the relevant transfer of data to/from the referenced objects without extraneous error handling.
The high-level business/persistence API for PetClinic is the org.springframework.samples.petclinic.Clinic interface. Each persistence strategy in PetClinic is a different implementation of the Clinic interface. In each case, the Clinic implementation is fronted by a transactional proxy, configured via the @Transactional annotation, that also implements Clinic. These objects are standard Java dynamic proxies which are created by an instance of org.springframework.transaction.interceptor.TransactionProxyFactoryBean. These proxies are configured in the respective application context file via <tx:annotation-driven /> and specify that all Clinic methods are run in a transactional context. The transaction managers used in PetClinic are all implementations of the org.springframework.transaction.PlatformTransactionManager interface. All of the implementations are by default configured to use a local DataSource that will work in any environment through the use of an instance of org.springframework.jdbc.datasource.DriverManagerDataSource. While this is appropriate for use in a demo or single user program, a connection pooling DataSource, such as an instance of org.apache.commons.dbcp.BasicDataSource, is more appropriate for use in a multi-user application. Another alternative is to obtain one through the Java EE environment using an instance of org.springframework.jndi.JndiObjectFactoryBean.
JDBC Clinic Implementation
Spring provides a number of high-level database access convenience classes in the package org.springframework.jdbc.object. These classes and the lower-level Spring classes that they use in the org.springframework.jdbc.core package provide a higher level of abstraction for using JDBC that keeps the developer from having to correctly implement the handling of the checked SqlExceptions with ugly error-prone nested try-catch-finally blocks. Using the classes in this package allows the developer to focus efforts on the functionality being implemented rather than the mechanics of error handling. When using these classes, it is the responsibility of the developer to provide the SQL needed and to map the parameters to/from the respective domain object. This typically is done by extending one of the org.springframework.jdbc.object classes, initializing its SQL, and overriding a method that takes care of the mapping. In this way, the developer gets to focus on implementing functionality rather than application plumbing. These classes also take care of closing connections to prevent hard to find resource leakage problems. It should be noted that instances of these classes are lightweight, reusable, and threadsafe.
The JDBC implementation of the Clinic interface is org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic, which uses Java 5 language features, org.springframework.jdbc.core.simple.SimpleJdbcTemplate, and org.springframework.jdbc.core.simple.SimpleJdbcInsert. It also takes advantage of classes like org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource and org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper which provide automatic mapping between JavaBean properties and JDBC parameters or query results. SimpleJdbcClinic is a rewrite of the AbstractJdbcClinic which was the base class for JDBC implementations of the Clinic interface for Spring 2.0.
The transaction manager used in the JDBC Clinic Implementation is an instance of org.springframework.jdbc.datasource.DataSourceTransactionManager that can be used for local transactions.
Hibernate 3 Clinic Implementation
The Hibernate 3 implementation of the Clinic interface is org.springframework.samples.petclinic.hibernate.HibernateClinic. To simplify using Hibernate, Spring provides the org.springframework.orm.hibernate3.LocalSessionFactoryBean. The Hibernate configuration is provided by the file src/main/resources/petclinic.hbm.xml.
Java Persistence API (JPA) Clinic Implementation
The JPA implementation of the Clinic interface is org.springframework.samples.petclinic.jpa.EntityManagerClinic, which is based on native JPA usage combined with Spring's @Repository and @Transactional annotations but otherwise has no dependencies on any Spring API's. To simplify JPA usage, Spring provides (among other classes) the org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean. The JPA configuration is provided by src/main/resources/META-INF/orm.xml and src/main/resources/META-INF/persistence.xml.
ApplicationContext
A Spring org.springframework.context.ApplicationContext object provides a map of user-defined JavaBeans that specify either a singleton object or the initial construction of prototype instances. These beans constitute the Business/Persistence Layer of PetClinic. The following beans are defined in all 3 versions (1 per access strategy) of the PetClinic src/main/webapp/WEB-INF/applicationContext-*.xml file:
- A PropertyPlaceholderConfigurer, which is configured via <context:property-placeholder ... /> and is a singleton bean that replaces ${...} placeholders with values from a properties file, in this case, JDBC-related settings for the dataSource bean described below (see src/main/resources/jdbc.properties).
- dataSource, which is a singleton bean that defines the implementation of the source of database connections used by the application.
- transactionManager, which is a singleton bean that defines the implementation of the transaction management strategy for the application.
- clinic, which is a singleton bean that defines the implementation of the Clinic interface that provides the primary Business Layer API of the application.
Presentation Layer
The Presentation Layer is implemented as a Java EE Web Application and provides a very thin and concise Model-View-Controller type user interface to the Business and Persistence Layers.
The PetClinic web application is configured via the following files:
- src/main/webapp/WEB-INF/web.xml: the web application configuration file.
- src/main/webapp/WEB-INF/petclinic-servlet.xml: configures the petclinic dispatcher servlet and the other controllers and forms that it uses. The beans defined in this file reference the Business/Persistence Layer beans defined in applicationContext-*.xml.
- src/main/resources/messages*.properties: configures the definition of internationalizable message resources.
Examine the comments provided in each of these files for a more in-depth understanding of the details of how the application is configured.
General
- In web.xml, a context-param, "webAppRootkey", provides the key for a system property that specifies the root directory for the web application. This parameter, "petclinic.root", can be used to aid in configuring the application.
- In web.xml, a org.springframework.web.context.ContextLoaderListener is defined that loads the root ApplicationContext object of this webapp at startup, by default from the designated /WEB-INF/applicationContext-*.xml. The root org.springframework.web.context.WebApplicationContext of PetClinic is an instance of org.springframework.web.context.support.XmlWebApplicationContext and is the parent of all servlet-specific ApplicationContexts. The Spring root ApplicationContext object provides a map of user-defined JavaBeans that can be used in any and all layers of the application. Beans defined in the root ApplicationContext are automatically available in all child ApplicationContext objects as (external) bean references. Beans defined in an ApplicationContext can also be accessed directly by Java code through getBean(name) method calls.
- In web.xml, a Servlet named "petclinic" is specified to act as a dispatcher for the entire application. This org.springframework.web.servlet.DispatcherServlet is used to handle all URL's matching the pattern "*.do". As with any Servlet, multiple URL mappings may be defined. It is also possible to define multiple instances of DispatcherServlet. Each DispatcherServlet dispatches requests to registered handlers (Controller interface implementations or POJOs annotated with @Controller) indirectly through a org.springframework.web.servlet.handler.HandlerMapping implementation. Each DispatcherServlet has its own ApplicationContext, by default defined in "{servlet-name}-servlet.xml". In this case, it is in the file "petclinic-servlet.xml". This ApplicationContext is used to specify the various web application user interface beans and the URL mappings that are used by the DispatcherServlet to control the handling of requests.
The files web.xml and log4j.properties specify the configuration of logging in the system:
- In web.xml, a "log4jConfigLocation" context-param is specified that sets the location of the log4j configuration file. The default location for this file is /WEB-INF/classes/log4j.properties. Specifying this parameter explicitly allows the location to be changed from the default and is also used to cause periodic log4j configuration refresh checks.
- In web.xml, a Log4jConfigListener is specified that will initialize log4j using the specified configuration file when the web app starts. The Log4jConfigListener is commented out in the file because of a conflict when using JBoss. It should also be noted that if the container initializes Servlets before Listeners as some pre-Servlet 2.4 containers do, a Log4jConfigServlet should be used instead.
- In log4j.properties,
the following loggers are specified:
- "stdout" provides logging messages to the container's log file.
- "logfile" provides logging messages to a rolling file that is specified using the previously defined "petclinic.root".
Examination and study of these logging files will provide insight into the operation of the Spring framework and the application as well as valuable troubleshooting information should something not work correctly.
DispatcherServlet
The following beans are accessible to the DispatcherServlet and are defined in the PetClinic petclinic-servlet.xml file. This dispatcher uses these definitions to delegate actual display and form processing tasks to implementations of the Spring org.springframework.web.servlet.mvc.Controller interface. The DispatcherServlet acts as the main application Front Controller and is responsible for dispatching all requests to the appropriate Controller indirectly through a URL mapping handler. These Controllers are responsible for the mechanics of interaction with the user and ultimately delegate action to the Business/Persistence Layers.
- messageSource is a singleton bean that defines a message source for this ApplicationContext. Messages are loaded from localized "messages_xx" files in the classpath, such as "/WEB-INF/classes/messages.properties" or "/WEB-INF/classes/messages_de.properties". getMessage() calls to this context will use this source. Child contexts can have their own message sources, which will inherit all messages from this source and are able to define new messages and override ones defined in the primary message source.
- InternalResourceViewResolver is a singleton bean that defines the view mappings used by the dispatcher. Specifically, logical view names returned by Controllers will be mapped to physical paths using the configured 'prefix' and 'suffix' properties. For example, a logical view name of "vets" will be mapped to "/WEB-INF/jsp/vets.jsp".
- SimpleMappingExceptionResolver is a singleton bean that defines how exceptions are propagated. Exceptions encountered that are not specified are propagated to the servlet container.
-
<context:component-scan ... />
is used to autodetect the controllers in the
org.springframework.samples.petclinic.web package, which
are POJOs labeled with the @Controller annotation.
- ClinicController is a singleton, annotation-driven MultiActionController that is used by the dispatcher to handle non-form based display tasks. A method is provided to handle each type of request that is supported.
- In addition, there are 6 singleton, annotation-driven Form controllers, which are used to handle the various Search, Add and Edit form processing tasks for the dispatcher.
- The form-based controllers within the PetClinic application provide @RequestMapping annotations at the type level for path mapping URLs and @RequestMapping at the method level for request type mappings (e.g., GET and POST). In contrast, ClinicController – which is not form-based – provides @RequestMapping only at the method level for path mapping URLs. DefaultAnnotationHandlerMapping is driven by these annotations and is enabled by default with Java 5+.
Views
The Controllers used by the dispatcher handle the work flow of the application. The actual display tasks are delegated by the Controllers to implementations of the Spring View interface. These View objects are themselves beans that can render a particular type of view. The handling Controller supplies the View with a data model to render. The data model is provided to the View as a Map of objects. Views are only responsible for rendering a display of the data model and performing any display logic that is particular to the type of View being rendered. Spring provides support for rendering many different types of views: JSP, XSLT, PDF, Velocity templates, Excel files, and others. By using a View mapping strategy, Spring supplies the developer with a great deal of flexibility in supporting easily configurable view substitution.
ClinicController relies on RequestToViewNameTranslator to automatically infer the logical view name from the incoming request URL; whereas, all Form controllers in the PetClinic application return logical view names as Strings. These logical view names are then mapped to physical paths via the configured InternalResourceViewResolver (see the DispatcherServlet section above for further details). Logical view names that are prepended with "redirect:" will be resolved to instances of RedirectView, which simply redirects to another URL. The other resolved Views will be instances of JstlView, which provides some handy support for internationalization & localization in JSP pages that use JSTL.
Messages
The messages*.properties files are loaded from the classpath to provide localized messages for the supported languages. PetClinic supplies a localized "welcome" message as well as localized form entry error messages in the default (i.e., English) and German properties files. See the "countries" sample application for a more detailed example of Spring's support for internationalization.
Presentation Layer classes
- org.springframework.samples.petclinic.web.ClinicController is an annotation-driven, POJO MultiActionController that is used to handle simple display-oriented URLs.
- org.springframework.samples.petclinic.web.FindOwnersForm is an annotation-driven, POJO Form controller that is used to search for Owners by last name.
- org.springframework.samples.petclinic.web.AddOwnerForm is an annotation-driven, POJO Form controller that is used to add a new Owner to the system.
- org.springframework.samples.petclinic.web.EditOwnerForm is an annotation-driven, POJO Form controller that is used to edit an existing Owner. A copy of the existing Owner is used for editing.
- org.springframework.samples.petclinic.web.AddPetForm is an annotation-driven, POJO Form controller that is used to add a new Pet to an existing Owner.
- org.springframework.samples.petclinic.web.EditPetForm is an annotation-driven, POJO Form controller that is used to edit an existing Pet. A copy of the existing Pet is used for editing.
- org.springframework.samples.petclinic.web.AddVisitForm is an annotation-driven, POJO Form controller that is used to add a new Visit to an existing Pet.
Logical Views & Implemented Use Cases
- welcome is the "home" screen. It provides links to display a list of all vets, find an owner, or view documentation.
- vets displays all vets and their specialties.
- findOwners is used to find owners by last name.
- findOwnersRedirect redirects to findOwner.
- selectOwner allows user to select from a list of multiple owners with the same last name.
- owner displays a owner's data and a list of the owner's pets and their data.
- ownerRedirect redirects to owner.
- owner supports AddOwnerForm and EditOwnerForm
- pet supports AddPetForm and web.EditPetForm
- visit supports AddVisitForm
- dataAccessFailure displays a stacktrace
Java Server Pages
- index.jsp redirects to the "welcome" page.
- includes.jsp is statically included in all JSP's used in the application. It specifies the taglibs that are in use.
- header.jsp and footer.jsp display info common to virtually all pages. Spring also supplies support for the integration of Tiles (included in Struts) but this is not used in PetClinic.
- dataAccessFailure.jsp is the error page configured via SimpleMappingExceptionResolver, which displays a stack trace and normally wouldn't be used in a production version of an application. It can be seen in action by entering a URL of "editOwner.do" or "editPet.do" with an invalid request parameter, for example: /petclinic/owner.do?ownerId=-1. The handlers for these URLs normally expect to see a respective "ownerId" or "petId" request parameter corresponding to an Owner or Pet in the database. Thus, these handlers will throw a DataAccessException when such a request parameter is provided which references a non-existing entity.
- uncaughtException.jsp is the web.xml configured "error-page". It displays a stack trace and normally wouldn't be used in a production version of an application. It can be seen in action by entering a URL of "editOwner.do" or "editPet.do" without a valid request parameter, for example: /petclinic/owner.do. The handlers for these URLs normally expect to see a respective "ownerId" or "petId" request parameter and throw a ServletException when such a request parameter is not found.
- welcome.jsp implements welcome.
- vets.jsp implements vets.
- findOwners.jsp implements findOwners.
- owners.jsp implements selectOwner.
- owner.jsp implements owner.
- ownerForm.jsp implements ownerForm.
- petForm.jsp implements petForm.
- visitForm.jsp implements visitForm.
The following items should be noted regarding the web application implementation design:
- all JSP's are stored under /WEB-INF/jsp except for index.jsp which is the configured "welcome-file"
- The use of JSP technology in the application is not exposed to the user, i.e., the end user never sees a URL ending in ".jsp".
- By convention, all URL's in the application ending in ".do" are handled by web application controllers. Static html pages ending in ".html", such as Javadoc, will be directly served to the end user.
- The results of all form entries are handled using browser round trip redirection to minimize possible end user confusion.
- All pages are extremely simple JSP implementations that focus only on providing the necessary functionality.
- References to Entity objects
are passed around in the application by supplying the object's
ID
as a request parameter.
Testing
- org.springframework.samples.petclinic.OwnerTests is a simple JUnit 4 based TestCase that supports Business Rule #1.
- org.springframework.samples.petclinic.AbstractClinicTests
is a JUnit 4 based TestCase requiring a live database connection that is
used to confirm correct operation of the database access objects in the
various implementations of the Clinic interface.
"AbstractClinicTests-context.xml" declares a common
javax.sql.DataSource. Subclasses specify additional
context locations which declare a
org.springframework.transaction.PlatformTransactionManager
and a concrete implementation of Clinic.
AbstractClinicTests extends AbstractTransactionalJUnit4SpringContextTests, one of the valuable testing support classes provided by the Spring TestContext Framework found in the
org.springframework.test.context
package. The annotation-driven configuration used here represents best practice for integration tests with Spring. Note, however, that AbstractTransactionalJUnit4SpringContextTests serves only as a convenience for extension. For example, if you do not wish for your test classes to be tied to a Spring-specific class hierarchy, you may configure your tests with annotations such as @ContextConfiguration, @TestExecutionListeners, @Transactional, etc.AbstractClinicTests and its subclasses benefit from the following services provided by the Spring TestContext Framework:
- Spring IoC container caching which spares us unnecessary set up time between test execution.
- Dependency Injection of test fixture instances,
meaning that we don't need to perform application context lookups. See the
use of @Autowired on the
clinic
instance variable, which uses autowiring by type. As an alternative, we could annotateclinic
with JSR 250's @Resource to achieve dependency injection by name. (see: @ContextConfiguration, DependencyInjectionTestExecutionListener) - Transaction management, meaning each test method is executed in its own transaction, which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there is no need for a teardown or cleanup script. (see: @TransactionConfiguration, @Transactional, TransactionalTestExecutionListener)
- Useful inherited protected fields, such as a SimpleJdbcTemplate that can be used to verify database state after test operations or to verify the results of queries performed by application code. An ApplicationContext is also inherited and can be used for explicit bean lookup if necessary. (see: AbstractJUnit4SpringContextTests, AbstractTransactionalJUnit4SpringContextTests)
The Spring TestContext Framework and related unit and integration testing support classes are shipped in
spring-test.jar
.
Downloads
- Download and install the Spring Framework (the PetClinic sample application is included)
- Download and install a Java Software Developer Kit, version 1.5 or later
- Download and install Apache Maven, preferably version 2.0.10 or later
- Download and install Apache Ant, preferably version 1.7.1 or later
- Download and install Apache Tomcat, preferably version 6.0.20 or later
- Download and install MySQL, preferably version 5.1.x or later (optional)
- Hypersonic SQL, and Hibernate are provided with the application.
- PetClinic and Spring use the Apache Commons Logging and log4j packages.
Maven Setup
Make sure that the Maven executable is in your command shell path.
MYSQL Setup (optional)
Add the PetClinic database to a running MySQL server by following the
explicit instructions found in
db/mysql/petclinic_db_setup_mysql.txt.
PetClinic expects by default to be able to access the server via the
standard port 3306
. To use a different port, it will be
necessary to change the PetClinic Database Setup.
PetClinic Database Setup
To use a Java EE server supplied connection-pooled data source with Tomcat, it will be necessary to use and possibly edit the appropriate context definition file for the petclinic webapp. To use it, deploy a copy of the appropriate context definition file in Tomcat's webapps directory and restart the server. Consult the Tomcat log files if something goes wrong when starting either Tomcat or the PetClinic application. The context files are named petclinic_tomcat_*.xml, where * is either "hsqldb" or "mysql". There is a context file supplied for each database in its respective directory. There is also a context file db/petclinic_tomcat_all.xml that will provide a JNDI connection-pooled DataSource for all supported databases. Should you use this file, you must of course make sure that all the database servers are running when you restart Tomcat.
- Should you deploy one of the context files or define a context in Tomcat's server.xml, Tomcat will not automatically deploy the webapp from the petclinic.war file. The webapp will then need to be manually extracted to the target directory.
- The context files will also configure logging to supply a separate log file for the petclinic context. This will separate the container logging for petclinic from that of the other webapps. This should not be confused with the application log file provided through log4j.
- An Ant script (db/build.xml)
has been provided that can be used to re-initialize either database. To
select or configure the data source and database used for the webapp and
for testing, you will need to edit the following files:
- src/main/webapp/WEB-INF/applicationContext-*.xml: for configuring the DataSource in the webapp
- src/main/resources/jdbc.properties: for configuring JDBC connection settings for both the webapp and testing
- build.properties: for running the "tests" target in Ant
Building the PetClinic Application
Open a command line shell and navigate to the directory containing PetClinic. Make sure the database is running and execute "mvn clean package". This will run clean and compile everything and execute the tests, including integration tests against an in-memory database.
Deploying the PetClinic Application
Deploy the web application to the server in the usual way (see notes regarding database setup). If you need instructions for web application deployment, see the Tomcat documentation for details. The Web Application aRchive file is org.springframework.samples.petclinic.war and can be found in the target/artifacts directory.
Using the PetClinic Application
Make sure the PetClinic web application is running and browse to http://localhost:8080/org.springframework.samples.petclinic/.
Home | ![]() |