Praise for the First Edition
“This is one of those rare books that connect a tutorial for using a certain software
product with a plethora of ideas on good software design and design patterns. I
enjoyed this book very much...”
—Computing Reviews
“Covers all the bases with extensive examples and explicit instructions...a superbly
organized and fluently written instruction and reference manual.”
—Internet Bookwatch
“...easy to read...and has just enough humor mixed in...”
—Books-On-Line
“While Spring’s reference documentation is high quality, this book makes learning
Spring much more enjoyable. The book injects a fair amount of humor that keeps it
entertaining. If you want to learn Spring, you can’t go wrong with this offering.”
—Bill Siggelkow’s Weblog
Author of Jakarta Struts Cookbook
“Truly a great resource... The book clearly defines the power that Spring brings to
enterprise programmers and how Spring abstracts away many of the tougher J2EE
services that most serious applications use. The book has been through a rigorous early
access program, so thankfully grammar and code errors are all but non-existent. To
me, there is nothing worse than trying to learn a new technology from a poorly written
and edited technical book. Thankfully, Craig, Ryan, and the Manning team have
paid attention to detail and produced a book that I highly recommend.”
—JavaLobby.org
“A complete reference manual that covers nearly every aspect of Spring. This doesn’t
mean it is complicated: every explanation is clear and there are a lot of code examples.
...[it] explains clearly what “Inversion of Control” and AOP mean and how Spring
makes them possible. ...how you can write services and Daos, and how you can simply
implement transaction management and service remoting. ...the third part talks
about the Web layer covering Spring MVC as well as other technologies and
frameworks. ...Overall an excellent resource for any developer interested in using
Spring in his project.”
—Java User Group Milano
Spring in Action
Second Edition
CRAIG WALLS
with Ryan Breidenbach
MANNING
Greenwich
(74° w. long.)
For online information and ordering of this and other Manning books, please visit
www.manning.com. The publisher offers discounts on this book when ordered in quantity.
For more information, please contact:
Special Sales Department
Manning Publications Co.
Sound View Court 3B Fax: (609) 877-8256
Greenwick, CT 06830 Email:
©2008 by Manning Publications Co. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in
any form or by means electronic, mechanical, photocopying, or otherwise, without prior written
permission of the publisher.
Many of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in the book, and Manning
Publications was aware of a trademark claim, the designations have been printed in initial caps
or all caps.
Recognizing the importance of preserving what has been written, it is Manning’s policy to have
the books we publish printed on acid-free paper, and we exert our best efforts to that end.
Manning Publications Co.
Sound View Court 3B
Greenwich, CT 06830
Copyeditor: Liz Welch
Typesetter: Dottie Marsico
Cover designer: Leslie Haimes
ISBN 1-933988-13-4
Printed in the United States of America
1 2 3 4 5 6 7 8 9 10 – MAL – 13 12 11 10 09 08 07
For my wife Raymie and my daughters Maisy and Madison
I am endlessly mystified as to how I merit the love
of the world’s three most beautiful girls.
brief contents
PART 1
PART 2
CORE SPRING ...............................................................1
1
■
Springing into action
2
■
Basic bean wiring
3
■
Advanced bean wiring
4
■
Advising beans
3
31
72
116
ENTERPRISE SPRING ................................................. 153
5
■
Hitting the database
6
■
Managing transactions
7
■
Securing Spring
8
■
Spring and POJO-based remote services
9
■
Building contract-first web services in Spring
10
■
Spring messaging 384
11
■
Spring and Enterprise JavaBeans
12
■
Accessing enterprise services
vii
155
220
247
441
423
305
343
viii
PART 3
BRIEF CONTENTS
CLIENT-SIDE SPRING ..................................................487
13
■
Handling web requests
489
14
■
Rendering web views
15
■
Using Spring Web Flow
16
■
Integrating with other web frameworks
533
580
appendix A
Setting up Spring
667
appendix B
Testing with (and without) Spring
678
623
contents
preface xix
preface to the first edition xxii
acknowledgments xxv
about this book xxvii
about the title xxxiii
about the cover illustration xxxiv
PART 1 CORE SPRING ................................................ 1
1
Springing into action 3
1.1
What is Spring?
5
Spring modules 6
1.2
1.3
A Spring jump start 11
Understanding dependency injection
14
Injecting dependencies 14 Dependency injection in action 15
Dependency injection in enterprise applications 21
■
1.4
Applying aspect-oriented programming
Introducing AOP
1.5
Summary
24
30
ix
■
AOP in action
26
24
x
CONTENTS
2
Basic bean wiring 31
2.1
Containing your beans
33
Introducing the BeanFactory 34
context 35 A bean’s life 37
■
Working with an application
■
2.2
Creating beans
40
Declaring a simple bean 40
2.3
■
Injecting through constructors
Injecting into bean properties
46
Injecting simple values 47 Referencing other beans 48
Wiring collections 52 Wiring nothing (null) 58
■
■
2.4
Autowiring
58
The four types of autowiring 59 Mixing auto with explicit
wiring 63 To autowire or not to autowire 63
■
■
2.5
Controlling bean creation
64
Bean scoping 65 Creating beans from factory methods 66
Initializing and destroying beans 68
■
2.6
3
Summary
71
Advanced bean wiring 72
3.1
Declaring parent and child beans
Abstracting a base bean type 74
properties 76
3.2
Applying method injection
Basic method replacement
3.3
3.4
3.5
80
■
73
Abstracting common
79
■
Using getter injection 83
Injecting non-Spring beans 85
Registering custom property editors 88
Working with Spring’s special beans 92
Postprocessing beans 93 Postprocessing the bean factory 95
Externalizing configuration properties 96 Resolving text
messages 99 Decoupling with application events 101
Making beans aware 103
■
■
■
3.6
Scripting beans
106
Putting the lime in the coconut 107 Scripting a bean 108
Injecting properties of scripted beans 111 Refreshing scripted
beans 112 Writing scripted beans inline 113
■
■
■
3.7
Summary
114
42
xi
CONTENTS
4
Advising beans 116
4.1
Introducing AOP 118
Defining AOP terminology 119
4.2
Spring’s AOP support 122
■
Creating classic Spring aspects
125
Creating advice 127 Defining pointcuts and advisors
Using ProxyFactoryBean 136
■
4.3
Autoproxying
139
Creating autoproxies for Spring aspects 140
@AspectJ aspects 141
PART 2
5
132
4.4
Declaring pure-POJO aspects
4.5
Injecting AspectJ aspects
4.6
Summary
■
Autoproxying
145
149
152
ENTERPRISE SPRING ................................. 153
Hitting the database 155
5.1
Learning Spring’s data access philosophy
157
Getting to know Spring’s data access exception hierarchy 158
Templating data access 161 Using DAO support classes 163
■
5.2
Configuring a data source 165
Using JNDI data sources 165 Using a pooled data source
JDBC driver-based data source 168
■
5.3
Using JDBC with Spring
170
Tackling runaway JDBC code 170 Working with JDBC
templates 173 Using Spring’s DAO support classes for
JDBC 180
■
■
5.4
Integrating Hibernate with Spring
183
Choosing a version of Hibernate 185 Using Hibernate
templates 186 Building Hibernate-backed DAOs 190
Using Hibernate 3 contextual sessions 192
■
■
5.5
Spring and the Java Persistence API
194
Using JPA templates 194 Configuring an entity manager
factory 197 Building a JPA-backed DAO 202
■
■
167
xii
CONTENTS
5.6
Spring and iBATIS 203
Configuring an iBATIS client template 204
an iBATIS-backed DAO 207
5.7
Caching
■
Building
208
Configuring a caching solution 210 Proxying beans
for caching 215 Annotation-driven caching 217
■
■
5.8
6
Summary
218
Managing transactions 220
6.1
Understanding transactions
222
Explaining transactions in only four words 223
Understanding Spring’s transaction management
support 224
6.2
Choosing a transaction manager 225
JDBC transactions 226 Hibernate transactions 227
Java Persistence API transactions 227 Java Data
Objects transactions 228 Java Transaction API
transactions 229
■
■
■
6.3
6.4
Programming transactions in Spring 229
Declaring transactions 232
Defining transaction attributes 233 Proxying
transactions 238 Declaring transactions in
Spring 2.0 241 Defining annotation-driven
transactions 243
■
■
■
6.5
7
Summary
245
Securing Spring 247
7.1
7.2
Introducing Spring Security
Authenticating users 252
248
Configuring a provider manager 253 Authenticating
against a database 256 Authenticating against
an LDAP repository 264
■
■
7.3
Controlling access
271
Voting access decisions 272 Casting an access decision
vote 273 Handling voter abstinence 275
■
■
CONTENTS
7.4
Securing web applications
275
Proxying Spring Security’s filters 278 Handling the
security context 285 Prompting the user to log
in 286 Handling security exceptions 291 Enforcing
web security 293 Ensuring a secure channel 294
■
■
■
■
■
7.5
View-layer security
297
Conditionally rendering content 298
authentication information 299
7.6
Securing method invocations
Creating a security aspect
metadata 303
7.7
8
Summary
301
■
Displaying user
300
■
Securing methods using
304
Spring and POJO-based remote services 305
8.1
8.2
An overview of Spring remoting
Working with RMI 309
Wiring RMI services 310
8.3
■
306
Exporting RMI services 312
Remoting with Hessian and Burlap
Accessing Hessian/Burlap services 317
functionality with Hessian/Burlap 318
8.4
Exposing bean
Using Spring’s HttpInvoker 322
Accessing services via HTTP
HTTP Services 324
8.5
316
■
Spring and web services
323
■
Exposing beans as
326
Exporting beans as web services using XFire 326
Declaring web services with JSR-181 annotations 330
Consuming web services 333 Proxying web services with
an XFire client 340
■
8.6
9
Summary
341
Building contract-first web services in Spring
9.1
9.2
Introducing Spring-WS 345
Defining the contract (first!) 347
Creating sample XML messages
348
343
xiii
xiv
CONTENTS
9.3
Handling messages with service endpoints
Building a JDOM-based message endpoint 355
message payloads 358
9.4
Wiring it all together
353
■
Marshaling
361
Spring-WS: The big picture 361 Mapping messages to
endpoints 363 Wiring the service endpoint 364
Configuring a message marshaler 364 Handling endpoint
exceptions 367 Serving WSDL files 369 Deploying the
service 373
■
■
■
■
9.5
■
Consuming Spring-WS web services
373
Working with web service templates 374
gateway support 381
9.6
10
Summary
■
Using web service
382
Spring messaging 384
10.1
A brief introduction to JMS
386
Architecting JMS 387 Assessing the benefits of JMS
Setting up ActiveMQ in Spring 392
■
10.2
390
Using JMS with Spring 393
Tackling runaway JMS code 393 Working with JMS
templates 395 Converting messages 402 Using Spring’s
gateway support classes for JMS 405
■
■
10.3
■
Creating message-driven POJOs
Creating a message listener 408
MDPs 412
10.4
Using message-based RPC
Introducing Lingo 417
Proxying JMS 420
10.5
11
Summary
■
■
407
Writing pure-POJO
416
Exporting the service
418
422
Spring and Enterprise JavaBeans 423
11.1
Wiring EJBs in Spring 425
Proxying session beans (EJB 2.x) 426
beans 430
11.2
■
Wiring EJBs into Spring
Developing Spring-enabled EJBs (EJB 2.x)
431
CONTENTS
11.3
Spring and EJB3
434
Introducing Pitchfork 435 Getting started with Pitchfork 436
Injecting resources by annotation 437 Declaring interceptors
using annotations 438
■
■
11.4
12
Summary
440
Accessing enterprise services
12.1
441
Wiring objects from JNDI
442
Working with conventional JNDI 443 Injecting JNDI
objects 446 Wiring JNDI objects in Spring 2 449
■
■
12.2
Sending email
450
Configuring a mail sender
12.3
Scheduling tasks
451
Constructing the email 453
■
456
Scheduling with Java’s Timer 457 Using the Quartz
scheduler 460 Invoking methods on a schedule 464
■
■
12.4
Managing Spring beans with JMX
466
Exporting Spring beans as MBeans 467 Remoting
MBeans 477 Handling notifications 482
■
■
12.5
Summary
485
PART 3 CLIENT-SIDE SPRING .................................. 487
13
Handling web requests 489
13.1
Getting started with Spring MVC
490
A day in the life of a request 491 Configuring
DispatcherServlet 492 Spring MVC in a nutshell
■
■
13.2
Mapping requests to controllers
495
502
Using SimpleUrlHandlerMapping 503 Using
ControllerClassNameHandlerMapping 504 Using metadata
to map controllers 505 Working with multiple handler
mappings 505
■
■
■
13.3
Handling requests with controllers
506
Processing commands 509 Processing form submissions 512
Processing complex forms with wizards 520 Working with
throwaway controllers 528
■
■
xv
xvi
CONTENTS
13.4
13.5
14
Handling exceptions
Summary 532
531
Rendering web views 533
14.1
Resolving views
534
Using template views 535 Resolving view beans
Choosing a view resolver 540
537
■
14.2
Using JSP templates
542
Binding form data 542
Displaying errors 547
14.3
Rendering externalized messages
Laying out pages with Tiles
Tile views 550
14.4
■
■
14.5
549
Creating Tile controllers
Working with JSP alternatives
Using Velocity templates 557
544
■
554
556
Working with FreeMarker 564
Generating non-HTML output 569
Producing Excel spreadsheets 570 Generating PDF
documents 573 Developing custom views 576
■
■
14.6
15
Summary
578
Using Spring Web Flow
15.1
580
Getting started with Spring Web Flow
Installing Spring Web Flow 584
essentials 589 Creating a flow
■
15.2
■
582
Spring Web Flow
591
Laying the flow groundwork 591
Flow variables 591 Start and end states 593 Gathering
customer information 594 Building a pizza order 601
Completing the order 605 A few finishing touches 608
■
■
■
■
15.3
Advanced web flow techniques
Using decision states
substates 614
15.4
■
Extracting subflows and using
Integrating Spring Web Flow with other frameworks
Jakarta Struts 619
15.5
612
611
Summary
622
■
JavaServer Faces 620
619
CONTENTS
16
Integrating with other web frameworks 623
16.1
Using Spring with Struts
624
Registering the Spring plug-in with Struts 626 Writing Springaware Struts actions 627 Delegating to Spring-configured
actions 629 What about Struts 2? 632
■
■
■
16.2
16.3
Working Spring into WebWork 2/Struts 2
Integrating Spring with Tapestry 636
Integrating Spring with Tapestry 3 637
Tapestry 4 641
16.4
Putting a face on Spring with JSF
■
633
Integrating Spring with
643
Resolving JSF-managed properties 644 Resolving Spring
beans 646 Using Spring beans in JSF pages 646
Exposing the application context in JSF 648
■
■
16.5
Ajax-enabling applications in Spring with DWR
Direct web remoting
DWR 659
16.6
Summary
650
■
Accessing Spring-managed beans
664
appendix A Setting up Spring 667
appendix B Testing with (and without) Spring 678
index 707
web content
web chapter
appendix C
appendix D
appendix E
appendix F
648
Building portlet applications
Spring XML configuration reference
Spring JSP tag library reference
Spring Web Flow definition reference
Customizing Spring configuration
xvii
preface
It was December 7, 2005. I was standing at the side of a large hotel meeting room
in Miami Beach, Florida. The room was filled with developers from all over the
world who had descended upon the beautiful sandy beaches of southern Florida
for a single purpose: to talk about Spring.
What can I say? It was a room full of nerds. Rather than soak in the sun and
surf, we all gathered inside to bask in the warm glow of our laptop screens to learn
more about our beloved framework from those who know it best.
On that particular night, we were hanging on the words of Spring’s creator,
Rod Johnson, as he presented the opening keynote for the conference. He spoke
of Spring’s origins and the successes it had enjoyed. Then he invited a few members of the Spring team to the podium to introduce new features that were to be
in the next version.
He wasn’t far into his presentation when Rod made an announcement that
caught everyone’s attention. We were all expecting these great new features to be
available in Spring 1.3, the supposed next version of Spring. Much to our surprise,
Rod informed us that there would be no Spring 1.3; the next version would be
Spring 2.0.
The decision to bump up the major version number of the next release isn’t
made lightly. Such an action connotes a significant advance in Spring. If the next
version of Spring would be 2.0, then we could expect major enhancements.
Indeed, ten months later, Spring 2.0 would be released with an abundance of new
capabilities, including:
xix
xx
PREFACE
■
Simplified XML configuration and the option to create custom configuration elements
■
Greatly simplified AOP and transactions
■
Support for Java 5 annotations for declaring aspects, transactions, and
required bean properties
■
The ability to create beans from scripts written in JRuby, Groovy, or BeanShell
■
New JDBC templates to support named parameters and Java 5 features
■
Improved JMS support, including receiving messages asynchronously (for
creating message-driven POJOs)
■
A new form-binding JSP tag library
■
Several convention-over-configuration improvements to reduce the amount
of XML required to configure Spring
■
Support for the Java Persistence API (JPA)
■
Enhanced bean scoping, including request and session scoping of beans for
web applications
■
The ability to perform dependency injection on objects that Spring doesn’t
create (such as domain objects)
At one point in his keynote, Rod said that if the wealth of new features being
introduced didn’t justify a jump to 2.0, then how would they ever be able to justify
a 2.0 release?
That’s not all. In addition to the work being done on the core Spring Framework, several interesting Spring-related projects were underway to provide additional capabilities on top of Spring. Among them:
■
Spring Web Flow, which is based on Spring MVC and enables development
of flow-based web applications
■
XFire, for exporting your Spring beans as SOAP web services
■
Spring-WS for creating contract-first web services
■
Spring Modules, which provides (among other things) declarative caching
and validation
■
Direct Web Remoting (DWR) for Ajax-enabling Spring beans
■
Lingo, which makes it possible to asynchronously invoke methods on
remote beans
PREFACE
xxi
Then it occurred to me: if all of these new advances in Spring didn’t justify a second edition of Spring in Action, then what would? As it turned out, Manning was
thinking the same thing.
And now, well over a year later, here’s the long-awaited update to Spring in
Action that covers many of the new features of Spring 2.0. It has taken me a lot
longer to finish than I had planned, but I hope that it was worth the wait. My goal
for this edition is the same as with the first: to share the joy of developing in
Spring. I hope this book will serve to enhance your enjoyment of Spring.
preface to the first edition
Software developers need to have a number of traits in order to practice their
craft well. First, they must be good analytical thinkers and problem solvers. A
developer’s primary role is to create software that solves business problems.
This requires analyzing customer needs and coming up with successful, creative solutions.
They also need to be curious. Developments in the software industry are moving targets, always evolving. New frameworks, new techniques, new languages, and
new methodologies are constantly emerging. Each one is a new tool that needs to
be mastered and added to the toolbox, allowing the developer to do his or her job
better and faster.
Then there is the most cherished trait of all, “laziness.” The kind of laziness
that motivates developers to work hard to seek out solutions with the least amount
of effort. It was with curiosity, a good dose of “laziness,” and all the analytical abilities we could muster that the two of us struck out together four years ago to find
new ways to develop software.
This was the time when open source software was reaching critical mass in the
Java community. Tons of open source frameworks were blossoming on the Java
landscape. In order to decide to adopt one, it had to hit the sweet spot of our
needs—it had to do 80% of what we needed right out of the box. And for any
functionality that was not right out of the box, the framework needed to be easily
extendible so that functionality too would be included. Extending didn’t mean
xxii
PREFACE TO THE FIRST EDITION
xxiii
kludging in some hack that was so ugly you felt dirty afterwards—it meant extending in an elegant fashion. That wasn’t too much to ask, right?
The first of these frameworks that gained immediate adoption on our team
was Ant. From the get-go, we could tell that Ant had been created by another
developer who knew our pain in building Java applications. From that moment
on, no more javac. No more CLASSPATH. All this with a straightforward (albeit
sometimes verbose) XML configuration. Huzzah! Life (and builds) just got easier.
As we went along, we began adopting more and more tools. Eclipse became
our IDE of choice. Log4J became our (and everybody else’s) default logging toolkit. And Lucene supplanted our commercial search solution. Each of these tools
met our criteria of filling a need while being easy to use, understand, and extend.
But something was lacking. These great tools were designed to help develop
software, like Ant and Eclipse, or to serve a very specific application need, like
searching in the case of Lucene and logging for Log4J. None of them addressed
the needs at the heart of enterprise applications: persistence, transactions, and
integration with other enterprise resources.
That all changed in the last year or so when we discovered the remarkable onetwo enterprise punch of Spring and Hibernate. Between these two frameworks
nearly all of our middle- and data-tier needs were met.
We first adopted Hibernate. It was the most intuitive and feature-rich object/
relational mapping tool out there. But it was by adopting Spring that we really got
our code to look good. With Spring’s dependency injection, we were able to get
rid of all our custom factories and configurers. In fact, that is the reason we first
integrated Spring into our applications. Its wiring allowed us to streamline our
application configurations and move away from homegrown solutions. (Hey,
every developer likes writing his own framework. But sometimes you just have to
let go!)
We quickly discovered a nice bonus: Spring also provided very easy integration
with Hibernate. This allowed us to ditch our custom Hibernate integration classes
and use Spring’s support instead. In turn, this led us directly to Spring’s support
for transparent persistence.
Look closely and you will see a pattern here. The more we used Spring, the
more we discovered new features. And each feature we discovered was a pleasure
to work with. Its web MVC framework worked nicely in a few applications. Its AOP
support has been helpful in several places, primarily security. The JDBC support
was quite nice for some smaller programs. Oh yeah, we also use it for scheduling.
And JNDI access. And email integration. When it comes to hitting development
sweet spots, Spring knocks the ball out of the park.
xxiv
PREFACE TO THE FIRST EDITION
We liked Spring so much, we decided somebody should write a book about it.
Fortunately, one of us had already written a book for Manning and knew how to
go about doing this sort of thing. Soon that “somebody who should write a book”
became us. In taking on this project we are trying to spread the gospel of Spring.
The Spring framework has been nothing but a joy for us to work with—we predict
it will be the same for you. And, we hope this book will be a pleasant vehicle for
you to get to that point.