Getting Started With Spring Framework, Second Edition J Sharma Ashish Sarin Framework A Hands On Guide To Begin Developing Ap

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 517 [warning: Documents this large are best viewed by clicking the View PDF Link!]

GettingstartedwithSpringFramework
SecondEdition
AshishSarin,JSharma
Tableofcontents
Preface
Howtousethisbook
Conventionsusedinthisbook
Feedbackandquestions
Abouttheauthors
Chapter1IntroductiontoSpringFramework
1-1Introduction
1-2SpringFrameworkmodules
1-3SpringIoCcontainer
1-4BenefitsofusingSpringFramework
Consistentapproachtomanaginglocalandglobaltransactions
Declarativetransactionmanagement
Security
JMX(JavaManagementExtensions)
JMS(JavaMessageService)
Caching
1-5AsimpleSpringapplication
Identifyingapplicationobjectsandtheirdependencies
CreatingPOJOclassescorrespondingtoidentifiedapplicationobjects
Creatingtheconfigurationmetadata
CreatinganinstanceofSpringcontainer
AccessbeansfromtheSpringcontainer
1-6FrameworksbuiltontopofSpring
1-7Summary
Chapter2SpringFrameworkbasics
2-1Introduction
2-2Programmingtointerfacesdesignprinciple
Scenario:Dependentclasscontainsreferencetotheconcreteclassofdependency
Scenario:Dependentclasscontainsreferencetotheinterfaceimplementedbythe
dependency
Spring’ssupportforprogrammingtointerfaces’designapproach
2-3DifferentapproachestoinstantiatingSpringbeans
Instantiatingbeansviastaticfactorymethods
Instantiatingbeansviainstancefactorymethods
2-4Dependencyinjectiontechniques
Setter-basedDI
Constructor-basedDI
2-5Beanscopes
Singleton
Prototype
Choosingtherightscopeforyourbeans
2-6Summary
Chapter3-Configuringbeans
3-1Introduction
3-2Beandefinitioninheritance
MyBank–Beandefinitioninheritanceexample
Whatgetsinherited?
3-3Constructorargumentmatching
Passingsimplevaluesandbeanreferencesusing<constructor-arg>element
Constructorargumentmatchingbasedontype
Constructorargumentmatchingbasedonname
3-4Configuringdifferenttypesofbeanpropertiesandconstructorarguments
Built-inpropertyeditorsinSpring
Specifyingvaluesfordifferentcollectiontypes
Specifyingvaluesforarrays
Defaultcollectionimplementationfor<list>,<set>and<map>elements
3-5Built-inpropertyeditors
CustomCollectionEditor
CustomMapEditor
CustomDateEditor
3-6RegisteringpropertyeditorswiththeSpringcontainer
CreatingaPropertyEditorRegistrarimplementation
ConfiguringtheCustomEditorConfigurerclass
3-7Concisebeandefinitionswithpandcnamespaces
p-namespace
c-namespace
3-8Springsutilschema
<list>
<map>
<set>
<properties>
<constant>
<property-path>
3-9FactoryBeaninterface
MyBankapplicationStoringeventsinthedatabase
MyBank–FactoryBeanexample
AccessingtheFactoryBeaninstance
3-10Summary
Chapter4-Dependencyinjection
4-1Introduction
4-2Innerbeans
4-3Explicitlycontrollingthebeaninitializationorderwithdepends-onattribute
MyBank–implieddependenciesbetweenbeans
Implicitdependencyproblem
4-4Singleton-andprototype-scopedbeansdependencies
Singleton-scopedbeansdependencies
Prototype-scopedbean’sdependencies
4-5Obtainingnewinstancesofprototypebeansinsidesingletonbeans
ApplicationContextAwareinterface
<lookup-method>element
<replaced-method>element
4-6Autowiringdependencies
byType
constructor
byName
default/no
Makingbeansunavailableforautowiring
Autowiringlimitations
4-7Summary
Chapter5-Customizingbeansandbeandefinitions
5-1Introduction
5-2Customizingbeansinitializationanddestructionlogic
MakingSpringinvokecleanupmethodspecifiedbythedestory-methodattribute
Cleanupmethodsandprototype-scopedbeans
Specifyingdefaultbeaninitializationanddestructionmethodsforallbeans
InitializingBeanandDisposableBeanlifecycleinterfaces
JSR250s@PostConstructand@PreDestroyannotations
5-3InteractingwithnewlycreatedbeaninstancesusingBeanPostProcessor
BeanPostProcessorexample–Validatingbeaninstances
BeanPostProcessorexample–Resolvingbeandependencies
BeanPostProcessorbehaviorforFactoryBeans
RequiredAnnotationBeanPostProcessor
DestructionAwareBeanPostProcessor
5-4ModifyingbeandefinitionsusingBeanFactoryPostProcessor
BeanFactoryPostProcessorexample
PropertySourcesPlaceholderConfigurer
PropertyOverrideConfigurer
5-5Summary
Chapter6-Annotation-drivendevelopmentwithSpring
6-1Introduction
6-2IdentifyingSpringcomponentswith@Component
6-3@Autowired-autowiringdependenciesbytype
6-4@Qualifierautowiringdependenciesbyname
6-5JSR330s@Injectand@Namedannotations
6-6JSR250s@Resourceannotation
6-7@Scope,@Lazy,@DependsOnand@Primaryannotations
6-8Simplifyingcomponentconfigurationusing@Valueannotation
6-9ValidatingobjectsusingSpringsValidatorinterface
6-10SpecifyingconstraintsusingJSR303annotations
JSR303supportinSpring
6-11ProgrammaticallyconfiguringSpringbeansusing@Configurationand@Bean
annotations
6-12Summary
Chapter7-DatabaseinteractionusingSpring
7-1Introduction
7-2MyBankapplicationsrequirements
7-3DevelopingtheMyBankapplicationusingSpringsJDBCmodule
Configuringadatasource
CreatingDAOsthatuseSpring’sJDBCmoduleclasses
7-4DevelopingtheMyBankapplicationusingHibernate
ConfiguringSessionFactoryinstance
CreatingDAOsthatuseHibernateAPIfordatabaseinteraction
7-5TransactionmanagementusingSpring
MyBankstransactionmanagementrequirements
Programmatictransactionmanagement
Declarativetransactionmanagement
Spring’ssupportforJTA
7-6Summary
Chapter8-Messaging,emailing,asynchronousmethodexecution,andcachingusing
Spring
8-1Introduction
8-2MyBankapplicationsrequirements
8-3SendingJMSmessages
ConfiguringActiveMQbrokertoruninembeddedmode
ConfiguringaJMSConnectionFactory
SendingJMSmessagesusingJmsTemplate
SendingJMSmessageswithinatransaction
DynamicJMSdestinationsandJmsTemplateconfiguration
JmsTemplateandmessageconversion
8-4ReceivingJMSmessages
SynchronouslyreceivingJMSmessagesusingJmsTemplate
AsynchronouslyreceivingJMSmessagesusingmessagelistenercontainers
8-5Sendingemails
8-6Taskschedulingandasynchronousexecution
TaskExecutorinterface
TaskSchedulerinterface
@Asyncand@Scheduledannotations
8-7Caching
ConfiguringaCacheManager
Cachingannotations-@Cacheable,@CacheEvictand@CachePut
8-8RunningtheMyBankapplication
8-9Summary
Chapter9-Aspect-orientedprogramming
9-1Introduction
9-2AsimpleAOPexample
9-3SpringAOPframework
Proxycreation
expose-proxyattribute
9-4Pointcutexpressions
@Pointcutannotation
executionandargspointcutdesignators
beanpointcutdesignator
Annotations-basedpointcutdesignators
9-5Advicetypes
Beforeadvice
Afterreturningadvice
Afterthrowingadvice
Afteradvice
Aroundadvice
9-6SpringAOP-XMLschema-style
ConfiguringanAOPaspect
Configuringanadvice
Associatingapointcutexpressionwithanadvice
9-7Summary
Chapter10–SpringWebMVCbasics
10-1Introduction
10-2Directorystructureofsamplewebprojects
10-3Understandingthe‘HelloWorldwebapplication
HelloWorldController.java–HelloWorldwebapplicationscontrollerclass
helloworld.jsp–JSPpagethatshowstheHelloWorld!!message
myapp-config.xmlWebapplicationcontextXMLfile
web.xmlWebapplicationdeploymentdescriptor
10-4DispatcherServletthefrontcontroller
AccessingServletContextandServletConfigobjects
10-5Developingcontrollersusing@Controllerand@RequestMappingannotations
Developinga‘HelloWorld’webapplicationusinganannotatedcontroller
10-6MyBankwebapplicationsrequirements
10-7SpringWebMVCannotations-@RequestMappingand@RequestParam
Mappingrequeststocontrollersorcontrollermethodsusing@RequestMapping
@RequestMappingannotatedmethodsarguments
@RequestMappingannotatedmethodsreturntypes
Passingrequestparameterstocontrollermethodsusing@RequestParam
10-8Validation
10-9Handlingexceptionsusing@ExceptionHandlerannotation
10-11LoadingrootwebapplicationcontextXMLfile(s)
10-12Summary
Chapter11–ValidationanddatabindinginSpringWebMVC
11-1Introduction
11-2Addingandretrievingmodelattributesusing@ModelAttributeannotation
Addingmodelattributesusingmethod-level@ModelAttributeannotation
Retrievingmodelattributesusing@ModelAttributeannotation
Requestprocessingand@ModelAttributeannotatedmethods
Behaviorof@ModelAttributeannotatedmethodarguments
RequestToViewNameTranslator
11-3Cachingmodelattributesusing@SessionAttributesannotation
11-4DatabindingsupportinSpring
WebDataBinderdatabinderforwebrequestparameters
ConfiguringaWebDataBinderinstance
Allowingordisallowingfieldsfromdatabindingprocess
InspectingdatabindingandvalidationerrorsusingBindingResultobject
11-5ValidationsupportinSpring
ValidatingmodelattributesusingSpringsValidatorinterface
SpecifyingconstraintsusingJSR303annotations
ValidatingobjectsthatuseJSR303annotations
11-6Springsformtaglibrary
HTML5supportinSpringsformtaglibrary
11-7Summary
Chapter12–DevelopingRESTfulwebservicesusingSpringWebMVC
12-1Introduction
12-2Fixeddepositwebservice
12-3ImplementingaRESTfulwebserviceusingSpringWebMVC
JSON(JavaScriptObjectNotation)
FixedDepositWSwebserviceimplementation
12-4AccessingRESTfulwebservicesusingRestTemplate
12-5ConvertingJavaobjectstoHTTPrequestsandresponsesandviceversausing
HttpMessageConverter
12-6@PathVariableand@MatrixVariableannotations
12-7Summary
Chapter13–MoreSpringWebMVCinternationalization,fileuploadand
asynchronousrequestprocessing
13-1Introduction
13-2Pre-andpost-processingrequestsusinghandlerinterceptors
Implementingandconfiguringahandlerinterceptor
13-3Internationalizingusingresourcebundles
MyBankwebapplicationsrequirements
InternationalizingandlocalizingMyBankwebapplication
13-4Asynchronouslyprocessingrequests
Asynchronousrequestprocessingconfiguration
ReturningCallablefrom@RequestMappingmethods
ReturningDeferredResultfrom@RequestMappingmethods
Settingdefaulttimeoutvalue
Interceptingasynchronousrequests
13-5TypeconversionandformattingsupportinSpring
CreatingacustomConverter
ConfiguringandusingacustomConverter
CreatingacustomFormatter
ConfiguringacustomFormatter
CreatingAnnotationFormatterFactorytoformatonly@AmountFormatannotated
fields
ConfiguringAnnotationFormatterFactoryimplementation
13-6FileuploadsupportinSpringWebMVC
UploadingfilesusingCommonsMultipartResolver
UploadingfilesusingStandardServletMultipartResolver
13-7Summary
Chapter14–SecuringapplicationsusingSpringSecurity
14-1Introduction
14-2SecurityrequirementsoftheMyBankwebapplication
14-3SecuringMyBankwebapplicationusingSpringSecurity
Webrequestsecurityconfiguration
Authenticationconfiguration
SecuringJSPcontentusingSpringSecuritysJSPtablibrary
Securingmethods
14-4MyBankwebapplication-securingFixedDepositDetailsinstancesusingSpring
Security’sACLmodule
Deployingandusingch14-bankapp-db-securityproject
DatabasetablestostoreACLanduserinformation
Userauthentication
Webrequestsecurity
JdbcMutableAclServiceconfiguration
Method-levelsecurityconfiguration
Domainobjectinstancesecurity
ManagingACLentriesprogrammatically
MutableAclandsecurity
14-5Summary
AppendixAImportinganddeployingsampleprojectsinEclipseIDE(orIntelliJ
IDEA)
A-1Settingupthedevelopmentenvironment
A-2ImportingasampleprojectintoEclipseIDE(orIntelliJIDEA)
Importingasampleproject
ConfiguringtheM2_REPOclasspathvariableintheEclipseIDE
A-3ConfiguringEclipseIDEwithTomcat7server
A-4DeployingawebprojectonTomcat7server
RunningtheTomcat7serverinembeddedmode
Preface
Howtousethisbook
Downloadsampleprojects
This book comes with many sample projects that you can download from the following Google Code
project:http://code.google.com/p/getting-started-with-spring-framework-2edition/.Youcandownloadthe
sampleprojectsasasingleZIPfileoryoucancheckoutthesampleprojectsusingSVN.Formoredetails,
refertotheaboveURL.
ImportsampleprojectsintoyourEclipseorIntelliJIDEAIDE
IfyouseeIMPORTchapter<chapter-number>/<projectname>at anypoint while reading the book,
youshouldimportthespecifiedprojectintoyourEclipseorIntelliJIDEAIDE(oranyotherIDEthatyou
areusing).ThesampleprojectsuseMaven3.xbuildtoolforbuildingtheproject;therefore,youllfinda
pom.xmlfileinsideeachoftheprojects.Apom.xmlfileisalsoprovidedattherootofthesourcecode
distribution,whichbuildsalltheprojects.
ReferappendixAtoseethestepsrequiredforimportingandrunningthesampleprojects.
Refertocodeexamples
Each example listing specifies the sample project name (usingProject label) and the location of the
sourcefile(usingSourcelocationlabel).IftheProjectandSourcelocationlabelsarenotspecified,you
canassumethatthecodeshownintheexamplelistingisnotbeingusedanywhereinthesampleprojects,
andithasbeenshownpurelytosimplifyunderstanding.
Conventionsusedinthisbook
Italicshasbeenusedforemphasizingterms
Comic Sans MS has been used for example listings, Java code, configuration details in XML and
propertiesfiles
Comic Sans MS has been used in example listings to highlight important parts of the code or
configuration
ANOTEhighlightsanimportaintpoint.
Feedbackandquestions
You can post your feedback and questions to the authors in the following Google Groups forum:
https://groups.google.com/forum/#!forum/getting-started-with-spring-framework
Abouttheauthors
AshishSarinisaSunCertifiedEnterpriseArchitectwithmorethan14yearsofexperienceinarchitecting
applications.HeistheauthorofSpringRoo1.1Cookbook(byPacktPublishing)andPortletsinAction
(byManningPublications)
JSharmaisafreelanceJavadeveloperwithextensiveexperienceindevelopingSpringapplications.
Chapter1IntroductiontoSpringFramework
1-1Introduction
InthetraditionalJavaenterpriseapplicationdevelopmentefforts,itwasadevelopersresponsibilityto
createwell-structured,maintainableandeasilytestableapplications.Thedevelopersusedmyriaddesign
patternstoaddressthesenon-businessrequirementsofanapplication.Thisnotonlyledtolowdeveloper
productivity,butalsoadverselyaffectedthequalityofdevelopedapplications.
Spring Framework (or ‘Spring in short) is an open source application framework from SpringSource
(http://www.springsource.org) that simplifies developing Java enterprise applications. It provides the
infrastructurefordevelopingwell-structured,maintainableandeasilytestableapplications.Whenusing
Spring Framework, a developer only needs to focus on writing the business logic of the application,
resultinginimproveddeveloperproductivity.YoucanuseSpringFrameworktodevelopstandaloneJava
applications,webapplications,applets,oranyothertypeofJavaapplication.
ThischapterstartsoffwithanintroductiontoSpringFrameworkmodulesanditsbenefits.Attheheartof
SpringFrameworkisitsInversionofControl(IoC)container,whichprovidesdependencyinjection(DI)
feature.  This chapter introduces SpringsDIfeature and IoC container, and shows how to develop a
standalone Java application using Spring. Towards the end of this chapter, we’ll look at some of the
SpringSource’sprojectsthatuseSpringFrameworkastheirfoundation.Thischapterwillsetthestagefor
theremainingchaptersthatdelvedeeperintotheSpringFramework.
NOTEInthisbook,we’lluseanexampleInternetBankingapplication,MyBank,tointroduceSpring
Frameworkfeatures.
1-2SpringFrameworkmodules
SpringFrameworkconsistsofmultiplemodulesthataregroupedbasedontheapplicationdevelopment
featurestheyaddress.ThefollowingtabledescribesthedifferentmodulegroupsinSpringFramework:
Modulegroup Description
Corecontainer
ContainsmodulesthatformthefoundationofSpringFramework.Themodulesinthisgroup
provideSpringsDIfeatureandIoCcontainerimplementation.
AOPand
instrumentation
Contains modules that support AOP (Aspect-oriented Programming) and class
instrumentation.
DataAccess/Integration
Contains modules that simplify interaction with databases and messaging providers. This
modulegroupalsocontainsmodulesthatsupportprogrammaticanddeclarativetransaction
management,andobject/XM Lmappingimplementations,likeJAXBandCastor.
Web Containsmodulesthatsimplifydevelopingwebandportletapplications.
Test Containsasinglemodulethatsimplifiescreatingunitandintegrationtests.
TheabovetableshowsthatSpringcoverseveryaspectofenterpriseapplicationdevelopment;youcan
useSpringfordevelopingwebapplications,accessingdatabases,managingtransactions,creatingunitand
integration tests, and so on. The Spring Framework modules are designed in such a way that youonly
needtoincludethemodulesthatyourapplicationneeds.Forinstance,touseSpringsDIfeatureinyour
application,youonlyneedtoincludethemodulesgroupedunderCorecontainer.Asyouprogressthrough
thisbook,you’llfinddetailsofsomeofthemodulesthatarepartofSpring,andexamplesthatshowhow
theyareusedindevelopingapplications.
Thefollowingfigureshowstheinter-dependenciesofdifferentmodulesofSpring:
Figure1-1Springmodulesinter-dependencies
YoucaninferfromtheabovefigurethatthemodulescontainedintheCorecontainergrouparecentralto
theSpringFramework,andothermodulesdependonit.Equallyimportantarethemodulescontainedin
theAOPandinstrumentationgroupbecausetheyprovideAOPfeaturestoothermodulesintheSpring
Framework.
Now,thatyouhavesomebasicideaabouttheareasofapplicationdevelopmentcoveredbySpring,let’s
lookattheSpringIoCcontainer.
1-3SpringIoCcontainer
AJavaapplicationconsistsofobjectsthatinteractwitheachothertoprovideapplicationbehavior.The
objectswithwhichanobjectinteractsarereferredtoasitsdependencies.Forinstance,ifanobjectX
interactswithobjectsYandZ,thenYandZaredependenciesofobjectX.DIisadesignpatterninwhich
thedependenciesofanobjectaretypicallyspecifiedasargumentstoitsconstructorandsettermethods.
And,thesedependenciesareinjectedintotheobjectwhenitscreated.
In a Spring application, Spring IoC container (also referred to as Spring container) is responsible for
creating application objects and injecting their dependencies. The application objects that the Spring
containercreatesandmanagesarereferredasbeans.AstheSpringcontainerisresponsibleforputting
togetherapplicationobjects,youdon’tneedtoimplementdesignpatterns,likeFactory,ServiceLocator,
andsoon,tocomposeyourapplication.DIisalsoreferredtoasInversionofControl(IoC)becausethe
responsibilityofcreatingandinjectingdependenciesisnotwiththeapplicationobjectbutwiththeSpring
container.
LetssaythattheMyBankapplication(whichisthenameofoursampleapplication)containstwoobjects,
FixedDepositController and FixedDepositService. The following example listing shows that the
FixedDepositControllerobjectdependsonFixedDepositServiceobject:
Examplelisting1-1:FixedDepositControllerclass
publicclassFixedDepositController{
privateFixedDepositServicefixedDepositService;
publicFixedDepositController(){
fixedDepositService=newFixedDepositService();
}

publicbooleansubmit(){
//--savethefixeddepositdetails
fixedDepositService.save(.....);
}
}
In the above example listing, FixedDepositControllers constructor creates an instance of
FixedDepositService which is later used in FixedDepositControllers submit method. As
FixedDepositController interacts with FixedDepositService, FixedDepositService represents a
dependencyofFixedDepositController.
To configure FixedDepositController as a Spring bean, you first need to modify the
FixedDepositControllerclassofexamplelisting1-1suchthatitacceptsFixedDepositServicedependency
as a constructor argument or as a setter method argument. The following example listing shows the
modifiedFixedDepositControllerclass:
Example listing 1-2: FixedDepositController class – FixedDepositService is passed as a constructor
argument
publicclassFixedDepositController{
privateFixedDepositServicefixedDepositService;
publicFixedDepositController(FixedDepositServicefixedDepositService){
this.fixedDepositService=fixedDepositService;
}

publicbooleansubmit(){
//--savethefixeddepositdetails
fixedDepositService.save(.....);
}
}
TheaboveexamplelistingshowsthattheFixedDepositServiceinstanceisnowpassedasaconstructor
argumenttotheFixedDepositControllerinstance.Now,theFixedDepositServiceclasscanbeconfigured
as a Spring bean. Notice that the FixedDepositController class doesnt implement or extend from any
Springinterfaceorclass.
Foragivenapplication,informationaboutapplicationobjectsandtheirdependenciesisspecifiedusing
configurationmetadata. Spring IoC container reads applications configuration metadata to instantiate
applicationobjectsandinjecttheirdependencies.Thefollowingexamplelistingshowstheconfiguration
metadata(inXMLformat)foranapplicationthatconsistsofMyControllerandMyServiceclasses:
Examplelisting1-3:Configurationmetadata
<beans.....>
<beanid="myController"class="sample.spring.controller.MyController">
<constructor-argindex="0"ref="myService"/>
</bean>
<beanid="myService"class="sample.spring.service.MyService"/>
</beans>
Intheaboveexamplelisting,each<bean>elementdefinesanapplicationobjectthatismanagedbythe
Springcontainer,andthe<constructor-arg>elementspecifiesthataninstanceofMyServiceispassedas
anargumenttoMyControllersconstructor.The<bean>elementisdiscussedindetaillaterinthischapter,
andthe<constructor-arg>elementisdiscussedinchapter2.
Spring container reads the configuration metadata (like the one shown in example listing 1-3) of an
application and creates the application objects defined by <bean> elements and injects their
dependencies. Spring container makes use ofJava Reflection API
(http://docs.oracle.com/javase/tutorial/reflect/index.html) to create application objects and inject their
dependencies.ThefollowingfiguresummarizeshowtheSpringcontainerworks:
Figure 1-2 Spring container reads applications configuration metadata and creates a fully-configured
application
TheconfigurationmetadatacanbesuppliedtotheSpringcontainerviaXML(asshowninexamplelisting
1-3),Javaannotations(referchapter6)andalsothroughtheJavacode(referchapter6).
AstheSpringcontainerisresponsibleforcreatingandmanagingapplicationobjects,enterpriseservices
(like transaction management, security, remote access, and so on) can be transparently applied to the
objectsbytheSpringcontainer.TheabilityoftheSpringcontainertoenhancetheapplicationobjectswith
additional functionality makes it possible for you to model your application objects as simple Java
objects(alsoreferredtoasPOJOsorPlainOldJavaObjects).JavaclassescorrespondingtoPOJOs
are referred to as POJO classes, which are nothing but Java classes that dont implement or extend
framework-specificinterfacesorclasses.Theenterpriseservices,liketransactionmanagement,security,
remoteaccess,andsoon,requiredbythesePOJOsaretransparentlyprovidedbytheSpringcontainer.
Now,thatweknowhowSpringcontainerworks,letslookatsomeexamplesthatdemonstratebenefitsof
developingapplicationsusingSpring.
1-4BenefitsofusingSpringFramework
Intheprevioussection,wediscussedthefollowingbenefitsofusingSpring:
§Springsimplifiescomposing Javaapplications bytakingcare ofcreating applicationobjects and
injectingtheirdependencies
§SpringpromotesdevelopingapplicationsasPOJOs
SpringalsosimplifiesinteractionwithJMSproviders,JNDI,MBeanservers,emailservers,databases,
andsoon,byprovidingalayerofabstractionthattakescareoftheboilerplatecode.
Lets take a quick look at a few examples to better understand the benefits of developing applications
usingSpring.
Consistentapproachtomanaginglocalandglobaltransactions
If you are using Spring for developingtransactional applications, you can use Springs declarative
transactionmanagementsupporttomanagetransactions.
ThefollowingexamplelistingshowstheFixedDepositServiceclassofMyBankapplication:
Examplelisting1-4–FixedDepositServiceclass
publicclassFixedDepositService{
publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}
publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....}
}
TheFixedDepositService class is a POJO class that defines methods to create and retrieve details of
fixeddeposits.Thefollowingfigureshowstheformforcreatinganewfixeddeposit:
Figure1-3HTMLformforcreatinganewfixeddeposit
Acustomerentersthefixeddepositamount,tenureandemailidinformationintheaboveformandclicks
theSave button to create a new fixed deposit. The FixedDepositServices createFixedDeposit method
(referexamplelisting1-1)isinvokedtocreatethefixeddeposit.ThecreateFixedDepositmethoddebits
theamountenteredbythecustomerfromhisbankaccount,andcreatesafixeddepositofthesameamount.
LetssaythatinformationaboutthebankbalanceofcustomersisstoredinBANK_ACCOUNT_DETAILS
databasetable,andthefixeddepositdetailsarestoredinFIXED_DEPOSIT_DETAILSdatabasetable.If
a customer creates a fixed deposit of amount x, amount x is subtracted from the
BANK_ACCOUNT_DETAILStable,andanewrecordisinsertedinFIXED_DEPOSIT_DETAILStable
toreflectthenewlycreatedfixeddeposit.IfBANK_ACCOUNT_DETAILStableisnotupdatedoranew
recordisnotinsertedinFIXED_DEPOSIT_DETAILStable,it’llleavethesysteminaninconsistentstate.
ThismeansthecreateFixedDepositmethodmustbeexecutedwithinatransaction.
The database used by the MyBank application represents a transactional resource. In the traditional
approachtoperforma setof databasemodificationsasasingleunitof work,youllfirstdisableauto-
commit mode of JDBC connection, then execute SQL statements, and finally commit (or rollback) the
transaction. The following example listing shows how to manage database transactions in the
createFixedDepositmethodusingthetraditionalapproach:
Examplelisting1-5–ProgrammaticallymanagingdatabasetransactionusingJDBCConnectionobject
importjava.sql.Connection;
importjava.sql.SQLException;
publicclassFixedDepositService{
publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}

publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){
Connectioncon=.....;
try{
con.setAutoCommit(false);
//--executeSQLstatementsthatmodifydatabasetables
con.commit();
}catch(SQLExceptionsqle){
if(con!=null){
con.rollback();
}
}
.....
}
}
TheaboveexamplelistingshowsthatthecreateFixedDepositmethodprogrammaticallymanagesdatabase
transactionusingJDBCConnectionobject.Thisapproachissuitableforapplicationscenariosinwhicha
singledatabaseisinvolved.Transactionsthatareresource-specific,likethetransactionassociatedwitha
JDBCConnection,arereferredtoaslocaltransactions.
When multiple transactional resources are involved, JTA (Java Transaction API) is used for managing
transactions.Forinstance,ifyouwanttosendaJMSmessagetoamessagingmiddleware(atransactional
resource)andupdateadatabase(anothertransactionalresource)inthesametransaction,youmustusea
JTA transaction manager to manage transactions. JTA transactions are also referred to asglobal (or
distributed)transactions.TouseJTA,youfetchUserTransactionobject(whichispartofJTAAPI)from
JNDIandprogrammaticallystartandcommit(orrollback)transactions.
As you can see, you can either useJDBC Connection (for local transactions) or UserTransaction (for
globaltransactions)objecttoprogrammaticallymanage transactions.Itisimportanttonotethatalocal
transactioncannot run within a global transaction. This means that if you want database updates in
createFixedDepositmethod(referexamplelisting1-5)tobepartofaJTAtransaction,youneedtomodify
thecreateFixedDepositmethodtousetheUserTransactionobjectfortransactionmanagement.
Spring simplifies transaction management by providing a layer of abstraction that gives aconsistent
approach to managing both local and global transactions.  This means that if you write the
createFixedDepositmethod(referexamplelisting1-5)usingSpringstransactionabstraction,youdont
needtomodifythemethodwhenyouswitchfromlocaltoglobaltransactionmanagement,orviceversa.
Springstransactionabstractionisexplainedinchapter7.
Declarativetransactionmanagement
Springgivesyoutheoptiontousedeclarativetransactionmanagement.Youcanannotateamethodwith
Springs@TransactionalannotationandletSpringhandletransactions,asshownhere:
Examplelisting1-6–@Transactionalannotationusage
importorg.springframework.transaction.annotation.Transactional;
publicclassFixedDepositService{
publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}

@Transactional
publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....}
}
TheaboveexamplelistingshowsthattheFixedDepositServiceclassdoesntimplementorextendfrom
any Spring-specific interface or class to use Springs transaction management facility. The Spring
Framework transparently provides transaction management feature to @Transactional annotated
createFixedDeposit method. This shows that Spring is a non-invasive framework because it doesnt
require your application objects to be dependent upon Spring-specific classes or interfaces. Also, you
dontneedtodirectlyworkwithtransactionmanagementAPIstomanagetransactions.
Security
Security is an important aspect of any Java application. Spring Security
(http://static.springsource.org/spring-security/site/) is a SpringSources project that is built on top of
SpringFramework.SpringSecurityprovidesauthenticationandauthorizationfeaturesthatyoucanusefor
securingJavaapplications.
Lets say that the following 3 user roles have been identified for the MyBank application:
LOAN_CUSTOMER, SAVINGS_ACCOUNT_CUSTOMER and APPLICATION_ADMIN. A customer
mustbeassociatedwiththeSAVINGS_ACCOUNT_CUSTOMERortheAPPLICATION_ADMINroleto
invokethecreateFixedDepositmethod of FixedDepositService class (refer example listing 1-6). Using
Spring Security youcan easily address this requirementby annotating createFixedDeposit method with
SpringSecuritys@Securedannotation,asshowninthefollowingexamplelisting:
Examplelisting1-7–SecuredcreateFixedDepositmethod
importorg.springframework.transaction.annotation.Transactional;
importorg.springframework.security.access.annotation.Secured;
publicclassFixedDepositService{
publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}
@Transactional
@Secured({"SAVINGS_ACCOUNT_CUSTOMER","APPLICATION_ADMIN"})
publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....}
}
If you annotate a method with Spring Securitys @Secured annotation, security feature is transparently
applied to the method by the Spring Security framework. The above example listing shows that for
implementingmethod-levelsecurityyoudontneedtoextendorimplementanySpring-specificclassesor
interfaces.Also,youdontneedtowritesecurity-relatedcodeinyourbusinessmethods.
SpringSecurityframeworkisdiscussedindetailinchapter14.
JMX(JavaManagementExtensions)
SpringsJMXsupportsimplifiesincorporatingJMXtechnologyinyourapplications.
LetssaythatthefixeddepositfacilityofMyBankapplicationshouldonlybeavailabletocustomersfrom
9:00 AM to 6:00 PM everyday. To address this requirement, a variable is added to the
FixedDepositServiceclass,whichactsasaflagindicatingwhetherthefixeddepositserviceisactiveor
inactive.ThefollowingexamplelistingshowstheFixedDepositServiceclassthatusessuchaflag:
Examplelisting1-8–FixedDepositServicewithactivevariable
publicclassFixedDepositService{
privatebooleanactive;

publicFixedDepositDetailsgetFixedDepositDetails(.....){
if(active){.....}
}
publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){
if(active){.....}
}
publicvoidactivateService(){
active=true;
}
publicvoiddeactivateService(){
active=false;
}
}
TheaboveexamplelistingshowsthatavariablenamedactiveisaddedtotheFixedDepositServiceclass.
If the value of the active variable is true, the getFixedDepositDetails and createFixedDeposit methods
work as expected. If the value of the active variable is false, the getFixedDepositDetails and
createFixedDeposit methods throw an exception indicating that the fixed deposit service is currently
inactive.TheactivateServiceanddeactivateServicemethodssetthevalueofactivevariabletotrueand
false,respectively.
Now, who calls the activateService and deactivateService methods? Let’s say a separate scheduler
application, Bank App Scheduler, runs at 9:00 AM and 6:00 PM to execute activateService and
deactivateService methods, respectively. The Bank App Scheduler application uses JMX (Java
ManagementExtensions)APItoremotelyinteractwithFixedDepositServiceinstance.
NOTE Refer to the following article to learn more about JMX:
http://docs.oracle.com/javase/tutorial/jmx/index.html.
AsBankAppSchedulerusesJMXtochangethevalueoftheactivevariableoftheFixedDepositService
instance,youneedtoregistertheFixedDepositServiceinstanceasamanagedbean(orMBean)withan
MBean server, and expose FixedDepositService’s activateService and deactivateService methods as
JMXoperations.InSpring,youregisterinstancesofaclasswiththeMBeanserverbyannotatingtheclass
withSprings @ManagedResource annotation, and expose the methods of the class as JMX operations
usingSprings@ManagedOperationannotation.
Thefollowingexamplelistingshowsusageof@ManagedResourceand@ManagedOperationannotations
to register instances of the FixedDepositService class with the MBean server, and to expose its
activateServiceanddeactivateServicemethodsasJMXoperations:
Examplelisting1-9–FixedDepositServiceclassthatusesSpringsJMXsupport
importorg.springframework.jmx.export.annotation.ManagedOperation;
importorg.springframework.jmx.export.annotation.ManagedResource;
@ManagedResource(objectName="fixed_deposit_service:name=FixedDepositService")
publicclassFixedDepositService{
privatebooleanactive;
publicFixedDepositDetailsgetFixedDepositDetails(.....){
if(active){.....}
}
publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){
if(active){.....}
}
@ManagedOperation
publicvoidactivateService(){
active=true;
}
@ManagedOperation
publicvoiddeactivateService(){
active=false;
}
}
The above example listing shows that the FixedDepositService class doesnt directly use JMX API to
registeritsinstanceswiththeMBeanserverandtoexposeitsmethodsasJMXoperations.
JMS(JavaMessageService)
SpringsJMSsupportsimplifiessendingandreceivingmessagesfromJMSproviders.
InMyBankapplication,whenacustomersubmitsarequesttoreceivedetailsoftheirfixeddepositsvia
email, the FixedDepositService sends the request details to a JMS messaging middleware (like
ActiveMQ).Therequestislaterprocessedbyamessagelistener.SpringsimplifiesinteractionwithJMS
providers by providing a layer of abstraction. The following example listing shows how
FixedDepositServiceclasssendsrequestdetailstoaJMSproviderusingSpringsJmsTemplate:
Examplelisting1-10–FixedDepositServicethatsendsJMSmessages
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.jms.core.JmsTemplate;
publicclassFixedDepositService{
@Autowired
privatetransientJmsTemplatejmsTemplate;
.....
publicbooleansubmitRequest(Requestrequest){
jmsTemplate.convertAndSend(request);
}
}
TheaboveexamplelistingshowsthattheFixedDepositServicedefinesavariableoftypeJmsTemplate,
andisannotatedwithSprings@Autowiredannotation.Fornow,youcanassumethatthe@Autowired
annotationprovidesaccesstoaJmsTemplateinstance.TheJmsTemplateinstanceknowsabouttheJMS
destinationtowhichtheJMSmessageistobesent.HowtheJmsTemplateisconfiguredisdescribedin
detail in chapter 8. The FixedDepositServices submitRequest method invokes JmsTemplate’s
convertAndSend method to send request details (represented by Request argument of submitRequest
method)asaJMSmessagetotheJMSprovider.
Onceagain,theaboveexamplelistingshowsthatifyouareusingSpringFrameworktosendmessagesto
JMSproviders,thenyoudontneedtodirectlydealwithJMSAPI.
Caching
Springscacheabstractionprovidesaconsistentapproachtousecachinginyourapplication.
Itscommontousecachingsolutionstoimprovetheperformanceofanapplication.MyBankapplication
usesacachingproducttoimprovetheperformanceofreadoperationsforfixeddepositdetails.Spring
Frameworksimplifiesinteractingwithdifferentcachingsolutionsbyabstractingcaching-relatedlogic.
ThefollowingexamplelistingshowsthattheFixedDepositServicesgetFixedDepositDetailsmethoduses
Springscacheabstractionfeaturetocachefixeddepositdetails:
Examplelisting1-11–FixedDepositServicethatcachesfixeddepositdetails
importorg.springframework.cache.annotation.Cacheable;
publicclassFixedDepositService{

@Cacheable("FixedDeposits")
publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}

publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....}
}
In the above example listing, Springs @Cacheable annotation indicates that the fixed deposit details
returned by the getFixedDepositDetails method are cached. If the getFixedDepositDetails method is
invoked with the same argument value(s), the getFixedDepositDetails method is not executed, and the
fixeddepositdetailsarereturnedfromthecache.ThisshowsthatifyouareusingSpringFrameworkyou
dontneedtowritecaching-relatedlogicinyourclasses.Springscacheabstractionisexplainedindetail
inchapter8.
In this section, we saw that Spring Framework simplifies developing enterprise applications by
transparentlyprovidingservicestoPOJOs,thereby shieldingdevelopersfrom lowerlevelAPIdetails.
Spring also provides easy integration with standard frameworks, like Hibernate, iBATIS, Quartz, JSF,
Struts,EJB,andsoon,whichmakesSpringanidealchoiceforenterpriseapplicationdevelopment.
Now,thatwehavelookedatsomeofthebenefitsofusingSpringFramework,letstakealookathowto
developasimpleSpringapplication.
1-5AsimpleSpringapplication
Inthissection,we’lllookatasimpleSpringapplicationthatusesSpringsDIfeature.TouseSpringsDI
featureinanapplication,followthesesteps:
1.identifyapplicationobjectsandtheirdependencies
2.createPOJOclassescorrespondingtotheapplicationobjectsidentifiedinstep1
3.createconfigurationmetadatathatdepictsapplicationobjectsandtheirdependencies
4.createaninstanceofSpringIoCcontainerandpasstheconfigurationmetadatatoit
5.accessapplicationobjectsfromtheSpringIoCcontainerinstance
LetsnowlookatabovementionedstepsinthecontextofMyBankapplication.
Identifyingapplicationobjectsandtheirdependencies
WediscussedearlierthattheMyBankapplicationshowsaformforcreatingafixeddeposit(referfigure
1-3) to its users for creating a fixed deposit. The following sequence diagram shows the application
objects(andtheirinteraction)thatcomeintopicturewhentheusersubmitstheform:
Figure1-4MyBanksapplicationobjectsandtheirdependencies
In the above sequence diagram, FixedDepositController represents a web controller that receives the
requestwhentheformissubmitted.ThefixeddepositdetailsarecontainedintheFixedDepositDetails
object.TheFixedDepositController invokes the createFixedDeposit method of FixedDepositService (a
servicelayerobject).Then,FixedDepositServiceinvokesFixedDepositDaoobject(adataaccessobject)
to save the fixed deposit details in the applications data store. So, we can interpret from the above
diagram that FixedDepositService is a dependency of FixedDepositController object, and
FixedDepositDaoisadependencyofFixedDepositServiceobject.
IMPORT chapter 1/ch01-bankapp-xml (This project shows a simple Spring application that uses
Springs DI feature. To run the application, execute the main method of the MyBankApp class of this
project)
CreatingPOJOclassescorrespondingtoidentifiedapplicationobjects
Onceyouhaveidentifiedapplicationobjects,thenextstep istocreatePOJOclassescorresponding to
these application objects. POJO classes corresponding to the FixedDepositController,
FixedDepositService and FixedDepositDao application objects are available in ch01-bankapp-xml
project.Thech01-bankapp-xmlprojectrepresentsasimplifiedversionofMyBankapplicationthatuses
SpringsDIfeature.Youshouldimportthech01-bankapp-xmlprojectintoyourIDEasintheremaining
stepswe’llbelookingatthefilescontainedinthisproject.
In section 1-3 we discussed that a dependency is passed to an application object as a constructor
argument or as a setter method argument. The following code listing shows that an instance of
FixedDepositService(adependencyofFixedDepositController)ispassedasasettermethodargumentto
theFixedDepositControllerobject:
Examplelisting1-12–FixedDepositControllerclass
Project–ch01-bankapp-xml
Sourcelocation-src/main/java/sample/spring/chapter01/bankapp
packagesample.spring.chapter01.bankapp;
.....
publicclassFixedDepositController{
.....
privateFixedDepositServicefixedDepositService;
.....
publicvoidsetFixedDepositService(FixedDepositServicefixedDepositService){
logger.info("SettingfixedDepositServiceproperty");
this.fixedDepositService=fixedDepositService;
}
.....
publicvoidsubmit(){
fixedDepositService.createFixedDeposit(newFixedDepositDetails(1,10000,
365,"someemail@something.com"));
}
.....
}
In the above example listing, FixedDepositService dependency is passed to FixedDepositController
throughsetFixedDepositServicemethod.We’llsoonseethatthesetFixedDepositServicesettermethodis
invokedbySpring.
NOTE If you look at the FixedDepositController,FixedDepositService and FixedDepositDao classes,
you’ll notice that none of these classes implement any Spring-specific interface or extend from any
Spring-specificclass.
Lets now look at how application objects and their dependencies are specified in the configuration
metadata.
Creatingtheconfigurationmetadata
We saw in section 1-3 that the configuration metadata specifies application objects and their
dependencies, which is read by the Spring container to instantiate application objects and inject their
dependencies.Inthissection,we’llfirstlookatwhatotherinformationiscontainedintheconfiguration
metadata,followedbyanin-depthlookathowconfigurationmetadataisspecifiedinXMLformat.
The configuration metadata specifies information about the enterprise services (like transaction
management,securityandremoteaccess)thatarerequiredbytheapplication.Forinstance,ifyouwant
Spring to manage transactions, you need to configure an implementation of Springs
PlatformTransactionManager interface in the configuration metadata. The PlatformTransactionManager
implementation is responsible for managing transactions (refer chapter 7 to know more about Springs
transactionmanagementfeature).
Ifyourapplicationinteractswithmessagingmiddlewares(likeActiveMQ),databases(likeMySQL),e-
mailservers,andsoon,thenSpring-specificobjectsthatsimplifyinteractingwiththeseexternalsystems
arealsodefinedintheconfigurationmetadata.Forinstance,ifyourapplicationsendsorreceivesJMS
messages from ActiveMQ, then you can configure Springs JmsTemplate class in the configuration
metadata to simplify interaction with ActiveMQ. We saw in example listing 1-10 that if you use
JmsTemplateforsendingmessagestoaJMSprovider,thenyoudon’tneedtodealwithlower-levelJMS
API(referchapter8toknowmoreaboutSpringssupportforinteractingwithJMSproviders).
YoucansupplytheconfigurationmetadatatotheSpringcontainerviaanXMLfileorthroughannotations
inPOJOclasses.StartingwithSpring3.0,youcanalsosupplytheconfigurationmetadatatotheSpring
containerthroughJavaclassesannotatedwithSprings@Configurationannotation.Inthissection,well
seehow configurationmetadata is specifiedinXMLformat.In chapter 6,well see how configuration
metadataissuppliedviaannotationsinPOJOclassesandthrough@ConfigurationannotatedJavaclasses.
You provide the configuration metadata for an application in XML format by creating anapplication
contextXMLfilethatcontainsinformationabouttheapplicationobjectsandtheirdependencies.Example
listing 1-3 showed how an application context XML file looks like. The following XML shows the
application context XML file of MyBank application that consists of FixedDepositController,
FixedDepositService and FixedDepositDao objects (refer figure 1-4 to see how these objects interact
witheachother):
Examplelisting1-13–applicationContext.xml-MyBanksapplicationcontextXMLfile
Project–ch01-bankapp-xml
Sourcelocation-src/main/resources/META-INF/spring
<?xmlversion="1.0"encoding="UTF-8"standalone="no"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<beanid="controller"
class="sample.spring.chapter01.bankapp.FixedDepositController">
<propertyname="fixedDepositService"ref="service"/>
</bean>
<beanid="service"class="sample.spring.chapter01.bankapp.FixedDepositService">
<propertyname="fixedDepositDao"ref="dao"/>
</bean>
<beanid="dao"class="sample.spring.chapter01.bankapp.FixedDepositDao"/>
</beans>
ThefollowingaretheimportantpointstonoteabouttheapplicationcontextXMLfileshownabove:
·The<beans>elementistherootelementoftheapplicationcontextXMLfile,andisdefinedin
spring-beans-4.0.xsdschema(alsoreferredtoasSpringsbeansschema).Thespring-beans-4.0.xsd
schema is contained in spring-beans-4.0.0.RELEASE.jar JAR file that comes with the Spring
Frameworkdistribution.
·Each<bean>elementconfiguresanapplicationobjectthatismanagedbytheSpringcontainer.In
SpringFrameworksterminology,a<bean>elementrepresentsabeandefinition.Theobjectthat
theSpringcontainercreatesbasedonthebeandefinitionisreferredtoasabean.Theidattribute
specifiesauniquenameforthebean,andtheclassattributespecifiesthefully-qualifiedclassname
ofthebean.Youcanalsousethenameattributeof<bean>elementtospecifyaliasesforthebean.
InMyBankapplication,theapplicationobjectsareFixedDepositController, FixedDepositService
andFixedDepositDao;therefore,wehave3<bean>elements-oneforeachapplicationobject.As
application objects configured by <bean> elements are managed by the Spring container, the
responsibility for creating them and injecting their dependencies is with the Spring container.
Insteadofdirectlycreatinginstancesofapplicationobjectsdefinedby<bean>elements,youshould
obtainthemfromtheSpringcontainer.Laterinthissection,welllookathowtoobtainapplication
objectsmanagedbySpringcontainer.
·        No<bean>element is defined corresponding to the FixedDepositDetails domain object of
MyBank application. This is because domain objects arenot typically managed by the Spring
container;theyarecreatedbytheORMframework(likeHibernate)usedbytheapplication,oryou
createthemprogrammaticallyusingthenewoperator.
·        The <property> element specifies a dependency (or a configuration property) of the bean
configuredbythe<bean>element.The<property>elementcorrespondstoaJavaBean-stylesetter
method in the bean class which is invoked by the Spring container to set a dependency (or a
configurationproperty)ofthebean.
Letsnowlookathowdependenciesareinjectedviasettermethods.
Injectingdependenciesviasettermethods
To understand how dependencies are injected via setter methods defined in the bean class, let’s once
againlookattheFixedDepositControllerclassofMyBankapplication:
Examplelisting1-14–FixedDepositControllerclass
Project–ch01-bankapp-xml
Sourcelocation-src/main/java/sample/spring/chapter01/bankapp
packagesample.spring.chapter01.bankapp;
importorg.apache.log4j.Logger;
publicclassFixedDepositController{
privatestaticLoggerlogger=Logger.getLogger(FixedDepositController.class);
privateFixedDepositServicefixedDepositService;
publicFixedDepositController(){
logger.info("initializing");
}
publicvoidsetFixedDepositService(FixedDepositServicefixedDepositService){
logger.info("SettingfixedDepositServiceproperty");
this.fixedDepositService=fixedDepositService;
}
.....
}
The above example listing shows that the FixedDepositController class declares an instance variable
namedfixedDepositServiceoftypeFixedDepositService.ThefixedDepositServicevariableissetbythe
setFixedDepositServicemethod-aJavaBean-stylesettermethodforfixedDepositServicevariable.This
isanexampleofsetter-basedDI,whereinasettermethodsatisfiesadependency.
The following figure describes the bean definition for the FixedDepositController class in the
applicationContext.xmlfile(referexamplelisting1-13):
Figure1-5Definingdependenciesusing<property>elements
The above bean definition shows that the FixedDepositController bean defines its dependence on
FixedDepositServicebeanvia<property>element.The<property>elementsnameattributecorresponds
totheJavaBean-stylesettermethodinthebeanclassthatisinvokedbytheSpringcontaineratthetimeof
beancreation.The<property>element’srefattributeidentifiestheSpringbeanwhoseinstanceneedsto
becreatedandpassedtotheJavaBean-stylesettermethod.Thevalueofrefattributemustmatchtheid
attribute’s value (or one of the names specified by the name attribute) of a <bean> element in the
configurationmetadata.
Infigure1-5,thevalueof<property>elementsnameattributeisfixedDepositService,whichmeansthat
the <property> element corresponds to the setFixedDepositService setter method of
FixedDepositController class (refer example listing 1-14). As the value of <property> elements ref
attribute is service, the <property> element refers to the <bean> element whose id attribute’s value is
service.Now,the<bean>elementwhoseidattribute’svalueisserviceistheFixedDepositServicebean
(refer example listing 1-13). Spring container creates an instance of FixedDepositService class (a
dependency), and invokes the setFixedDepositService method (a JavaBean-style setter method for
fixedDepositService variable) of FixedDepositController (a dependent object), passing the
FixedDepositServiceinstance.
InthecontextofFixedDepositControllerapplicationobject,thefollowingfiguresummarizesthepurpose
ofnameandrefattributesof<property>element:
Figure 1-6 <property> elements name attribute corresponds to a JavaBean-style setter method that
satisfiesabeandependency,andrefattributereferstoanotherbean.
The above figure shows that fixedDepositService value of name attribute corresponds to the
setFixedDepositServicemethodofFixedDepositControllerclass,andservicevalueofrefattributerefers
tothebeanwhoseidisservice.
NOTEItisfairlycommontorefertoabeandefinitionbyitsname(whichisidattribute’svalue)ortype
(whichisclassattribute’svalue)ortheinterfaceimplementedbythebeanclass.Forinstance,youcan
refer to ‘FixedDepositController bean as ‘controller bean’. And, if the FixedDepositController class
implements FixedDepositControllerIntf interface, you can refer to ‘FixedDepositController bean as
‘FixedDepositControllerIntfbean’.
ThefollowingdiagramsummarizeshowtheSpringcontainercreatesbeansandinjectstheirdependencies
basedontheconfigurationmetadatasuppliedbytheapplicationContext.xmlfile(referexamplelisting1-
13)ofMyBankapplication:
Figure1-7-ThesequenceinwhichSpringIoCcontainercreatesbeansandinjectstheirdependencies.
The above figure shows the sequence of steps followed by the Spring IoC container to create
FixedDepositController, FixedDepositService and FixedDepositDao beans and inject their
dependencies.  Before attempting to create beans, the Spring container reads and validates the
configuration metadata supplied by the applicationContext.xml file. The order in which the beans are
created by the Spring container depends on the order in which they are defined in the
applicationContext.xml file.  Spring container ensures that the dependencies of a bean are completely
configured before the setter method is invoked. For example, the FixedDepositController bean is
dependentonFixedDepositServicebean;therefore,SpringcontainerconfigurestheFixedDepositService
beanbeforeinvokingthesetFixedDepositServicemethodofFixedDepositControllerbean.
The bean definitions that we have seen so far, instruct Spring container to create bean instances by
invokingtheno-argumentconstructorofthebeanclass,andinjectdependenciesusingsetter-basedDI.In
chapter 2, we’ll look at bean definitions that instruct Spring container to create a bean instance via a
factorymethod defined in a class. Also, well look at how to inject dependencies through constructor
arguments(referredtoasconstructor-basedDI),throughargumentstothefactorymethodthatcreatesthe
beaninstance,andbyusingsetter-basedDIonthebeaninstancereturnedbythefactorymethod.
LetsnowlookathowtocreateaninstanceofSpringcontainerandpassconfigurationmetadatatoit.
CreatinganinstanceofSpringcontainer
Springs ApplicationContext object represents an instance of Spring container. Spring provides a few
built-in implementations of ApplicationContext interface, like ClassPathXmlApplicationContext,
FileSystemXmlApplicationContext, XmlWebApplicationContext, XmlPortletApplicationContext, and so
on. The choice of the ApplicationContext implementation depends on how you have defined the
configuration metadata (using XML, annotations or Java code), and the type of your application
(standalone, web or portlet application). For instance, ClassPathXmlApplicationContext and
FileSystemXmlApplicationContext classes are suitable forstandalone applications in which
configuration metadata is supplied in XML format, XmlWebApplicationContext is suitable for web
applications in which the configuration metadata is supplied in XML format,
AnnotationConfigWebApplicationContext is suitable forweb applications in which configuration
metadataissuppliedthroughJavacode,andsoon.
As MyBank application represents a standalone application, we can use either
ClassPathXmlApplicationContext or FileSystemXmlApplicationContext class to create an instance of
Spring container. You should note that the ClassPathXmlApplicationContext class loads an application
contextXMLfilefromthespecifiedclasspathlocation,andtheFileSystemXmlApplicationContextclass
loadsanapplicationcontextXMLfilefromthespecifiedlocationonthefilesystem.
The following BankApp class of MyBank application shows that an instance of Spring container is
createdusingtheClassPathXmlApplicationContextclass:
Examplelisting1-15–BankAppclass
Project–ch01-bankapp-xml
Sourcelocation-src/main/java/sample/spring/chapter01/bankapp
packagesample.spring.chapter01.bankapp;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassBankApp{
.....
publicstaticvoidmain(Stringargs[]){
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
.....
}
}
TheaboveexamplelistingshowstheBankApp’smainmethod,whichisresponsibleforbootstrappingthe
Springcontainer.TheclasspathlocationoftheapplicationcontextXMLfileispassedtotheconstructor
of ClassPathXmlApplicationContext class. The creation of ClassPathXmlApplicationContext instance
resultsincreationofthosebeansintheapplicationcontextXMLfilethataresingleton-scopedandsetto
bepre-instantiated.Inchapter 2,well discussbean scopes, andwhatitmeanstohave beanspre- or
lazily-instantiated by Spring container. For now, you can assume that the beans defined in the
applicationContext.xml file of MyBank application are singleton-scoped and set to be pre-instantiated.
This means that the beans defined in the applicationContext.xml file are created when an instance of
ClassPathXmlApplicationContextiscreated.
Now,thatwehaveseenhowtocreateaninstanceoftheSpringcontainer,letslookathowtoretrieve
beaninstancesfromtheSpringcontainer.
AccessbeansfromtheSpringcontainer
Theapplicationobjectsdefinedvia<bean>elementsarecreatedandmanagedbytheSpringcontainer.
You can access instances of these application objects by calling one of the getBean methods of the
ApplicationContextinterface.
The following example listing shows the main method of BankApp class that retrieves an instance of
FixedDepositControllerbeanfromtheSpringcontainerandinvokesitsmethods:
Examplelisting1-16–BankAppclass
Project–ch01-bankapp-xml
Sourcelocation-src/main/java/sample/spring/chapter01/bankapp
packagesample.spring.chapter01.bankapp;
importorg.apache.log4j.Logger;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassBankApp{
privatestaticLoggerlogger=Logger.getLogger(BankApp.class);
publicstaticvoidmain(Stringargs[]){
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");

FixedDepositControllerfixedDepositController=
(FixedDepositController)context.getBean("controller");
logger.info("Submissionstatusoffixeddeposit:"+fixedDepositController.submit());
logger.info("Returnedfixeddepositinfo:"+fixedDepositController.get());
}
}
At first, the ApplicationContexts getBean method is invoked to retrieve an instance of
FixedDepositController bean from the Spring container, followed by invocation of submit and get
methodsofFixedDepositControllerbean.TheargumentpassedtothegetBeanmethodisthenameofthe
beanwhoseinstanceyouwanttoretrievefromtheSpringcontainer.Thenameofthebeanpassedtothe
getBeanmethodmustbethevalueoftheidornameattributeofthebeanthatyouwanttoretrieve.Ifno
bean with the specified name is registered with the Spring container, an exception is thrown by the
getBeanmethod.
In example listing 1-16, to configure the FixedDepositController instance, we didnt programmatically
createaninstanceofFixedDepositService and set it on the FixedDepositController instance. Also, we
didnt create an instance of FixedDepositDao and set it on the FixedDepositService instance. This is
becausethetaskofcreatingdependencies,andinjectingthemintothethedependentobjectsishandledby
theSpringcontainer.
If you go to ch01-bankapp-xml project and execute the main method of BankApp class, you’ll see the
followingoutputontheconsole:
INFOsample.spring.chapter01.bankapp.FixedDepositController-initializing
INFOsample.spring.chapter01.bankapp.FixedDepositService-initializing
INFOsample.spring.chapter01.bankapp.FixedDepositDao-initializing
INFOsample.spring.chapter01.bankapp.FixedDepositService-SettingfixedDepositDaoproperty
INFOsample.spring.chapter01.bankapp.FixedDepositController-SettingfixedDepositServiceproperty
INFOsample.spring.chapter01.bankapp.BankApp-Submissionstatusoffixeddeposit:true
INFOsample.spring.chapter01.bankapp.BankApp-Returnedfixeddepositinfo:id:1,depositamount:10000.0,tenure:365,email:
someemail@something.com
The above output shows that Spring container creates an instance of each of the beans defined in the
applicationContext.xmlfileofMyBankapplication.Also,Springcontainerusessetter-basedDItoinject
an instance of FixedDepositService into FixedDepositController instance, and an instance of
FixedDepositDaointotheFixedDepositServiceinstance.
LetsnowlookatsomeoftheframeworksthatarebuiltontopofSpringFramework.
1-6FrameworksbuiltontopofSpring
Though there are many frameworks from SpringSource that use Spring Framework as the foundation,
we’lllook atsomeofthewidelypopular ones.Foramorecomprehensivelistofframeworks,andfor
moredetailsaboutanindividualframework,itsrecommendedthatyouvisittheSpringSourcewebsite
(www.springsource.org).
Thefollowingtableprovidesahigh-leveloverviewoftheframeworksfromSpringSourcethatarebuilt
ontopofSpringFramework:
Framework Description
SpringSecurity
Authenticationandauthorizationframeworkforenterpriseapplications.Youneedto
configure a few beans in your application context XM L file to incorporate
authenticationandauthorizationfeaturesintoyourapplication.
SpringData
Provides a consistent programming model to interact with different types of
databases.Forinstance,youcanuseittointeractwithnon-relationaldatabases,like
MongoDBorNeo4j,andyoucanalsouseitforaccessingrelationaldatabasesusing
JPA.
SpringBatch Ifyourapplicationrequiresbulkprocessing,thisframeworkisforyou.
SpringIntegration ProvidesEnterpriseApplicationIntegration(EAI)capabilitiestoapplications.
SpringSocial If your application requires interaction with social media websites, like Facebook
andTwitter,thenyou’llfindthisframeworkhighlyuseful.
SpringBlazeDS
Integration
IfyouaredevelopinganAdobeFlexbasedapplication,youcanusethisframework
toconnectFlexfrontendwithSpring-basedbusinesstier.
AstheframeworksmentionedintheabovetablearebuiltontopofSpringFramework,beforeusingany
oftheseframeworksmakesurethattheyarecompatiblewiththeSpringFrameworkversionthatyouare
using.
1-7Summary
Inthischapter,welookedatthebenefitsofusingSpringFramework.WealsolookedatasimpleSpring
applicationthatshowedhowtospecifyconfigurationmetadatainXMLformat,createtheSpringcontainer
instanceandretrievebeansfromit.Inthenextchapter,welllookatsomeofthefoundationconceptsof
SpringFramework.
Chapter2SpringFrameworkbasics
2-1Introduction
Inthepreviouschapter,wesawthattheSpringcontainerinvokestheno-argumentconstructorofabean
classtocreateabeaninstance,andsetter-basedDIisusedtosetbeandependencies.Inthischapter,we’ll
goastepfurtherandlookat:
§Springssupportfor‘programmingtointerfacesdesignprinciple
§differentapproachestoinstantiatingSpringbeans
§constructor-basedDIforpassingbeandependenciesasconstructorarguments
§constructor-andsetter-basedDIforpassingsimpleStringvaluestobeans,and
§beanscopes
Lets begin this chapter with looking at how Spring improves testability of applications by supporting
‘programmingtointerfacesdesignprinciple.
2-2Programmingtointerfacesdesignprinciple
Insection1-5ofchapter1,wesawthatadependentPOJOclasscontainedreferencetotheconcreteclass
of the dependency. For example, the FixedDepositController class contained reference to the
FixedDepositService class, and the FixedDepositService class contained reference to the
FixedDepositDaoclass.Ifadependentclasshasdirectreferencetotheconcreteclassofthedependency,
it results in tight coupling between the classes. This means that if you want to substitute a different
implementationofthedependency,itdrequirechangingthedependentclass.
Letsnowlookatascenarioinwhichadependentclasscontainsdirectreferencetotheconcreteclassof
thedependency.
Scenario:Dependentclasscontainsreferencetotheconcreteclassofdependency
Lets say that the FixedDepositDao class makes use of plain JDBC to interact with the database. To
simplify database interaction, you create another DAO implementation, FixedDepositHibernateDao,
whichusesHibernateORMfordatabaseinteraction.Now,toswitchfromplainJDBCtoHibernateORM
implementation,you’llneedtochangeFixedDepositServiceclasstouseFixedDepositHibernateDaoclass
insteadofFixedDepositDao,asshowninthefollowingexamplelisting:
Examplelisting2-1–FixedDepositServiceclass
publicclassFixedDepositService{
privateFixedDepositHibernateDaofixedDepositDao;
publicvoidsetFixedDepositDao(FixedDepositHibernateDaofixedDepositDao){
this.fixedDepositDao=fixedDepositDao;
}
publicFixedDepositDetailsgetFixedDepositDetails(longid){
returnfixedDepositDao.getFixedDepositDetails(id);
}
publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){
returnfixedDepositDao.createFixedDeposit(fixedDepositDetails);
}
}
The above example listing shows that reference to FixedDepositDao class was replaced by
FixedDepositHibernateDaosothatHibernateORMcanbeusedfordatabaseinteraction.Thisshowsthat
if a dependent class refers to the concrete implementation class of the dependency, then substituting a
differentimplementationrequireschangesinthedependentclass.
Letsnowlookatascenarioinwhichadependentclasscontainsreferencetotheinterfaceimplemented
bythedependency.
Scenario:Dependentclasscontainsreferencetotheinterfaceimplementedbythe
dependency
WeknowthataJavainterfacedefinesacontracttowhichtheimplementationclassesconform.So,ifa
class depends on the interface implemented by the dependency, no change is required in the class if a
different implementation of the dependency is substituted. The application design approach in which a
class depends on the interface implemented by the dependency is referred to as ‘programming to
interfaces.Theinterfaceimplementedbythedependencyclassisreferredtoasadependencyinterface.
Asitisagooddesignpracticetoprogramtointerfacesthanto‘programtoclasses’,thefollowingclass
diagramshowsthatitisagooddesignifABeanclassdependsonBBeaninterfaceandnotonBBeanImpl
classthatimplementsBBeaninterface:
Figure2-1-Programtointerfacesisagooddesignpracticethanto‘programtoclasses
The following class diagram shows how FixedDepositService class can make use of ‘programming to
interfacesdesignapproachtoeasilyswitchthestrategyusedfordatabaseinteraction:
Figure2-2–TheFixedDepositServicedependsonFixedDepositDaointerface,whichisimplementedby
FixedDepositJdbcDaoandFixedDepositHibernateDaoclasses.
The above figure shows that the FixedDepositService class is not directly dependent on the
FixedDepositJdbcDaoorFixedDepositHibernateDaoclass.Instead,FixedDepositServicedependsonthe
FixedDepositDao interface (the dependency interface) implemented by FixedDepositJdbcDao and
FixedDepositHibernateDao classes. Now, depending on whether you want to use plain JDBC or
Hibernate ORM framework, you supply an instance of FixedDepositJdbcDao or
FixedDepositHibernateDaototheFixedDepositServiceinstance.
As FixedDepositService depends on FixedDepositDao interface, you can support other database
interactionstrategies inthe future. Lets say that you decidetouse iBATIS(now renamed to MyBatis)
persistence framework for database interaction. You can use iBATIS without making any changes to
FixedDepositService class by simply creating a new FixedDepositIbatisDao class that implements
FixedDepositDao interface, and supplying an instance of FixedDepositIbatisDao to the
FixedDepositServiceinstance.
Sofarwehaveseenthat‘programmingtointerfaces’designapproachresultsinloosecouplingbetweena
dependentclassanditsdependencies.Letsnowlookathowthisdesignapproachimprovestestabilityof
thedependentclasses.
Improvedtestabilityofdependentclasses
In figure 2-2, we saw that the FixedDepositService class holds reference to the FixedDepositDao
interface.FixedDepositJdbcDaoandFixedDepositHibernateDaoareconcreteimplementationclassesof
FixedDepositDaointerface.Now,tosimplifyunittestingofFixedDepositServiceclass,youcansubstitute
amockimplementationofFixedDepositDaointerfacethatdoesntrequireadatabase.
If the FixedDepositService class had direct reference to FixedDepositJdbcDao or
FixedDepositHibernateDao class, testing FixedDepositService class would have required setting up a
databasefortestingpurposes.Thisshowsthatbyusingamockimplementationofdependencyinterface,
youcansavetheefforttosetuptheinfrastructureforunittestingyourdependentclasses.
LetsnowseehowSpringsupports‘programmingtointerfacesdesignapproachinapplications.
Springssupportfor‘programmingtointerfacesdesignapproach
Touseprogrammingtointerfacesdesignapproach inyour Springapplication,youneedtoensurethe
followingthings:
§the<bean>elementsintheconfigurationmetadataspecifytheconcreteclassesofthedependency
§thedependentbean classes refer tothedependency interface insteadof the concrete class ofthe
dependency
Lets now look at the modified MyBank application that uses ‘programming to interfaces’ design
approach.
IMPORT chapter 2/ch02-bankapp-interfaces (This project shows how ‘programming to interfaces’
designapproachisusedincreatingSpringapplications.Toruntheapplication,executethemainmethod
oftheBankAppclassofthisproject)
MyBankapplicationthatusesprogrammingtointerfaces’designapproach
The following class diagram depicts the modified MyBank application that uses ‘programming to
interfacesdesignapproach:
Figure2-3-MyBankapplicationthatuses‘programtointerfacesdesignapproach
Theabovefigureshowsthatadependentclassdependsontheinterfaceimplementedbythedependency,
and not on the concrete implementation class of the dependency. For instance, the
FixedDepositControllerImpl class depends on the FixedDepositService interface, and the
FixedDepositServiceImplclassdependsontheFixedDepositDaointerface.
ThefollowingexamplelistingshowstheFixedDepositServiceImpl class based onthedesignshownin
figure2-3:
Examplelisting2-2–FixedDepositServiceclass
Project–ch02-bankapp-interfaces
Sourcelocation-src/main/java/sample/spring/chapter02/bankapp
packagesample.spring.chapter02.bankapp;
publicclassFixedDepositServiceImplimplementsFixedDepositService{
privateFixedDepositDaofixedDepositDao;
.....
publicvoidsetFixedDepositDao(FixedDepositDaofixedDepositDao){
this.fixedDepositDao=fixedDepositDao;
}
publicFixedDepositDetailsgetFixedDepositDetails(longid){
returnfixedDepositDao.getFixedDepositDetails(id);
}
publicbooleancreateFixedDeposit(FixedDepositDetailsfdd){
returnfixedDepositDao.createFixedDeposit(fdd);
}
}
The above example listing shows that the FixedDepositServiceImpl class contains reference to the
FixedDepositDao interface. The FixedDepositDao implementation that you want to inject into the
FixedDepositServiceImplinstanceisspecifiedintheapplicationcontextXMLfile.Asshowninfigure2-
3, you can inject any one of the following concrete implementations of FixedDepositDao interface:
FixedDepositIbatisDao,FixedDepositJdbcDaoandFixedDepositHibernateDao.
ThefollowingexamplelistingshowstheapplicationContext.xmlfilethat caters tothe design shown in
figure2-3:
Examplelisting2-3–applicationContext.xml-MyBanksapplicationcontextXMLfile
Project–ch02-bankapp-interfaces
Sourcelocation-src/main/resources/META-INF/spring
<?xmlversion="1.0"encoding="UTF-8"standalone="no"?>
<beans.....>
<beanid="controller"
class="sample.spring.chapter02.bankapp.controller.FixedDepositControllerImpl">
<propertyname="fixedDepositService"ref="service"/>
</bean>
<beanid="service"class="sample.spring.chapter02.bankapp.service.FixedDepositServiceImpl">
<propertyname="fixedDepositDao"ref="dao"/>
</bean>
<beanid="dao"class="sample.spring.chapter02.bankapp.dao.FixedDepositHibernateDao"/>
</beans>
The above applicationContext.xml file shows that an instance of FixedDepositHibernateDao (an
implementation of FixedDepositDao interface) is injected into FixedDepositServiceImpl. Now, if you
decidetouseiBATISinsteadofHibernateforpersistence,thenallyouneedtodoistochangetheclass
attributeofthedaobeandefinitionintheapplicationContext.xmlfiletorefertothefully-qualifiednameof
theFixedDepositIbatisDaoclass.
LetsnowlookatdifferentwaysinwhichSpringcontainercaninstantiatebeans.
2-3DifferentapproachestoinstantiatingSpringbeans
SofarwehaveseenbeandefinitionexamplesthatinstructSpringcontainertocreatebeaninstancesby
invokingtheno-argumentconstructorofthebeanclass.Considerthefollowingbeandefinition:
<beanid=”myBeanclass=”mypackage.MyBean”/>
In the above bean definition, MyBean class represents a POJO class that defines a no-argument
constructor. MyBean class doesn’t implement any Spring-specific interface or extend from any Spring-
specific class. This effectively means that the Spring container can create and manage instance of any
classthatprovidesano-argumentconstructor.
NOTE It is important to note that the Spring container can create and manage instance of any class,
irrespectiveofwhethertheclassprovidesano-argumentconstructorornot.Insection2-4,we’lllookat
beandefinitionsinwhichtheconstructorofthebeanclassacceptsoneormorearguments.
Ifyouhaveanexistingprojectthatusesfactoryclassestocreateobjectinstances,youcanstilluseSpring
containertomanageobjectscreatedbythesefactories.LetsnowlookathowSpringcontainerinvokesa
staticoraninstancefactorymethodofaclasstomanagethereturnedobjectinstance.
Instantiatingbeansviastaticfactorymethods
Infigure2-3,wesawthattheFixedDepositDaointerfaceisimplementedbyFixedDepositHibernateDao,
FixedDepositIbatisDao and FixedDepositJdbcDao classes. The following example listing shows a
FixedDepositDaoFactoryclassthatdefinesastaticfactorymethodforcreatingandreturninganinstance
ofFixedDepositDaobasedontheargumentpassedtothestaticmethod:
Examplelisting2-4–FixedDepositDaoFactoryclass
publicclassFixedDepositDaoFactory{
privateFixedDepositDaoFactory(){}

publicstaticFixedDepositDaogetFixedDepositDao(StringdaoType){
FixedDepositDaofixedDepositDao=null;
if("jdbc".equalsIgnoreCase(daoType)){
fixedDepositDao=newFixedDepositJdbcDao();
}
if("hibernate".equalsIgnoreCase(daoType)){
fixedDepositDao=newFixedDepositHibernateDao();
}
.....
returnfixedDepositDao;
}
}
TheaboveexamplelistingshowsthattheFixedDepositDaoFactoryclassdefinesagetFixedDepositDao
staticmethodthatcreatesandreturnsaninstanceofFixedDepositJdbcDao,FixedDepositHibernateDao
orFixedDepositIbatisDaoclass,dependingonthevalueofthedaoTypeargument.
ThefollowingbeandefinitionfortheFixedDepositDaoFactoryclassinstructsSpringcontainertoinvoke
FixedDepositDaoFactory’sgetFixedDepositDao method to obtain an instance of FixedDepositJdbcDao
class:
Examplelisting2-5–BeandefinitionfortheFixedDepositDaoFactoryclass
<beanid="dao"class="sample.spring.FixedDepositDaoFactory"
factory-method="getFixedDepositDao">
<constructor-argindex=”0”value="jdbc"/>
</bean>
Intheabovebeandefinition,classattributespecifiesthefully-qualifiednameoftheclassthatdefinesthe
staticfactorymethod.Thefactory-methodattributespecifiesthenameofthestaticfactorymethodthatthe
SpringcontainerinvokestoobtainaninstanceofFixedDepositDaoobject.The<constructor-arg>element
is defined in Springs beansschema and is used for passing arguments to constructors, and static and
instancefactorymethods.Theindexattributereferstothelocationoftheargumentintheconstructor,orin
thestaticorinstancefactorymethod.Intheabovebeandefinition,thevalue0ofindexattributemeans
that the <constructor-arg> element is supplying value for the first argument, which is daoType, of the
getFixedDepositDaofactorymethod.Thevalueattributespecifiestheargumentvalue.Ifafactorymethod
acceptsmultiplearguments,youneedtodefinea<constructor-arg>elementforeachofthearguments.
ItisimportanttonotethatcallingApplicationContextsgetBeanmethodtoobtaindaobean(referexample
listing 2-5) will result in invocation of the FixedDepositDaoFactorys getFixedDepositDao factory
method. This means that calling getBean("dao") returns the FixedDepositDao instance created by the
getFixedDepositDaofactorymethod,andnotaninstanceofFixedDepositDaoFactoryclass.
Now,thatwehaveseentheconfigurationofthefactoryclassthatcreatesaninstanceofFixedDepositDao,
the following example listing shows how to inject an instance of FixedDepositDao into
FixedDepositServiceImplclass:
Examplelisting2-6–Injectingobjectinstancescreatedbystaticfactorymethod
<beanid="service"class="sample.spring.chapter02.bankapp.FixedDepositServiceImpl">
<propertyname=“fixedDepositDao"ref="dao"/>
</bean>
<beanid="dao"class="sample.spring.chapter02.basicapp.FixedDepositDaoFactory"
factory-method="getFixedDepositDao">
<constructor-argindex=”0”value="jdbc"/>
</bean>
In the above example listing, <property> element injects an instance of FixedDepositDao returned by
FixedDepositDaoFactory’sgetFixedDepositDao factory methodintoFixedDepositServiceImpl instance.
If you compare the bean definition for the FixedDepositServiceImpl class shown above with the one
shown in example listing 2-3, youll notice that they are exactly the same. This shows that the bean
dependencies are specifiedthe same way irrespective of how (using no-argumentconstructor or static
factorymethod)theSpringcontainercreatesbeaninstances.
LetsnowlookathowSpringcontainerinstantiatebeansbyinvokinganinstancefactorymethod.
Instantiatingbeansviainstancefactorymethods
ThefollowingexamplelistingshowstheFixedDepositDaoFactoryclassthatdefinesaninstancefactory
methodforcreatingandreturninganinstanceofFixedDepositDao:
Examplelisting2-7–FixedDepositDaoFactoryclass
publicclassFixedDepositDaoFactory{
publicFixedDepositDaoFactory(){
}

publicFixedDepositDaogetFixedDepositDao(StringdaoType){
FixedDepositDaoFixedDepositDao=null;
if("jdbc".equalsIgnoreCase(daoType)){
FixedDepositDao=newFixedDepositJdbcDao();
}
if(“hibernate”.equalsIgnoreCase(daoType)){
FixedDepositDao=newFixedDepositHiberateDao();
}
.....
returnfixedDepositDao;
}
}
Ifaclassdefinesaninstancefactorymethod,theclassmustdefineapublicconstructorsothattheSpring
containercancreateaninstanceofthatclass.Intheaboveexamplelisting,theFixedDepositDaoFactory
class defines a public no-argument constructor. The FixedDepositDaoFactorys getFixedDepositDao
methodisaninstancefactorymethodthatcreatesandreturnsaninstanceofFixedDepositDao.
The following example listing shows how to instruct Spring container to invoke
FixedDepositDaoFactory’sgetFixedDepositDaomethodtoobtainaninstanceofFixedDepositDao:
Examplelisting2-8–ConfigurationtoinvokeFixedDepositDaoFactorysgetFixedDepositDaomethod
<beanid="daoFactory"class="sample.spring.chapter02.basicapp.FixedDepositDaoFactory"/>
<beanid="dao"factory-bean="daoFactory"factory-method="getFixedDepositDao">
<constructor-argindex="0"value="jdbc"/>
</bean>
<beanid="service"class="sample.spring.chapter02.bankapp.FixedDepositServiceImpl">
<propertyname=“fixedDepositDao"ref="dao"/>
</bean>
TheaboveexamplelistingshowsthattheFixedDepositDaoFactoryclass(aclassthatcontainsinstance
factory method) is configured like a regular Spring bean, and a separate <bean> element is used to
configuretheinstancefactorymethoddetails.Toconfiguredetailsofaninstancefactorymethod,factory-
beanandfactory-methodattributesof<bean>elementareused.Thefactory-bean attribute referstothe
beanthatdefinestheinstancefactorymethod,andthefactory-methodattributespecifiesthenameofthe
instance factory method. In the above example listing, <property> element injects an instance of
FixedDepositDao returned by FixedDepositDaoFactorys getFixedDepositDao factory method into
FixedDepositServiceImplinstance.
Aswithstaticfactorymethods,youcanpassargumentstoinstancefactorymethodsusing<constructor-
arg> element. It is important to note that invoking ApplicationContextsgetBean method to obtain dao
bean in the above example listing will result in invocation of the FixedDepositDaoFactorys
getFixedDepositDaofactorymethod.
So far we have looked at bean definition examples in which dependencies are injected into beans via
settermethods.Let’snowlookatdifferentDImechanismsthatyoucanuseforinjectingdependencies.
2-4Dependencyinjectiontechniques
In Spring, dependency injection is performed by passing arguments to a beans constructor and setter
methods.Ifyouareusingastaticorinstancefactorymethodtocreatebeaninstances,youcanpassbean
dependencies to the factory method or you can set them on the bean instance returned by the factory
method.
We’llnowlookatexamplesthatdemonstratedifferentDItechniques.
Setter-basedDI
Sofarinthisbook,weveseenexamplesofsetter-basedDI.Insetter-basedDI,<property>elementsare
used to specify bean dependencies. The <property> element is also used to pass configuration
information(ifany)requiredbythebean.
LetssaythattheMyBankapplicationcontainsaPersonalBankingServiceservicethatallowscustomers
toretrievebankaccountstatement,checkbankaccountdetails,updatecontactnumber,changepassword,
and contact customer service. The PersonalBankingService class uses JmsMessageSender (for sending
JMS messages), EmailMessageSender (for sending emails) and WebServiceInvoker (for invoking
external web services) objects toaccomplish its intended functionality. The following example listing
showsthePersonalBankingServiceclass:
Examplelisting2-9–PersonalBankingServiceclass
publicclassPersonalBankingService{
privateJmsMessageSenderjmsMessageSender;
privateEmailMessageSenderemailMessageSender;
privateWebServiceInvokerwebServiceInvoker;
.....
publicvoidsetJmsMessageSender(JmsMessageSenderjmsMessageSender){
this.jmsMessageSender=jmsMessageSender;
}
publicvoidsetEmailMessageSender(EmailMessageSenderemailMessageSender){
this.emailMessageSender=emailMessageSender;
}
publicvoidsetWebServiceInvoker(WebServiceInvokerwebServiceInvoker){
this.webServiceInvoker=webServiceInvoker;
}
.....
}
The above example listing shows that a setter method is defined for JmsMessageSender,
EmailMessageSenderandWebServiceInvokerdependenciesofPersonalBankingServiceclass.
We can use setter-based DI to inject the dependencies of the PersonalBankingService class, as shown
here:
Examplelisting2-10–BeandefinitionsforPersonalBankingServiceclassanditsdependencies
<beanid="personalBankingService"class="PersonalBankingService">
<propertyname="emailMessageSender"ref="emailMessageSender"/>
<propertyname="jmsMessageSender"ref="jmsMessageSender"/>
<propertyname="webServiceInvoker"ref="webServiceInvoker"/>
</bean>
<beanid="jmsMessageSender"class="JmsMessageSender">
.....
</bean>
<beanid="webServiceInvoker"class="WebServiceInvoker"/>
.....
</bean>
<beanid="emailMessageSender"class="EmailMessageSender"/>
.....
</bean>
The personalBankingService bean definition shows that a <property> element is specified for each
dependencyofPersonalBankingServiceclass.
PersonalBankingServiceusesEmailMessageSenderbeantosendanemailnotificationtothecustomers
emailaddressincasecustomerchangeshiscontactnumber.EmailMessageSenderrequiresemailserver
address, and username and password for authenticating with the email server. The following example
listingshowsthatthe<property>elementcanalsobeusedforsettingbeanpropertiesoftypeString:
Examplelisting2-11EmailMessageSenderclassandthecorrespondingbeandefinition
publicclassEmailMessageSender{
privateStringhost;
privateStringusername;
privateStringpassword;
.....
publicvoidsetHost(Stringhost){
this.host=host;
}
publicvoidsetUsername(Stringusername){
this.username=username;
}
publicvoidsetPassword(Stringpassword){
this.password=password;
}
.....
}

<beanid="emailMessageSender"class="EmailMessageSender">
<propertyname="host"value="smtp.gmail.com"/>
<propertyname="username"value="myusername"/>
<propertyname="password"value="mypassword"/>
</bean>
The above example listing shows that <property> elements have been used to set host, username and
passwordpropertiesofEmailMessageSenderbean.ThevalueattributespecifiestheStringvaluetobeset
for the bean property identified by the name attribute. The host, username and password properties
representconfigurationinformationrequiredbyEmailMessageSenderbean.Inchapter3,we’llseehow
the <property> element is used to set primitive type (like int, long, and so on), collection type (like
java.util.List,java.util.Map,andsoon)andcustomtype(likeAddress)properties.
Setter-based DI is also used to inject dependencies into beans created bystatic and instance factory
methods.Let’slookathowtousesetter-basedDIinconjunctionwithstaticandinstancefactorymethods.
Injectingdependenciesintobeaninstancescreatedbyfactorymethods
Youcanusesetter-basedDItoinjectdependenciesofthebeaninstancereturnedbyastaticorinstance
factorymethod.
ConsiderthefollowingFixedDepositJdbcDaoclassthatdefinesadatabaseInfoproperty:
Examplelisting2-12–FixedDepositJdbcDaoclass
publicclassFixedDepositJdbcDao{
privateDatabaseInfodatabaseInfo;
.....
publicFixedDepositJdbcDao(){}
publicvoidsetDatabaseInfo(DatabaseInfodatabaseInfo){
this.databaseInfo=databaseInfo;
}
.....
}
In the above example listing, the databaseInfo attribute represents a dependency of the
FixedDepositJdbcDaoclassthatisfulfilledbysetDatabaseInfomethod.
The following FixedDepositDaoFactory class defines a factory method responsible for creating and
returninganinstanceofFixedDepositDaoJdbcclass:
Examplelisting2-13–FixedDepositDaoFactoryclass
publicclassFixedDepositDaoFactory{
publicFixedDepositDaoFactory(){
}

publicFixedDepositDaogetFixedDepositDao(StringdaoType){
FixedDepositDaoFixedDepositDao=null;
if("jdbc".equalsIgnoreCase(daoType)){
FixedDepositDao=newFixedDepositJdbcDao();
}
if(“hibernate”.equalsIgnoreCase(daoType)){
FixedDepositDao=newFixedDepositHiberateDao();
}
.....
returnfixedDepositDao;
}
}
Intheaboveexamplelisting,thegetFixedDepositDaomethodisaninstancefactorymethodforcreating
FixedDepositDao instances. The getFixedDepositDao method creates an instance of
FixedDepositJdbcDaoinstanceifthevalueofdaoTypeargumentisjdbc.Itisimportanttonotethatthe
getFixedDepositDaomethoddoesn’tsetthedatabaseInfopropertyoftheFixedDepositJdbcDaoinstance.
Aswesawinexamplelisting2-8,thefollowingbeandefinitionsinstructSpringcontainertocreatean
instance of FixedDepositJdbcDao by invoking the getFixedDepositDao instance factory method of
FixedDepositDaoFactoryclass:
Examplelisting2-14–ConfigurationtoinvokeFixedDepositDaoFactorysgetFixedDepositDaomethod
<beanid="daoFactory"class="FixedDepositDaoFactory"/>
<beanid="dao"factory-bean="daoFactory"factory-method="getFixedDepositDao">
<constructor-argindex="0"value="jdbc"/>
</bean>
ThedaobeandefinitionresultsininvocationofFixedDepositDaoFactory’sgetFixedDepositDaomethod,
which creates and returns an instance of FixedDepositJdbcDao. But, the FixedDepositJdbcDao’s
databaseInfopropertyisnotset.TosetthedatabaseInfodependency,youcanperformsetter-basedDIon
theFixedDepositJdbcDaoinstancereturnedbythegetFixedDepositDaomethod,asshownhere:
Examplelisting2-15–ConfigurationtoinvokeFixedDepositDaoFactorysgetFixedDepositDaomethod
andsetdatabaseInfopropertyofreturnedFixedDepositJdbcDaoinstance
<beanid="daoFactory"class="FixedDepositDaoFactory"/>
<beanid="dao"factory-bean="daoFactory"factory-method="getFixedDepositDao">
<constructor-argindex="0"value="jdbc"/>
<propertyname="databaseInfo"ref="databaseInfo"/>
</bean>
<beanid="databaseInfo"class="DatabaseInfo"/>
The above bean definition shows that <property> element is used to set databaseInfo property of
FixedDepositJdbcDao instance returned by getFixedDepositDao instance factory method. As with the
instancefactorymethod,youcanusethe<property>elementtoinjectdependenciesintothebeaninstance
returnedbythestaticfactorymethod.
Letsnowlookathowtoinjectbeandependenciesviaconstructorarguments.
Constructor-basedDI
Inconstructor-basedDI,dependenciesofabeanarepassedasargumentstothebeanclasssconstructor.
For instance, the following example listing shows PersonalBankingService class whose constructor
acceptsJmsMessageSender,EmailMessageSenderandWebServiceInvokerobjects:
Examplelisting2-16–PersonalBankingServiceclass
publicclassPersonalBankingService{
privateJmsMessageSenderjmsMessageSender;
privateEmailMessageSenderemailMessageSender;
privateWebServiceInvokerwebServiceInvoker;
.....
publicPersonalBankingService(JmsMessageSenderjmsMessageSender,
EmailMessageSenderemailMessageSender,
WebServiceInvokerwebServiceInvoker){
this.jmsMessageSender=jmsMessageSender;
this.emailMessageSender=emailMessageSender;
this.webServiceInvoker=webServiceInvoker;
}
.....
}
The arguments to the PersonalBankingService’s constructor represent dependencies of the
PersonalBankingService class. The following example listing shows how dependencies of
PersonalBankingServiceinstancearesuppliedvia<constructor-arg>elements:
Examplelisting2-17–PersonalBankingServicebeandefinition
<beanid="personalBankingService"class="PersonalBankingService">
<constructor-argindex="0"ref="jmsMessageSender"/>
<constructor-argindex="1"ref="emailMessageSender"/>
<constructor-argindex="2"ref="webServiceInvoker"/>
</bean>
<beanid="jmsMessageSender"class="JmsMessageSender">
.....
</bean>
<beanid="webServiceInvoker"class="WebServiceInvoker"/>
.....
</bean>
<beanid="emailMessageSender"class="EmailMessageSender"/>
.....
</bean>
In the above example listing, <constructor-arg> elements specify details of the constructor arguments
passedtothePersonalBankingServiceinstance.Theindexattributespecifiestheindexoftheconstructor
argument.Iftheindexattributevalueis0,itmeansthatthe<constructor-arg>elementcorrespondstothe
firstconstructorargument,andiftheindexattributevalueis1,itmeansthatthe<constructor-arg>element
correspondstothesecondconstructorargument,andsoon.Wesawearlierthatrefattributeof<property>
elementisusedforpassingreferencetoabean.Similarly,refattributeof<constructor-arg>elementis
usedforpassingreferencetoabean.Likethe<property>element,the<constructor-arg>elementisalso
usedtopassconfigurationinformation(ifany)requiredbythebean.
You should note that the <constructor-arg> element is also used for passing arguments to static and
instancefactorymethodsthatcreatebeaninstances(refersection2-3).
NOTE Instead of using ref attribute of <property> and <constructor-arg> elements, you can use <ref>
elementinsidethe<property>and<constructor-arg>elementstosetreferencetobeans.Therefattribute
ispreferredasitmakestheXMLlessverbose.
The following example listing shows the EmailMessageSender class and the corresponding bean
definitionthatdemonstratesuseof<constructor-arg>elementstosupplyvaluesforStringtypeconstructor
arguments:
Examplelisting2-18EmailMessageSenderclassandthecorrespondingbeandefinition
publicclassEmailMessageSender{
privateStringhost;
privateStringusername;
privateStringpassword;
.....
publicEmailMessageSender(Stringhost,Stringusername,Stringpassword){
this.host=host;
this.username=username;
this.password=password;
}
.....
}
<beanid="emailMessageSender"class="EmailMessageSender">
<constructor-argindex="0"value="smtp.gmail.com"/>
<constructor-argindex="1"value="myusername"/>
<constructor-argindex="2"value="mypassword"/>
</bean>
Sofarwehaveseenthat<constructor-arg>elementisusedforinjectingbeandependenciesandpassing
valuesforStringtypeconstructorarguments.Inchapter3,wellseehowthe<constructor-arg>elementis
usedtosetprimitivetype(likeint,long,andsoon),collectiontype(likejava.util.List,java.util.Map,and
soon)andcustomtype(likeAddress)properties.
Letsnowlookathowwecanuseconstructor-basedDIalongwithsetter-basedDI.
Usingamixofconstructor-andsetter-basedDImechanisms
Ifabeanclassrequiresbothconstructor-andsetter-basedDImechanisms,youcanuseacombinationof
<constructor-arg>and<property>elementstoinjectdependencies.
The following example listing shows a bean class whose dependencies are injected as arguments to
constructorandsettermethods:
Examplelisting2-19–PersonalBankingServiceclass
publicclassPersonalBankingService{
privateJmsMessageSenderjmsMessageSender;
privateEmailMessageSenderemailMessageSender;
privateWebServiceInvokerwebServiceInvoker;
.....
publicPersonalBankingService(JmsMessageSenderjmsMessageSender,
EmailMessageSenderemailMessageSender){
this.jmsMessageSender=jmsMessageSender;
this.emailMessageSender=emailMessageSender;
}

publicvoidsetWebServiceInvoker(WebServiceInvokerwebServiceInvoker){
this.webServiceInvoker=webServiceInvoker;
}
.....
}
In the PersonalBankingService class, jmsMessageSender and emailMessageSender dependencies are
injected as constructor arguments, and webServiceInvoker dependency is injected via the
setWebServiceInvoker setter method. The following bean definition shows that both <constructor-arg>
and<property>elementsareusedtoinjectdependenciesofPersonalBankingServiceclass:
Examplelisting2-20–Mixingconstructor-andsetter-basedDImechanisms
<beanid="dataSource"class="PersonalBankingService">
<constructor-argindex="0"ref="jmsMessageSender"/>
<constructor-argindex="1"ref="emailMessageSender"/>
<propertyname="webServiceInvoker"ref="webServiceInvoker"/>
</bean>
Now,that we have seenhowtoinstructSpringcontainertocreatebeansand performDI,let’slookat
differentscopesthatyoucanspecifyforbeans.
2-5Beanscopes
Youmaywanttospecifythescopeofabeantocontrolwhetherasharedinstanceofthebeaniscreated
(singletonscope),oranewbeaninstanceiscreatedeverytimethebeanisrequested(prototypescope)
fromtheSpringcontainer.Thescopeofabeanisdefinedbythescopeattributeofthe<bean>element.If
thescopeattributeisnotspecified,itmeansthatthebeanisasingleton-scopedbean.
NOTEInwebapplicationscenarios,Springallowsyoutospecifyadditionalscopes:request,session
and globalSession. These scopes determine thelifetime of the bean instance. For instance, a request-
scoped beans lifetimeis limited toasingle HTTP request.Asin this chapter we’ll not be discussing
SpringWebMVCorSpringPortletMVC,we’llrestrictthediscussiontosingletonandprototypescopes.
Therequest,sessionandglobalSessionscopesaredescribedinchapter10.
IMPORTchapter2/ch02-bankapp-scopes(Thisproject shows usageof singletonandprototype bean
scopes.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject.Theproject
alsocontains2JUnittests,PrototypeTestandSingletonTestthatyoucanexecute)
Singleton
Thesingletonscopeisthedefaultscope for all the beansdefinedintheapplicationcontext XML file.
Instance of a singleton-scoped bean is created when the Spring container is created, and is destroyed
whentheSpringcontainerisdestroyed.Springcontainercreatesasingleinstanceofasingleton-scoped
bean,whichissharedbyallthebeansthatdependonit.
ThefollowingexamplelistingshowstheapplicationContext.xmlfileofch02-bankapp-scopesprojectin
whichallthebeansaresingleton-scoped:
Examplelisting2-21–applicationContext.xml-Singleton-scopedbeans
Project–ch02-bankapp-scopes
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
<beanid="controller"
class="sample.spring.chapter02.bankapp.controller.FixedDepositControllerImpl">
<propertyname=“fixedDepositService"ref="service"/>
</bean>
<beanid="service"
class="sample.spring.chapter02.bankapp.service.FixedDepositServiceImpl">
<propertyname=“fixedDepositDao"ref="dao"/>
</bean>
<beanid="dao"class="sample.spring.chapter02.bankapp.dao.FixedDepositDaoImpl"/>
.....
</beans>
IntheaboveapplicationContext.xmlfile,controller,serviceanddaobeansaresingleton-scopedbecause
no scope attribute is specified for the <bean> elements. This means that only a single instance of
FixedDepositControllerImpl,FixedDepositServiceImplandFixedDepositDaoImpl classes is createdby
theSpringcontainer.Asthesebeansaresingleton-scoped,Springcontainerreturnsthesameinstanceof
thebeaneverytimeweretrieveoneofthesebeansusingApplicationContext’sgetBeanmethod.
NOTEIfthescopeattributeisnotspecifiedorthevalueofscopeattributeissingleton,itmeansthatthe
beanissingleton-scoped.
ThefollowingexamplelistingshowsthetestInstancesmethodofSingletonTest(aJUnittestclass)classof
ch02-bankapp-scopes project. The testInstances method tests whether multiple invocation of
ApplicationContextsgetBeanmethodreturnsthesameordifferentinstanceofthecontrollerbean:
Examplelisting2-22–SingletonTestJUnittestclass
Project–ch02-bankapp-scopes
Sourcelocation-src/test/java/sample/spring/chapter02/bankapp
packagesample.spring.chapter02.bankapp;
importstaticorg.junit.Assert.assertSame;
importorg.junit.BeforeClass;
importorg.junit.Test;
importsample.spring.chapter02.bankapp.controller.FixedDepositController;
publicclassSingletonTest{
privatestaticApplicationContextcontext;
@BeforeClass
publicstaticvoidinit(){
context=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
}
@Test
publicvoidtestInstances(){
FixedDepositControllercontroller1=(FixedDepositController)context.getBean("controller");
FixedDepositControllercontroller2=(FixedDepositController)context.getBean("controller");
assertSame("DifferentFixedDepositControllerinstances",controller1,controller2);
}
.....
}
Intheaboveexamplelisting,JUnit’s@BeforeClassannotationspecifiesthattheinitmethodisinvoked
beforeanyofthetestmethods(thatis,methodsannotatedwithJUnits@Testannotation)intheclass.This
means that @BeforeClass annotated method is invoked onlyonce, and @Test annotated methods are
executedonlyaftertheexecutionof@BeforeClassannotatedmethod.Notethattheinitmethodisastatic
method. The init method creates an instance of ApplicationContext object by passing the configuration
metadata (shown in example listing 2-21) to the ClassPathXmlApplicationContext’s constructor. The
testInstancesmethodobtains2instancesofcontrollerbeanandcheckswhetherboththeinstancesarethe
samebyusingJUnitsassertSameassertion.Asthecontrollerbeanissingleton-scoped,controller1and
controller2 bean instances are the same. For this reason, SingletonTest’s testInstances test executes
withoutanyassertionerrors.
ThefollowingfigureshowsthattheSpringcontainerreturnsthesameinstanceofcontrollerbeanwhen
youcalltheApplicationContextsgetBeanmethodmultipletimes:
Figure2-4Multiplerequestsforasingleton-scopedbeanresultsinthesamebeaninstancereturnedbythe
Springcontainer
The above figure shows that multiple calls to obtain controller bean returns the same instance of the
controllerbean.
NOTEInfigure2-4,thecontrollerbeaninstanceisrepresentedbya2-compartmentrectangle.Thetop
compartmentshowsthenameofthebean(thatis,thevalueoftheidattributeofthe<bean>element)and
thebottomcompartmentshowsthetypeofthebean(thatis,thevalueoftheclassattributeofthe<bean>
element). In the rest of this book, we’ll use this convention to show bean instances inside a Spring
container.
Asingleton-scopedbeaninstanceissharedamongstthebeansthatdependonit.Thefollowingexample
listing shows the testReference method of SingletonTest JUnit test class that checks if the
FixedDepositDao instance referenced by the FixedDepositController instance is the same as the one
obtaineddirectlybycallinggetBeanmethodofApplicationContext:
Examplelisting2-23–testReferencemethodofSingletonTestJUnittestclass
Project–ch02-bankapp-scopes
Sourcelocation-src/test/java/sample/spring/chapter02/bankapp
packagesample.spring.chapter02.bankapp;
importstaticorg.junit.Assert.assertSame;
importorg.junit.Test;
publicclassSingletonTest{
privatestaticApplicationContextcontext;
.....
@Test
publicvoidtestReference(){
FixedDepositControllercontroller=(FixedDepositController)context.getBean("controller");
FixedDepositDaofixedDepositDao1=
controller.getFixedDepositService().getFixedDepositDao();
FixedDepositDaofixedDepositDao2=(FixedDepositDao)context.getBean("dao");
assertSame("DifferentFixedDepositDaoinstances",fixedDepositDao1,fixedDepositDao2);
}
}
Intheaboveexamplelisting,thetestReferencemethodfirstretrievestheFixedDepositDaoinstance(refer
fixedDepositDao1variableintheaboveexamplelisting)referencedbytheFixedDepositControllerbean,
followed by directly retrieving another instance of FixedDepositDao bean (refer fixedDepositDao2
variable in the above example listing) using ApplicationContexts getBean method. If you execute the
testReference test, you’ll see that the test completes successfully because the fixedDepositDao1 and
fixedDepositDao2instancesarethesame.
Figure2-5showsthattheFixedDepositDaoinstancereferencedbyFixedDepositControllerinstanceisthe
sameastheonereturnedbyinvokinggetBean("dao")methodonApplicationContext.
Figure2-5Singleton-scopedbeaninstanceissharedbetweenbeansthatdependonit
TheabovefigureshowsthattheFixedDepositDaoinstancereferencedbyFixedDepositController bean
instance and the one retrieved directly by calling ApplicationContexts getBean are same. If there are
multiple beans dependent on a singleton-scoped bean, then all the dependent beans share the same
singleton-scopedbeaninstance.
Lets now look at whether or not the same singleton-scoped bean instance is shared between multiple
Springcontainerinstances.
Singleton-scopedbeansandmultipleSpringcontainerinstances
Thescopeofasingleton-scopedbeaninstanceislimitedtotheSpringcontainerinstance.Thismeansthat
if you create 2 instances of the Spring container using the same configuration metadata, each Spring
containerhasitsowninstancesofthesingleton-scopedbeans.
ThefollowingexamplelistingshowsthetestSingletonScopemethodofSingletonTestclass,whichtests
whethertheFixedDepositControllerbeaninstanceretrievedfromtwodifferentSpringcontainerinstances
aresameordifferent:
Examplelisting2-24–testSingletonScopemethodofSingletonTestJUnittestclass
Project–ch02-bankapp-scopes
Sourcelocation-src/test/java/sample/spring/chapter02/bankapp
packagesample.spring.chapter02.bankapp;
importstaticorg.junit.Assert.assertNotSame;
publicclassSingletonTest{
privatestaticApplicationContextcontext;
.....
@BeforeClass
publicstaticvoidinit(){
context=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
}
@Test
publicvoidtestSingletonScope(){
ApplicationContextanotherContext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
FixedDepositControllerfixedDepositController1=(FixedDepositController)anotherContext
.getBean("controller");
FixedDepositControllerfixedDepositController2=
(FixedDepositController)context.getBean("controller");
assertNotSame("SameFixedDepositControllerinstances",
fixedDepositController1,fixedDepositController2);
}
}
TheSingletonTest’sinitmethod(annotatedwithJUnit’s@BeforeClassannotation)createsaninstanceof
ApplicationContext(identifiedbycontextvariable)beforeany@Testannotatedmethodisexecuted.The
testSingletonScopemethodcreates one more instance ofSpring container (identifiedbyanotherContext
variable) using the same applicationContext.xml file. An instance of FixedDepositController bean is
retrieved from both the Spring containers and checked if they arenot the same. If you execute the
testSingletonScope test, youll find that the test completes successfully because the
FixedDepositControllerbeaninstanceretrievedfromcontextinstanceisdifferentfromtheoneretrieved
fromanotherContextinstance.
ThefollowingfiguredepictsthebehaviorexhibitedbythetestSingletonScopemethod:
Figure2-6EachSpringcontainercreatesitsowninstanceofasingleton-scopedbean
TheabovefigureshowsthateachSpringcontainercreatesitsowninstanceofcontrollerbean.Thisisthe
reasonwhycontextandanotherContextinstancesreturndifferentinstancesofcontrollerbeanwhenyou
callgetBean("controller")method.
ThetestSingletonScopemethodshowedthateachSpringcontainercreatesitsowninstanceofasingleton-
scopedbean.ItisimportanttonotethatSpringcontainercreatesaninstanceofasingleton-scopedbean
foreach bean definition. The following example listing shows multiple bean definitions for the
FixedDepositDaoImplclass:
Examplelisting2-25–applicationContext.xml-Multiplebeandefinitionsforthesameclass
Project–ch02-bankapp-scopes
Sourcelocation-src/main/resources/META-INF/spring
<beanid="dao"class="sample.spring.chapter02.bankapp.dao.FixedDepositDaoImpl"/>
<beanid="anotherDao"
class="sample.spring.chapter02.bankapp.dao.FixedDepositDaoImpl"/>
ThebeandefinitionsshownintheaboveexamplelistingareforFixedDepositDaoImplclass.Asscope
attributeisnotspecified,beandefinitionsshownintheaboveexamplelistingrepresentsingleton-scoped
beans.Evenifmultiplebeandefinitionsaredefinedforaclass,Springcontainercreatesabeaninstance
corresponding to each bean definition. This means that Spring container creates distinct instances of
FixedDepositDaoImpl class corresponding to dao and anotherDao bean definitions. The following
example listing shows SingletonScope’s testSingletonScopePerBeanDef method that tests whether the
FixedDepositDaoImpl instances corresponding to dao and anotherDao bean definitions are same or
different:
Examplelisting2-26–testSingletonScopePerBeanDefmethodofSingletonTestJUnittestclass
Project–ch02-bankapp-scopes
Sourcelocation-src/test/java/sample/spring/chapter02/bankapp
packagesample.spring.chapter02.bankapp;
importstaticorg.junit.Assert.assertNotSame;
publicclassSingletonTest{
privatestaticApplicationContextcontext;
.....
@Test
publicvoidtestSingletonScopePerBeanDef(){
FixedDepositDaofixedDepositDao1=(FixedDepositDao)context.getBean("dao");
FixedDepositDaofixedDepositDao2=(FixedDepositDao)context.getBean("anotherDao");
assertNotSame("SameFixedDepositDaoinstances",fixedDepositDao1,fixedDepositDao2);
}
}
Intheaboveexamplelisting,fixedDepositDao1andfixedDepositDao2variablesrepresentinstancesof
FixedDepositDaoImplclassthatSpringcontainercreatescorrespondingtothedaoandanotherDaobean
definitions, respectively. If you execute the testSingleScopePerBeanDef test, itll execute without any
assertion errors because the fixedDepositDao1 instance (corresponding to dao bean definition) and
fixedDepositDao2instance(correspondingtoanotherDaobeandefinition)aredistinct.
Thefollowingfiguresummarizesthatasingleton-scopedbeaniscreatedperbeandefinition:
Figure2-7Thereisonesingleton-scopedbeaninstanceperbeandefinition
Theabovefigureshowsthatthereexistsoneinstanceofsingleton-scopedbeanperbeandefinitioninthe
Springcontainer.
We mentioned earlier that a singleton-scoped bean is pre-instantiated by default, which means an
instanceofasingleton-scopedbeaniscreatedwhenyoucreateaninstanceoftheSpringcontainer.Lets
nowlookathowyoucanlazilyinitializeasingleton-scopedbean.
Lazilyinitializingasingleton-scopedbean
You can instruct Spring container to create an instance of a singleton-scoped bean only when it is
requested for the first time. The following lazyExample bean definition shows how to instruct Spring
containertolazyinitializelazyBeanbean:
Examplelisting2-27–Lazilyinitializingasingleton-scopedbean
<beanid="lazyBean"class="example.LazyBean"lazy-init=”true/>
The<bean>element’slazy-initattributespecifieswhetherthebeaninstanceiscreatedlazilyoreagerly.If
thevalueistrue(asincaseofthebeandefinitionshownabove),thebeaninstanceisinitializedbythe
Springcontainerwhenitreceivestherequestforthebeanforthefirsttime.
Thefollowingsequencediagramshowshowlazy-initattributeaffectsthecreationofasingleton-scoped
beaninstance:
Figure2-8Alazily-initializedsingleton-scopedbeaninstanceiscreatedwhenitisrequestedforthefirst
timebytheapplication
In the above diagram, BeanA represents a singleton-scoped bean instance that isnot set to be lazily-
initialized,andLazyBeanrepresentsasingleton-scopedbeanthatissettobelazily-initialized.Whenthe
Spring container instance is created, BeanA is also instantiated because it isnot set to be lazily-
initialized. On the other hand, LazyBean is instantiated when ApplicationContexts getBean method is
invokedforthetimefirsttimetoretrieveaninstanceofLazyBeanfromtheSpringcontainer.
NOTEYoucanuse<beans>elementsdefault-lazy-initattributetospecifydefaultinitializationstrategy
forbeansdefinesintheapplicationcontextXMLfile.Ifthe<bean>element’slazy-initattributespecifies
adifferentvaluethanthe<beans>elementsdefault-lazy-init,thevaluespecifiedbythelazy-initattribute
appliestothebean.
Asasingleton-scopedbeancanbelazily-initializedorpre-instantiatedbytheSpringcontainer,youmay
bethinkingatthistimewhetheryoushoulddefineyoursingleton-scopedbeanstobelazily-initializedor
pre-instantiated.Inmostapplicationscenarios,itisbeneficialtopre-instantiatesingleton-scopedbeansto
discover configuration issues at the time of creation of the Spring container. The following example
listingshowsaaBeansingleton-scopedbeanthatissettobelazily-initialized,andthatdependsonbBean
bean:
Examplelisting2-28–Alazily-initializedsingleton-scopedbean
publicclassABean{
privateBBeanbBean;

publicvoidsetBBean(BBeanbBean){
this.bBean=bBean;
}
.....
}
<beanid="aBean"class="ABean"lazy-init="true">
<propertyname="bBean"value="bBean"/>
</bean>
<beanid="bBean"class="BBean"/>
Intheaboveexamplelisting,ABean’sbBeanpropertyreferstotheBBeanbean.Noticethatinsteadofref
attribute, value attribute of <property> element has been used to set ABeans bBean property. If you
createanApplicationContextinstancebypassingittheXMLfilecontainingtheabovebeandefinition,no
errors will be reported. But, when you try to fetch the aBean bean by invoking ApplicationContext’s
getBeanmethod,you’llgetthefollowingerrormessage:
Causedby:java.lang.IllegalStateException:Cannotconvertvalueoftype[java.lang.String]torequiredtype[BBean]forproperty'bBean:no
matchingeditorsorconversionstrategyfound
The above error message is shown because the Spring container fails to convert the String value of
ABean’sbBeanpropertytoBBeantype.Thishighlightsasimpleconfigurationissueinwhichinsteadof
specifying<bean>elementsrefattribute,valueattributewasspecified.IftheaBeanbeanwasdefinedas
pre-instantiated(insteadoflazily-initialized),theaboveconfigurationissuecouldhavebeencaughtatthe
timewecreatedaninstanceofApplicationContext,andnotwhenwetriedtoobtainaninstanceofaBean
beanfromtheApplicationContext.
Letsnowlookatprototype-scopedbeansinSpring.
Prototype
Aprototype-scopedbeanisdifferentfromasingleton-scopedbeaninthesensethattheSpringcontainer
always returns a new instance of a prototype-scoped bean. Another distinctive feature of prototype-
scopedbeansisthattheyarealwayslazily-initialized.
The following FixedDepositDetails bean in the applicationContext.xml file of ch02-bankapp-scopes
projectrepresentsaprototype-scopedbean:
Examplelisting2-29–applicationContext.xml-Aprototype-scopedbeanexample
Project–ch02-bankapp-scopes
Sourcelocation-src/main/resources/META-INF/spring
<beanid="FixedDepositDetails"
class="sample.spring.chapter02.bankapp.domain.FixedDepositDetails"
scope="prototype"/>
Theaboveexamplelistingshowsthatthe<bean>elementsscopeattributevalueissettoprototype.This
meansthattheFixedDepositDetailsbeanisaprototype-scopedbean.
The following testInstances method of PrototypeTest JUnit test class shows that the 2 instances of
FixedDepositDetailsbeanretrievedfromtheSpringcontaineraredifferent:
Examplelisting2-30–testInstancesmethodofPrototypeTestJUnittestclass
Project–ch02-bankapp-scopes
Sourcelocation-src/test/java/sample/spring/chapter02/bankapp
packagesample.spring.chapter02.bankapp;
importstaticorg.junit.Assert.assertNotSame;
publicclassPrototypeTest{
privatestaticApplicationContextcontext;
.....
@Test
publicvoidtestInstances(){
FixedDepositDetailsfixedDepositDetails1=
(FixedDepositDetails)context.getBean("fixedDepositDetails");
FixedDepositDetailsfixedDepositDetails2=
(FixedDepositDetails)context.getBean("fixedDepositDetails");
assertNotSame("SameFixedDepositDetailsinstances",
fixedDepositDetails1,fixedDepositDetails2);
}
}
If you execute the testInstances test, it’ll complete without any assertion errors because the 2
FixedDepositDetails instances (fixedDepositDetails1 and fixedDepositDetails2) obtained from the
ApplicationContextaredifferent.
Letsnowlookathowtochoosetherightscope(singletonorprototype)forabean.
Choosingtherightscopeforyourbeans
Ifabeandoesn’tmaintainanyconversationalstate(thatis,itisstatelessinnature),itshouldbedefinedas
a singleton-scoped bean. If a bean maintains conversational state, it should be defined as a prototype-
scopedbean.FixedDepositServiceImpl,FixedDepositDaoImplandFixedDepositControllerImplbeansof
MyBank application are stateless in nature; therefore, they are defined as singleton-scoped beans.
FixedDepositDetails bean (adomain object) of MyBank application maintains conversational state;
therefore,itisdefinedasaprototype-scopedbean.
NOTEIfyouareusinganORMframework(likeHibenateoriBATIS)inyourapplication,thedomain
objectsarecreatedeitherbytheORMframeworkoryoucreatethemprogrammaticallyinyour
applicationcodeusingthenewoperator.Itisbecauseofthisreasondomainobjectsarenotdefinedinthe
applicationcontextXMLfileiftheapplicationusesanORMframeworkforpersistence.
2-6Summary
In this chapter,we discussed some ofthe basics ofSpring Framework.We looked at ‘programming to
interfacesdesignapproach,differentapproachestocreatebeaninstances,constructor-basedDIandbean
scopes.Inthenextchapter,we’lllookathowtosetdifferenttypes(likeint,long,Map,Set,andsoon)of
beanpropertiesandconstructorarguments.
Chapter3-Configuringbeans
3-1Introduction
Inpreviouschapters,wetoucheduponsomeofthebasicconceptsofSpringFramework.Wesawhow
SpringbeansandtheirdependenciesarespecifiedintheapplicationcontextXMLfile.Wealsolookedat
singleton-andprototype-scopedbeans,anddiscussedtheimplicationsofassigningthesescopestobeans.
Inthischapter,we’lllookat:
§beandefinitioninheritance
§howargumentstoabeanclass’sconstructorareresolved
§howtoconfigurebeanpropertiesandconstructorargumentsofprimitivetype(likeint,float,andso
on),collectiontype(likejava.util.List,java.util.Map,andsoon),customtype(likeAddress),and
soon
§ how you can make the application context XML file less verbose by using p-namespace and c-
namespacetospecifybeanpropertiesandconstructorarguments,respectively
§SpringsFactoryBeaninterfacethatallowsyoutowriteyourownfactoryclassfor creatingbean
instances
3-2Beandefinitioninheritance
Wesawinchapter1and2thatabeandefinitionintheapplicationcontextXMLfilespecifiesthefully-
qualifiednameofthebeanclassanditsdependencies.Insomescenarios,tomakeabeandefinitionless
verbose,youmaywantabeandefinitiontoinheritconfigurationinformationfromanotherbeandefinition.
LetslookatonesuchscenarioinMyBankapplication.
IMPORTchapter3/ch03-bankapp-inheritance(Thisproject showstheMyBankapplicationthatuses
beandefinitioninheritance.Toruntheapplication,executethemainmethodoftheBankAppclassofthis
project)
MyBankBeandefinitioninheritanceexample
Inthepreviouschapter,wesawthattheMyBankapplicationaccessesdatabasethroughDAOs.Let’ssay
that the MyBank application defines a DatabaseOperations class that simplifies interacting with the
database.So,alltheDAOsintheMyBankapplicationdependonDatabaseOperationsclasstoperform
databaseoperations,asshowninthefollowingfigure:
Figure 3-1 - DAO classes in MyBank application make use of DatabaseOperations class to perform
databaseinteraction
TheabovefigureshowsthattheFixedDepositDaoandPersonalBankingDaoclassesaredependentonthe
DatabaseOperations class. The following application context XML file shows the bean definitions for
theseclasses:
Examplelisting3-1–DAObeansaredependentonDatabaseOperationsbean
<beanid="databaseOperations"
class="sample.spring.chapter01.bankapp.utils.DatabaseOperations"/>
<beanid="personalBankingDao"
class="sample.spring.chapter01.bankapp.dao.PersonalBankingDaoImpl">
<propertyname="databaseOperations"ref="databaseOperations"/>
</bean>
<beanid="FixedDepositDao"
class="sample.spring.chapter01.bankapp.dao.FixedDepositDaoImpl">
<propertyname="databaseOperations"ref="databaseOperations"/>
</bean>
Both the personalBankingDao and FixedDepositDao bean definitions use the <property> element to
performdependencyinjectionoftheDatabaseOperationsinstance.Asthenameofthepropertythatrefers
totheDatabaseOperationsinstanceisdatabaseOperationsinboththebeandefinitions,itimpliesthatboth
PersonalBankingDaoImpl and FixedDepositDaoImpl classes define a setDatabaseOperations method to
allowSpringcontainertoinjectDatabaseOperationsinstance.
If multiple beans in your application share a common set of configuration (properties, constructor
arguments,andsoon),youcancreateabeandefinitionthatactsasaparentforotherbeandefinitions.In
case of personalBankingDao and fixedDepositDao bean definitions, the common configuration is the
databaseOperations property. The following example listing shows that the personalBankingDao and
fixedDepositDaobeandefinitionsmakeuseofbeandefinitioninheritance:
Examplelisting3-2–applicationContext.xml-MyBanksapplicationcontextXMLfile
Project–ch03-bankapp-inheritance
Sourcelocation-src/main/resources/META-INF/spring
<beanid="databaseOperations"
class="sample.spring.chapter03.bankapp.utils.DatabaseOperations"/>
<beanid="daoTemplate"abstract="true">
<propertyname="databaseOperations"ref="databaseOperations"/>
</bean>

<beanid="FixedDepositDao"parent="daoTemplate"
class="sample.spring.chapter03.bankapp.dao.FixedDepositDaoImpl"/>

<beanid="personalBankingDao"parent="daoTemplate"
class="sample.spring.chapter03.bankapp.dao.PersonalBankingDaoImpl"/>
Intheaboveexamplelisting,thedaoTemplatebeandefinitiondefinesthecommonconfigurationsharedby
both the fixedDepositDao and personalBankingDao bean definitions. As both the fixedDepositDao and
personalBankingDaobeandefinitionsrequirethedatabaseOperationsdependency(referexamplelisting
3-1),thedaoTemplatebeandefinitiondefinesthedatabaseOperationsdependencyusingthe<property>
element.The<bean>element’sparentattributespecifiesthenameofthebeandefinitionfromwhichthe
configuration is inherited. As the parent attribute value is daoTemplate for fixedDepositDao and
personalBankingDao bean definitions, they inherit databaseOperations property from the daoTemplate
beandefinition.Theexamplelistings3-1and3-2aresame,exceptthattheexamplelisting3-2makesuse
ofbeandefinitioninheritance.
Ifthe<bean>element’sabstractattributevalueissettotrue,itmeansthatthebeandefinitionisabstract.
It is important to note that the Spring containerdoesn’t attempt to create a bean corresponding to an
abstractbeandefinition.Itisimportanttonotethatyoucan’tdefineabeantobedependentonanabstract
bean,thatis,youcan’tuse<property>or<constructor-arg>elementtorefertoanabstractbean.
In example listing 3-2, daoTemplate bean definition is abstract. You may have noticed that the
daoTemplatebeandefinitiondoesn’tspecifytheclassattribute.Ifaparentbeandefinitiondoesn’tspecify
theclassattribute,childbeandefinitions(likethefixedDepositDaoandpersonalBankingDao)specifythe
class attribute. It is important to note that if you dont specify the class attribute, you must define the
parent bean definition as abstract so that Spring container doesnt attempt to create a bean instance
correspondingtoit.
ToverifythatthefixedDepositDaoandpersonalBankingDaobeandefinitionsinheritdaoTemplate bean
definitionsdatabaseOperationsproperty,executethemainmethodofBankAppclass ofch03-bankapp-
inheritance project. BankApp’s main method invokes methods on the fixedDepositDao and
personalBankingDaobeans;thosebeansinturninvokemethodsontheDatabaseOperationsinstance.Ifa
DatabaseOperations instance isnot injected into the fixedDepositDao and personalBankingDao beans,
java.lang.NullPointerExceptionwillbethrown.
ThefollowingdiagramsummarizeshowbeandefinitioninheritanceworksincaseofFixedDepositDao
andpersonalBankingDaobeandefinitions:
Figure3-2–BeandefinitioninheritanceinMyBankapplication
The above figure shows that the fixedDepositDaoand personalBankingDao bean definitions inherit the
databaseOperations property (shown initalics in the boxes labeled fixedDepositDao and
personalBankingDao)fromthedaoTemplatebeandefinition.TheabovefigurealsodepictsthattheSpring
container doesnt attempt to create a bean instance corresponding to the daoTemplate bean definition
becauseitismarkedasabstract.
Letsnowlookatwhatconfigurationinformationgetsinheritedfromtheparentbeandefinition.
Whatgetsinherited?
Achildbeandefinitioninheritsthefollowingconfigurationinformationfromtheparentbeandefinition:
·properties–specifiedvia<property>elements
·constructorarguments–specifiedvia<constructor-arg>elements
·methodoverrides(discussedinsection4-5ofchapter4)
·initializationanddestroymethods(discussedinchapter5),and
·factorymethods–specifiedviafactory-methodattributeof<bean>element(refersection2-3of
chapter2toknowhowstaticandinstancefactorymethodsareusedforcreatingbeans)
IMPORTchapter3/ch03-bankapp-inheritance-example(ThisprojectshowstheMyBankapplication
thatusesbeandefinitioninheritance.Inthisproject,youllseemultiplescenariosinwhichbeandefinition
inheritanceisused.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)
Letsnowlookatsomeofthebeandefinitioninheritanceexamples.
Beandefinitioninheritanceexampleparentbeandefinitionisnotabstract
Thefollowingexamplelistingshowsabeaninheritanceexampleinwhichtheparentbeandefinitionis
notabstract,andthechildbeandefinitionsdefineanadditionaldependency:
Examplelisting3-3–applicationContext.xml-Beandefinitioninheritance–parentbeandefinitionisnot
abstract
Project–ch03-bankapp-inheritance-examples
Sourcelocation-src/main/resources/META-INF/spring
<beanid="serviceTemplate"
class="sample.spring.chapter03.bankapp.base.ServiceTemplate">
<propertyname="jmsMessageSender"ref="jmsMessageSender"/>
<propertyname="emailMessageSender"ref="emailMessageSender"/>
<propertyname="webServiceInvoker"ref="webServiceInvoker"/>
</bean>

<beanid="fixedDepositService"class=".....FixedDepositServiceImpl"
parent="serviceTemplate">
<propertyname=“fixedDepositDao"ref="fixedDepositDao"/>
</bean>
<beanid="personalBankingService"class=".....PersonalBankingServiceImpl"
parent="serviceTemplate">
<propertyname="personalBankingDao"ref="personalBankingDao"/>
</bean>
<beanid="userRequestController"class=".....UserRequestControllerImpl">
<propertyname="serviceTemplate"ref="serviceTemplate"/>
</bean>
A littlebackgroundbefore we delve into the details ofthe above listedconfiguration: a service inthe
MyBank application may send JMS messages to a messaging-middleware or send emails to an email
server or it may invokean external web service. Intheabove example listing, the jmsMessageSender,
emailMessageSender and webServiceInvoker beans simplify these tasks by providing a layer of
abstraction.TheserviceTemplatebeanprovidesaccesstojmsMessageSender,emailMessageSenderand
webServiceInvoker beans. This is the reason why the serviceTemplate bean is dependent on the
jmsMessageSender,emailMessageSenderandwebServiceInvokerbeans.
Example listing 3-3 shows that the serviceTemplate bean definition is the parent bean definition of
fixedDepositServiceandpersonalBankingServicebeandefinitions.NoticethattheserviceTemplatebean
definitionisnotabstract;theclassattributespecifiesServiceTemplateastheclass.Inourpreviousbean
definition inheritance example (refer example listing 3-2), child bean definitions didn’t define any
properties.Intheaboveexamplelisting,noticethatthefixedDepositServiceandpersonalBankingService
childbeandefinitionsdefinefixedDepositDaoandpersonalBankingDaoproperties,respectively.
As parent bean definitions properties are inherited by the child bean definitions,
FixedDepositServiceImpl and PersonalBankingServiceImpl classes must define setter methods for
jmsMessageSender, emailMessageSender and webServiceInvoker properties. You have the option to
either define setter methods in FixedDepositServiceImpl and PersonalBankingServiceImpl classes or
make FixedDepositServiceImpl and PersonalBankingServiceImpl classes as subclasses of
ServiceTemplate class. In ch03-bankapp-inheritance-examples, the FixedDepositServiceImpl and
PersonalBankingServiceImplclassesaresubclassesofServiceTemplateclass.
ThefollowingexamplelistingshowsthePersonalBankingServiceImplclass:
Examplelisting3-4–PersonalBankingServiceImplclass
Project–ch03-bankapp-inheritance-examples
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/service
packagesample.spring.chapter03.bankapp.service;
publicclassPersonalBankingServiceImplextendsServiceTemplateimplements
PersonalBankingService{
privatePersonalBankingDaopersonalBankingDao;
publicvoidsetPersonalBankingDao(PersonalBankingDaopersonalBankingDao){
this.personalBankingDao=personalBankingDao;
}
@Override
publicBankStatementgetMiniStatement(){
returnpersonalBankingDao.getMiniStatement();
}
}
In example listing 3-3, we saw that the personalBankingService bean definition specifies
personalBankingDao as a dependency. In the above example listing, the setPersonalBankingDao setter
method corresponds to the personalBankingDao dependency. Also, notice that the
PersonalBankingServiceImplclassisasubclassoftheServiceTemplateclass.
Thefollowingdiagramshowsthataparentbeandefinition(likeserviceTemplate)neednotbeabstract,
child bean definitions (like fixedDepositService and personalBankingService) may define additional
properties, and classes represented by parent (like ServiceTemplate class) and child bean definitions
(like FixedDepositServiceImpl and PersonalBankingServiceImpl) may themselves be related by
inheritance:
Figure3-3–Childbeandefinitionsaddadditionalproperties,parentbeandefinitionisnotabstract,and
parent-childrelationshipexistsbetweentheclassesrepresentedbytheparentandchildbeandefinitions
Figure3-3shows:
·SpringcontainercreatesaninstanceofserviceTemplatebeanbecauseitsnotdefinedasabstract
·FixedDepositServiceImplandPersonalBankingServiceImplclasses(correspondingtothechild
bean definitions) are subclasses of ServiceTemplate class – the class corresponding to the
serviceTemplateparentbeandefinition.
·        And, fixedDepositService and personalBankingService bean definitions define additional
properties,fixedDepositDaoandpersonalBankingDao,respectively.Youshouldnotethatthechild
beandefinitionscanalsodefineadditionalconstructorargumentsandmethodoverrides(discussed
insection4-5).
AsserviceTemplatebeandefinitionisnotabstract,otherbeanscandefineserviceTemplatebeanastheir
dependency. For instance, in example listing 3-3, the serviceTemplate bean is a dependency of
userRequestController bean. You can infer from this discussion that if a parent bean definition is not
abstract,thefunctionalityofferedbytheparentbeancanbeutilizednotonlybychildbeansbutalsoby
otherbeansintheapplicationcontext.
Beandefinitioninheritanceexampleinheritingfactorymethodconfiguration
Childbeandefinitionscanusebeandefinitioninheritancetoinheritfactorymethodconfigurationfromthe
parentbeandefinition.Letslookatanexamplethatshowsfactorymethodconfigurationsareinheritedby
childbeandefinitions.
ThefollowingControllerFactoryclassdefinesagetControllerinstancefactorymethod:
Examplelisting3-5–ControllerFactoryclass
Project–ch03-bankapp-inheritance-examples
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/controller
packagesample.spring.chapter03.bankapp.controller;
publicclassControllerFactory{
publicObjectgetController(StringcontrollerName){
Objectcontroller=null;
if("fixedDepositController".equalsIgnoreCase(controllerName)){
controller=newFixedDepositControllerImpl();
}
if("personalBankingController".equalsIgnoreCase(controllerName)){
controller=newPersonalBankingControllerImpl();
}
returncontroller;
}
}
The above example listing shows that the getController factory method creates an instance of
FixedDepositControllerImpl or PersonalBankingControllerImpl class, depending upon the value of the
controllerNameargumentpassedtoit.IfthevalueofcontrollerNameargumentisfixedDepositController,
thegetController methodcreates an instance ofFixedDepositControllerImpl class. And, if the value of
controllerNameargumentispersonalBankingController,thegetControllermethodcreatesaninstanceof
PersonalBankingControllerImplclass.
The following bean definitions inthe applicationContext.xml file of ch03-bankapp-inheritance-example
project show that the child bean definitions inherit the getControllerinstance factory method
configurationfromtheparentbeandefinition:
Example listing 3-6 – applicationContext.xml - Bean definition inheritance – inheriting the factory
methodconfiguration
Project–ch03-bankapp-inheritance-examples
Sourcelocation-src/main/resources/META-INF/spring
<beanid="controllerFactory"
class="sample.spring.chapter03.bankapp.controller.ControllerFactory"/>
<beanid="controllerTemplate"factory-bean="controllerFactory"
factory-method="getController"abstract="true">
</bean>
<beanid="fixedDepositController"parent="controllerTemplate">
<constructor-argindex="0"value="fixedDepositController"/>
<propertyname=“fixedDepositService"ref="fixedDepositService"/>
</bean>
<beanid="personalBankingController"parent="controllerTemplate">
<constructor-argindex="0"value="personalBankingController"/>
<propertyname="personalBankingService"ref="personalBankingService"/>
</bean>
In the above example listing, the ControllerFactory class represents a factory class that defines a
getControllerinstance factory method. The controllerTemplate bean definition specifies that the
ControllerFactorysgetController factorymethodis used forcreatingbeaninstances.ThegetController
method (refer example listing 3-5) creates an instance of FixedDepositControllerImpl or
PersonalBankingControllerImplbean,dependingontheargumentpassedtothegetControllermethod.
As the controllerTemplate bean definition has been defined as abstract, it is up to the
fixedDepositController and personalBankingController child bean definitions to use the getController
factorymethodconfiguration.ThefixedDepositControllerbeandefinitionwouldliketopassanargument
to the ControllerFactorys getController factory method so that it creates an instance of
FixedDepositControllerImplbean.And,personalBankingControllerbeandefinitionwouldliketopassan
argument to the ControllerFactorys getController factory method so that it creates an instance of
PersonalBankingControllerImpl bean. We saw in section 2-3 of chapter 2 that the <constructor-arg>
element is used to pass an argument to aninstance factory method. In example listing 3-6, the
<constructor-arg>elementhasbeenusedbyfixedDepositControllerandpersonalBankingControllerchild
beandefinitionstopassfixedDepositService’and‘personalBankingService’values,respectively,tothe
getControllerfactorymethod.
It is recommended that you now run the main method of BankApp class of ch03-bankapp-inheritance-
examplesprojecttoseeusageofthebeandefinitioninheritanceexamplesdiscussedinthissection.
Letsnowlookathowconstructorargumentsarematched.
3-3Constructorargumentmatching
Inthepreviouschapter,wesawthattheconstructorargumentsarespecifiedinthebeandefinitionsusing
the<constructor-arg>element.Inthissection,we’lllookathowSpringcontainermatchesaconstructor
argumentspecifiedbya<constructor-arg>elementtothecorrespondingconstructorargumentspecifiedin
thebeanclasssconstructor.
Beforewegointothedetailsofconstructorargumentmatching,let’slookbackathowwepassarguments
toabeanclasssconstructor.
IMPORT chapter 3/ch03-bankapp-constructor-args-by-type (This project shows the MyBank
application in which bean class’s constructor arguments are matched by type (explained later in this
section).Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)
Passingsimplevaluesandbeanreferencesusing<constructor-arg>element
If a constructor argument is of simple Java type (like int, String, and so on), the <constructor-arg>
element’svalueattributeisusedtospecifythevalueoftheconstructorargument.Ifaconstructorargument
is a reference to a bean, you specify the name of the bean using the <constructor-arg> elements ref
attribute.
ThefollowingexamplelistingshowstheUserRequestControllerImplclassofch03-bankapp-constructor-
args-by-typeprojectwhoseconstructoracceptsanargumentoftypeServiceTemplate:
Examplelisting3-7–UserRequestControllerImplclass
Project–ch03-bankapp-constructor-args-by-type
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/controller
packagesample.spring.chapter03.bankapp.controller;
publicclassUserRequestControllerImplimplementsUserRequestController{
privateServiceTemplateserviceTemplate;

publicUserRequestControllerImpl(ServiceTemplateserviceTemplate){
this.serviceTemplate=serviceTemplate;
}

@Override
publicvoidsubmitRequest(Requestrequest){
//--dosomethingusingServiceTemplate
serviceTemplate.getJmsMessageSender();//--Forex.,sendJMSmessage
.....
}
}
The following example listing shows that a reference to ServiceTemplate instance (represented by
serviceTemplatebeandefinition)ispassedtoUserRequestControllerImplsconstructorusingrefattribute
of<constructor-arg>element:
Example listing 3-8 – applicationContext.xml - Passing reference to a Spring bean as constructor
argument
Project–ch03-bankapp-constructor-args-by-type
Sourcelocation-src/main/resources/META-INF/spring
<beanid="serviceTemplate"class="sample.spring.chapter03.bankapp.base.ServiceTemplate">
.....
</bean>
<beanid="userRequestController"
class="sample.spring.chapter03.bankapp.controller.UserRequestControllerImpl">
<constructor-argindex="0"ref="serviceTemplate"/>
</bean>
With this background information on how to pass simple values and bean references as constructor
arguments,letsnowlookathowSpringcontainermatchesconstructorargumenttypestolocatethebeans
constructortobeinvoked.
Constructorargumentmatchingbasedontype
Ifthe<constructor-arg>elementsindexattributeisnotspecified,Springcontainerlocatestheconstructor
tobeinvokedbymatchingthetypesreferencedbythe<constructor-arg>elementswiththeargumenttypes
specifiedinthebeanclass’sconstructor(s).
LetsfirstlookathowSpringcontainermatchesconstructorargumentswhentheconstructorargumentsare
Springbeansthatarenotrelatedbyinheritance.
ConstructorargumentsrepresentingdistinctSpringbeans
The following example listing shows the ServiceTemplate class that defines a constructor that accepts
referencestoJmsMessageSender,EmailMessageSenderandWebServiceInvokerbeans:
Examplelisting3-9–ServiceTemplateclass
Project–ch03-bankapp-constructor-args-by-type
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/base
packagesample.spring.chapter03.bankapp.base;
publicclassServiceTemplate{
.....
publicServiceTemplate(JmsMessageSenderjmsMessageSender,
EmailMessageSenderemailMessageSender,
WebServiceInvokerwebServiceInvoker){
.....
}
}
The following example listing shows the bean definitions for the ServiceTemplate class and the beans
referencedbyServiceTemplate:
Examplelisting3-10–applicationContext.xml-BeandefinitionfortheServiceTemplate class and its
dependencies
Project–ch03-bankapp-constructor-args-by-type
Sourcelocation-src/main/resources/META-INF/spring
<beanid="serviceTemplate"class="sample.spring.chapter03.bankapp.base.ServiceTemplate">
<constructor-argref="emailMessageSender"/>
<constructor-argref="jmsMessageSender"/>
<constructor-argref="webServiceInvoker"/>
</bean>
<beanid="jmsMessageSender"class="sample.spring.chapter03.bankapp.base.JmsMessageSender"/>
<bean id="emailMessageSender" class="sample.spring.chapter03.bankapp.base.EmailMessageSender"
/>
<beanid="webServiceInvoker"class="sample.spring.chapter03.bankapp.base.WebServiceInvoker"/>
Intheaboveexamplelisting,the<constructor-arg>elementsofserviceTemplatebeandon’tspecifythe
index attribute. The order in which the constructor arguments are specified by  the <constructor-arg>
elements is: EmailMessageSender, JmsMessageSender, WebServiceInvoker. The order in which
constructor arguments are specified in the ServiceTemplate classs constructor is: JmsMessageSender,
EmailMessageSender,WebServiceInvoker.Asyoucansee,theorderinwhichconstructorargumentsare
definedbythe<constructor-arg>elementsisdifferentfromtheorderspecifiedbytheServiceTemplate
classsconstructor.
If you execute the main method of BankApp class of ch03-bankapp-constructor-args-by-type project,
you’ll find that the Spring container successfully creates an instance of ServiceTemplate bean. This is
becauseJmsMessageSender,EmailMessageSenderandWebServiceInvokerclassesaredistinctinnature
(thatis,theyarenotrelatedbyinheritance),whichmakesiteasierfortheSpringcontainertoinjecttheir
instancesintotheServiceTemplateclasssconstructorinthecorrectorder.
Iftheconstructorargumenttypesarerelatedbyinheritance,Springcontainerneedsextrainstructionsto
help resolve constructor arguments. Lets now look at how Spring container matches constructor
argumentswhenbeansreferencedbytheconstructorargumentsarerelatedbyinheritance.
ConstructorargumentsrepresentingrelatedSpringbeans
ConsiderthefollowingSampleBeanbeanclasswhoseconstructoracceptsargumenttypesthatarerelated
byinheritance:
Examplelisting3-11–SampleBeanclass
publicclassSampleBean{
publicSampleBean(ABeanaBean,BBeanbBean){.....}
.....
}
The above example listing shows that the SampleBean classs constructor accepts ABean and BBean
typesasarguments.ABeanandBBeanrepresentSpringbeansthatarerelatedbyinheritance;BBeanisa
subclassofABean.
The following application context XML file shows the bean definitions for SampleBean, ABean and
BBeanclasses:
Examplelisting3-12–BeandefinitionsforSampleBean,ABeanandBBeanclasses
<beanid="aBean"class="example.ABean"/>
<beanid="bBean"class="example.BBean"/>

<beanid="sampleBean"class="example.SampleBean">
<constructor-argref="bBean"/>
<constructor-argref="aBean"/>
</bean>
AsaBeanandbBeanbeansarerelatedbyinheritance,Springcontainerappliesconstructorargumentsto
the SampleBeans constructor in the order in which <constructor-arg> elements appear in the bean
definitionfortheSampleBeanclass.IntheabovesampleBeanbeandefinition,thefirst<constructor-arg>
elementreferstobBeanbeanandthesecond<constructor-arg>elementreferstoaBeanbean.Thismeans
that bBean is passed as the first constructor argument and aBean is passed as the second constructor
argumenttotheSampleBeanconstructor.AsinstanceofABean(thesuperclass)can’t bepassedwhere
BBean(thesubclass)instanceisexpected,thesecond<constructor-arg>elementinthesampleBeanbean
definitionresultsinexceptionbeingthrownbytheSpringcontainer.Tohandlesuchscenarios,youcan
use <constructor-arg> elements index or type attribute to identify the constructor argument to which
<constructor-arg>elementapplies.Forinstance,thefollowingsampleBeanbeandefinitionmakesuseof
type attribute to indicate the type of the constructor argument to which the <constructor-arg> element
applies:
Examplelisting3-13 –<constructor-arg> element’stype attribute identifies the type of the constructor
argument
<beanid="sampleBean"class="example.SampleBean">
<constructor-argtype="sample.spring.chapter03.bankapp.controller.BBean"ref="bBean"/>
<constructor-argtype="sample.spring.chapter03.bankapp.controller.ABean"ref="aBean"/>
</bean>
The<constructor-arg>element’stypeattributespecifiesthefully-qualifiednameofthetypetowhichthe
<constructor-arg>elementapplies.Intheaboveexamplelisting,thefirst<constructor-arg>appliestothe
constructorargumentoftypeBBean,andthesecond<constructor-arg>elementappliestotheconstructor
argument of type ABean. Specifying the type attribute takes away the ambiguity that arises when
constructorargumentsarerelatedbyinheritance.
NOTEIftwoormoreconstructorargumentsareofthesametype,theonlyoptionistouseindex
attributetoidentifytheconstructorargumenttowhicheach<constructor-arg>elementapplies.
Sofarwehavelookedatconstructorargumenttypematchingscenariosinwhichconstructorarguments
represented distinct or related Spring beans. We’ll now look at how constructor argument types are
matchedforstandardJavatypes(likeint,long,boolean,String,Date,andsoon)andcustomtypes.
ConstructorargumentsrepresentingstandardJavatypesandcustomtypes
Ifthetypeofaconstructorargumentisaprimitivetype(likeint,long,boolean,andsoon)oraStringtype
or a custom type (like Address), the <constructor-arg> element’s value attribute is used to specify the
value. If there are 2 or more constructor arguments into which the string value specified by the value
attributecanbeconverted,it’llnotbepossiblefortheSpringcontainertoderivethetype(forexample,
whetherthevaluerepresentsanintorlongorString)oftheconstructorargument.Insuchscenarios,you
needtoexplicitlyspecifythetypeoftheconstructorargumentusingthetypeattribute.
ThefollowingexamplelistingshowstheTransferFundsServiceImplclassthatdefinesaconstructorwhich
acceptsargumentsoftypesString,boolean,longandint:
Examplelisting3-14–TransferFundsServiceImplclass
Project–ch03-bankapp-constructor-args-by-type
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/service
packagesample.spring.chapter03.bankapp.service;
publicclassTransferFundsServiceImplimplementsTransferFundsService{
publicTransferFundsServiceImpl(StringwebServiceUrl,booleanactive,longtimeout,
intnumberOfRetrialAttempts){.....}
.....
}
As the above example listing shows, TransferFundsServiceImpl constructor accepts the following
arguments:webServiceUrl,active,timeoutandnumberOfRetrialAttempts.Thefollowingbeandefinition
for the TransferFundsServiceImpl class shows how constructor argument values can be passed to the
TransferFundsServiceImplsconstructor:
Examplelisting3-15–BeandefinitionfortheTransferFundsServiceImplclass
<beanid="transferFundsService"
class="sample.spring.chapter03.bankapp.service.TransferFundsServiceImpl">
<constructor-argvalue="http://someUrl.com/xyz"/>
<constructor-argvalue="true"/>
<constructor-argvalue="5"/>
<constructor-argvalue="200"/>
</bean>
Letsassumethatthe3rd<constructor-arg>element(valueattribute’svalueis‘5’)issupposedtosupply
valueforthenumberOfRetrialAttemptsconstructorargument,andthe4th<constructor-arg>element(value
attribute’s value is ‘200’) is supposed to supply value for the timeout constructor argument. Spring
containerapplies<constructor-arg>elementstotheTransferFundsServiceImpl’sconstructorintheorder
inwhich<constructor-arg>elementsappearinthetransferFundsServicebeandefinition.Thismeansthat
the 3rd <constructor-arg> element applies to timeout argument, and the 4th <constructor-arg> element
appliestonumberOfRetrialAttemptsargument.Tohandlesuchambiguities,youcanspecifythetypeofa
constructorargumentvia<constructor-arg>element’stypeattribute,asshowninthefollowingexample
listing:
Examplelisting3-16–applicationContext.xml-<constructor-arg>element’stypeattribute
Project–ch03-bankapp-constructor-args-by-type
Sourcelocation-src/main/resources/META-INF/spring
<beanid="transferFundsService"
class="sample.spring.chapter03.bankapp.service.TransferFundsServiceImpl">
<constructor-argtype="java.lang.String"value="http://someUrl.com/xyz"/>
<constructor-argtype="boolean"value="true"/>
<constructor-argtype="int"value="5"/>
<constructor-argtype="long"value="200"/>
</bean>
IntheabovebeandefinitionfortheTransferFundsServiceImplclass,typeattributeisusedtospecifythe
constructor argument type. Spring container can now use type matching to correctly apply constructor
arguments.
NOTEIftwoormoreconstructorargumentsareofthesametype,theonlyoptionistouseindexattribute
foridentifyingtheconstructorargumenttowhicheach<constructor-arg>elementapplies.
Inthissection,wesawhowtypematchingisperformedbySpringtoresolveconstructorarguments.Lets
nowlookathowyoucaninstructSpringtoperformconstructorargumentmatchingbasedonconstructor
argumentsname.
IMPORT chapter 3/ch03-bankapp-constructor-args-by-name (This project shows the MyBank
application in which bean class’s constructor arguments are matched byname.To run the application,
executethemainmethodoftheBankAppclassofthisproject)
Constructorargumentmatchingbasedonname
The <constructor-arg> elements name attribute is used for specifying the name of the constructor
argument to which the <constructor-arg> element applies. The following example listing shows once
againtheTransferFundsServiceImplclasswhoseconstructoracceptsmultiplearguments:
Examplelisting3-17–TransferFundsServiceImplclass
Project–ch03-bankapp-constructor-args-by-name
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/service
packagesample.spring.chapter03.bankapp.service;
publicclassTransferFundsServiceImplimplementsTransferFundsService{
.....
publicTransferFundsServiceImpl(StringwebServiceUrl,booleanactive,longtimeout,
intnumberOfRetrialAttempts){.....}
}
The above example listing shows that the names of the constructor arguments defined by
TransferFundsServiceImpls constructor are: webServiceUrl, active, timeout and
numberOfRetrialAttempts.
NOTETheTransferFundsServiceImplclasssconstructoracceptsargumentsthataresimpleJavatypes
(like,int,long,boolean,String,andsoon),buttheconceptexplainedinthissectionalsoappliesto
scenariosinwhichconstructorargumentsarereferencestoSpringbeans.
ThefollowingbeandefinitionfortheTransferFundsServiceImplclassuses<constructor-arg>element’s
name attribute to specify the name of the constructor argument to which the <constructor-arg> element
applies:
Examplelisting3-18–applicationContext.xml-<constructor-arg>element’snameattribute
Project–ch03-bankapp-constructor-args-by-name
Sourcelocation-src/main/resources/META-INF/spring
<beanid="transferFundsService"
class="sample.spring.chapter03.bankapp.service.TransferFundsServiceImpl">
<constructor-argname="webServiceUrl"value="http://someUrl.com/xyz"/>
<constructor-argname="active"value="true"/>
<constructor-argname="numberOfRetrialAttempts"value="5"/>
<constructor-argname="timeout"value="200"/>
</bean>
TheaboveconfigurationwillworkonlyifTransferFundsServiceImplclassiscompiledwithdebugflag
enabled(referto-goptionofjavac).Whenthedebugflagisenabled,namesofconstructorargumentsare
preserved in the generated .class file. If you dont compile your classes with debug flag enabled, the
constructorargumentnamesarelostduringcompilation,andSpringhasnowaytolocatetheconstructor
argument corresponding to the constructor argument name specified by the <constructor-arg> element’s
nameattribute.
Ifyoudontwanttocompileyourclassesusingdebugflagenabled,youcanuse@ConstructorProperties
annotation(introducedinJavaSE6)toclearlyspelloutnamesoftheconstructorarguments,asshown
hereforTransferFundsServiceImplclass:
Examplelisting3-19–@ConstructorPropertiesannotation
Project–ch03-bankapp-constructor-args-by-name
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/service
packagesample.spring.chapter03.bankapp.service;
importjava.beans.ConstructorProperties;
publicclassTransferFundsServiceImplimplementsTransferFundsService{
@ConstructorProperties({"webServiceUrl","active","timeout","numberOfRetrialAttempts"})
publicTransferFundsServiceImpl(StringwebServiceUrl,booleanactive,longtimeout,
intnumberOfRetrialAttempts){.....}
}
In the above example listing, @ConstructorProperties annotation specifies the names of constructor
argumentsintheorderinwhichtheyappearinthebeanclass’sconstructor.Youmustensurethatyouuse
thesameconstructorargumentnamesinthe<constructor-arg>elements.
Letsnowlookathowthe@ConstructorPropertiesannotationaffectsbeandefinitioninheritance.
@ConstructorPropertiesannotationandbeandefinitioninheritance
If the constructor of the class corresponding to the parent bean definition is annotated with
@ConstructorPropertiesannotation,thebeanclasscorrespondingtothechildbeandefinitionmustalso
beannotatedwith@ConstructorPropertiesannotation.
The following example listing shows the serviceTemplate (parent bean definition) and
FixedDepositService(childbeandefinition)beandefinitions:
Examplelisting3-20–applicationContext.xml-Parentandchildbeandefinitions
Project–ch03-bankapp-constructor-args-by-name
Sourcelocation-src/main/resources/META-INF/spring
<beanid="serviceTemplate"
class="sample.spring.chapter03.bankapp.base.ServiceTemplate">
<constructor-argname="emailMessageSender"ref="emailMessageSender"/>
<constructor-argname="jmsMessageSender"ref="jmsMessageSender"/>
<constructor-argname="webServiceInvoker"ref="webServiceInvoker"/>
</bean>
<beanid="FixedDepositService"
class="sample.spring.chapter03.bankapp.service.FixedDepositServiceImpl"
parent="serviceTemplate">
<propertyname=“fixedDepositDao"ref="FixedDepositDao"/>
</bean>
TheaboveexamplelistingshowsthattheserviceTemplatebeandefinitionisnotabstract,whichmeans
that the Spring container will create an instance of serviceTemplate bean. The serviceTemplate bean
definition specifies 3 <constructor-arg> elements, corresponding to the 3 arguments defined by the
ServiceTemplateclass(referexamplelisting3-21).Aswehavespecifiedconstructorargumentsbyname
in the serviceTemplate bean definition, the ServiceTemplate class’s constructor is annotated with the
@ConstructorPropertiesannotationtoensurethatconstructorargumentnamesareavailabletoSpringat
runtime,asshownhere:
Examplelisting3-21–ServiceTemplateclass
Project–ch03-bankapp-constructor-args-by-name
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/base
packagesample.spring.chapter03.bankapp.base;
importjava.beans.ConstructorProperties;
publicclassServiceTemplate{
.....
@ConstructorProperties({"jmsMessageSender","emailMessageSender","webServiceInvoker"})
publicServiceTemplate(JmsMessageSenderjmsMessageSender,
EmailMessageSenderemailMessageSender,
WebServiceInvokerwebServiceInvoker){.....}
}
As FixedDepositService is a child bean definition of serviceTemplate, the <constructor-arg>
configurationinserviceTemplatebeandefinitionisinheritedbytheFixedDepositServicebeandefinition.
ThismeansthattheFixedDepositServiceImplclassmustdefineaconstructorthatacceptsthesamesetof
arguments as defined by the ServiceTemplate class, and itmust also be annotated with
@ConstructorProperties annotation. If you dont annotate FixedDepositServiceImpls constructor with
@ConstructorPropertiesannotation,Springcontainerwillnotbeabletomatchtheinherited<constructor-
arg>elementswiththeconstructorargumentsspecifiedintheFixedDepositServiceImplsconstructor.
Youcantuse@ConstructorPropertiesannotationforpassingargumentsbynametoastaticorinstance
factorymethod,asexplainednext.
@ConstructorPropertiesannotationandfactorymethods
We saw in section 2-3 of chapter 2 that the <constructor-arg> elements are also used for passing
argumentstostaticandinstancefactorymethods.Youmightthinkthatyoucanpassargumentsbynameto
static and instance factory methods by specifying the <constructor-arg> element’s name attribute and
annotating the factory method with @ConstructorProperties annotation. You should note that
@ConstructorProperties annotation is meant only for constructors; you can’t annotate methods with
@ConstructorProperties annotation. So, if you want to pass arguments by name to a static orinstance
factorymethod,theonlyoptionyouhaveistocompileclasseswithdebugflagenabled.
NOTEIfyoucompileclasseswithdebugflagenabled,itresultsin.classfilesthatarelargerinsize,but
hasnoimpactontheruntimeperformanceoftheapplication.Itonlyresultsinincreasedloadingtimefor
theclasses.
LetsnowlookathowtoenableordisabledebugflaginEclipseIDE.
Enabling(ordisabling)thedebugflaginEclipseIDE
InEclipseIDE,followthesestepstoenablethedebugflagforprojects:
1.GotoWindowsàPreferencesandselecttheoptionJavaàCompiler
2.YoullnowseeasectiontitledClassfileGeneration.Inthissection,ifyoucheckthecheckbox
labeled‘Addvariableattributestogeneratedclassfiles(usedbythedebugger),thedebugflagis
enabled.Uncheckingthischeckboxwilldisablethedebugflag.
Sofarwehavemostlyseenbeandefinitionexamplesinwhichbeanpropertiesandconstructorarguments
werereferencestootherbeans.Wellnowlookatbeandefinitionexamplesinwhichbeanpropertiesand
constructorargumentsareofprimitivetype,collectiontype,java.util.Date,java.util.Properties,andsoon.
3-4 Configuring different types of bean properties and constructor
arguments
Inrealworldapplicationdevelopmentscenarios,propertiesandconstructorargumentsofaSpringbean
could range from a String type to reference to another bean to any other standard (like java.util.Date,
java.util.Map)orcustom(likeAddress)type.Sofarwehaveseenexamplesofhowtosupplyvaluefor
String type bean properties (using value attribute of <property> element) and String type constructor
arguments (using value attribute of <constructor-arg> element). We also looked at how to inject
dependenciesviabeanproperties(usingrefattributeof<property>element)andconstructorarguments
(usingrefattributeof<constructor-arg>elements).
Inthissection,we’lllookatbuilt-inPropertyEditorimplementationsinSpringthatsimplifypassingbean
properties and constructor arguments of types java.util.Date, java.util.Currency, primitive type, and so
on.We’llalsolookathowtospecifyvaluesforcollectiontypes(likejava.util.Listandjava.util.Map)in
the application context XML file, and how to register a custom PropertyEditor implementation with
Spring.
Lets now look at bean definition examples that demonstrate use of built-in PropertyEditor
implementations.
IMPORT chapter 3/ch03-simple-types-examples (This project shows a Spring application in which
bean properties and constructor arguments are of primitive type, java.util.Date, java.util.List,
java.util.Map, and so on. This project also shows how to register a custom PropertyEditor
implementationwithSpringcontainer.Toruntheapplication,executethemainmethodoftheSampleApp
classofthisproject)
Built-inpropertyeditorsinSpring
JavaBeansPropertyEditorsprovidethenecessarylogicforconvertingaJavatypetoastringvalue,and
viceversa.Springprovidesacoupleofbuilt-inPropertyEditorsthatareusedforconvertingstringvalue
of a bean property or a constructor argument (specified via value attribute of <property> and
<constructor-arg>elements)totheactualJavatypeofthepropertyorconstructorargument.
Beforewelookat examples involvingbuilt-inPropertyEditors,lets firstunderstand the importance of
PropertyEditorsinsettingvaluesofbeanpropertiesorconstructorarguments.
ConsiderthefollowingBankDetailsclassthatwewanttoconfigureasasingleton-scopedbeanwithpre-
definedvaluesforitsattributes:
Examplelisting3-22–BankDetailsclass
publicclassBankDetails{
privateStringbankName;
publicvoidsetBankName(StringbankName){
this.bankName=bankName;
}
}
Intheaboveexamplelisting,bankNameisanattributeoftheBankDetailsclass,andisoftypeString.The
followingbeandefinitionfortheBankDetailsclassshowshowtosetthevalueofbankNameattributeto
‘MyPersonalBank:
Examplelisting3-23–BeandefinitionfortheBankDetailsclass
<beanid="bankDetails"class="BankDetails">
<propertyname="bankName"value="MyPersonalBank"/>
</bean>
In the above bean definition, the <property> element’s value attribute specifies a string value for the
bankNameproperty.Asyoucansee,ifabeanpropertyisoftypeString,youcansimplysetthatproperty
valueusing<property> element’s value attribute. Similarly, if a constructor argument is of type String,
youcansettheconstructorargumentvalueusing<constructor-arg>element’svalueattribute.
Letssaythatthefollowingattributes(alongwiththeirsettermethods)areaddedtotheBankDetailsclass:
a bankPrimaryBusiness attribute of type byte[], a headOfficeAddress attribute of type char[], a
privateBank attribute of type char, a primaryCurrency attribute of type java.util.Currency, a
dateOfInception attribute of type java.util.Date, and a branchAddresses attribute of type
java.util.Properties.ThefollowingexamplelistingshowsthemodifiedBankDetailsclass:
Examplelisting3-24–BankDetailsclasscontainingdifferenttypesofproperties
Project–ch03-simple-types-examples
Sourcelocation-src/main/java/sample/spring/chapter03/beans
packagesample.spring.chapter03.beans;
.....
publicclassBankDetails{
privateStringbankName;
privatebyte[]bankPrimaryBusiness;
privatechar[]headOfficeAddress;
privatecharprivateBank;
privateCurrencyprimaryCurrency;
privateDatedateOfInception;
privatePropertiesbranchAddresses;
.....
publicvoidsetBankName(StringbankName){
this.bankName=bankName;
}
//--moresettermethods
}
YoucanconfiguretheBankDetailsclassasaSpringbeanbyspecifyingstringvaluesfortheproperties,
and letting the Spring container convert these string values into the corresponding Java types of the
propertiesbyusingregisteredJavaBeansPropertyEditorimplementations.
ThefollowingbeandefinitionfortheBankDetailsclassshowsthatsimplestringvaluesarespecifiedfor
differentpropertytypes:
Examplelisting3-25–applicationContext.xml-BeandefinitionfortheBankDetailsclass
Project–ch03-simple-types-examples
Sourcelocation-src/main/resources/META-INF/spring
<beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">
<propertyname="bankName"value="MyPersonalBank"/>
<propertyname="bankPrimaryBusiness"value="Retailbanking"/>
<propertyname="headOfficeAddress"value="Addressofheadoffice"/>
<propertyname="privateBank"value="Y"/>
<propertyname="primaryCurrency"value="INR"/>
<propertyname="dateOfInception"value="30-01-2012"></property>
<propertyname="branchAddresses">
<value>
x=BranchX'saddress
y=BranchY'saddress
</value>
</property>
</bean>
Theaboveexamplelistingshows thatstring valuesarespecifiedforpropertiesoftypesjava.util.Date,
java.util.Currency, char[], byte[], char and java.util.Properties. Spring container uses registered
PropertyEditors for converting the string value of the property or constructor argument to the
correspondingJavatypeofthepropertyorconstructorargument.Forinstance,Springcontainerconverts
the value 30-01-2012’ of dateOfInception property to java.util.Date type using CustomDateEditor (a
built-inPropertyEditorimplementationforjava.util.Datetype).
If you look at how branchAddresses property (of type java.util.Properties) is configured in example
listing 3-25, youll notice that instead of <property> elements value attribute, <value> sub-element of
<property> element has been used to specify the value for the property. In case of single-valued
properties,theuseof<property>elementsvalueattributeispreferredover<value>sub-element.But,if
youneedtospecifymultiplevaluesforapropertyorthevaluesneedtobespecifiedonseparatelines(as
inthecaseofbranchAddressesproperty),the<value>sub-elementispreferredovervalueattribute.In
the next section, you’ll see that values for properties (or constructor arguments) of type
java.util.Properties can also be specified using <props> sub-element of <property> ( or <constructor-
arg>)element.
Springcomeswithcoupleofbuilt-inPropertyEditorimplementationsthatperformthetaskofconverting
valuesspecifiedintheapplicationcontextXMLfiletotheJavatypeofthebeanpropertyorconstructor
argument.Thefollowingtabledescribessomeofthebuilt-inPropertyEditorimplementationsinSpring:
Built-in PropertyEditor
implementation Description
CustomBooleanEditor convertsstringvaluetoBooleanorbooleantype
CustomNumberEditor convertsstringvaluetoanumber(likeint,long,andsoon)
ChracterEditor convertsstringvaluetochartype
ByteArrayPropertyEditor convertsstringvaluetobyte[]
CustomDateEditor convertsstringvaluetojava.util.Datetype
PropertiesEditor convertsstringvaluetojava.util.Propertiestype
Theabovetableshowsonlyasubsetofbuilt-inPropertyEditorimplementationsinSpring.Foracomplete
list,refertotheorg.springframework.beans.propertyeditorspackageofSpring.Itisimportanttonotethat
not all built-in PropertyEditor implementations in Spring are registered with the Spring container by
default. For instance, you need to explicitly register CustomDateEditor to allow Spring container to
performconversionfromastringvaluetoajava.util.Datetype.Laterinthissection,welllookathow
youcanregisterpropertyeditorswithSpringcontainer.
Lets now look at how to specify values for bean properties (or constructor arguments) of types
java.util.List,java.util.Setandjava.util.Map.
Specifyingvaluesfordifferentcollectiontypes
The <list>, <map> and <set> sub-elements (defined in Springs beans schema) of <property> and
<constructor-arg> elements are used to set properties and constructor arguments of type java.util.List,
java.util.Mapandjava.util.Set,respectively.
NOTESpringsutilschemaalsoprovides<list>,<set>and<map>elementsthatsimplifysetting
propertiesandconstructorargumentsofdifferentcollectiontypes.Laterinthischapter,we’lllookat
Springsutilschemaelementsindetail.
ThefollowingDataTypesExampleclassshowsthatitsconstructoracceptsargumentsofdifferenttypes:
Examplelisting3-26–DataTypesExampleclass
Project–ch03-simple-types-examples
Sourcelocation-src/main/java/sample/spring/chapter03/beans
packagesample.spring.chapter03.beans;
importjava.beans.ConstructorProperties;
.....
publicclassDataTypesExample{
privatestaticLoggerlogger=Logger.getLogger(DataTypesExample.class);

@SuppressWarnings("rawtypes")
@ConstructorProperties({"byteArrayType","charType","charArray",
"classType","currencyType","booleanType","dateType","longType",
"doubleType","propertiesType","listType","mapType","setType",
"anotherPropertiesType"})
publicDataTypesExample(byte[]byteArrayType,charcharType,
char[]charArray,ClassclassType,CurrencycurrencyType,
booleanbooleanType,DatedateType,longlongType,
doubledoubleType,PropertiespropertiesType,List<Integer>listType,
MapmapType,SetsetType,PropertiesanotherPropertiesType){
.....
logger.info("classType"+classType.getName());
logger.info("listType"+listType);
logger.info("mapType"+mapType);
logger.info("setType"+setType);
logger.info("anotherPropertiesType"+anotherPropertiesType);
}
}
The above example listing shows that the DataTypesExample classs constructor accepts arguments of
typesjava.util.List,java.util.Map,java.util.Setandjava.util.Properties,andsoon,andlogsthevalueof
eachconstructorargument.
ThefollowingexamplelistingshowsthebeandefinitionfortheDataTypesExampleclass:
Examplelisting3-27–applicationContext.xml-BeandefinitionforDataTypesExampleclass
Project–ch03-simple-types-examples
Sourcelocation-src/main/resources/META-INF/spring
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="anotherPropertiesType">
<props>
<propkey="book">GettingstartedwiththeSpringFramework</prop>
</props>
</constructor-arg>
<constructor-argname="listType"value-type="java.lang.Integer">
<list>
<value>1</value>
<value>2</value>
</list>
</constructor-arg>
<constructor-argname="mapType">
<map>
<entry>
<key>
<value>mapkey1</value>
</key>
<value>mapkey1’svalue</value>
</entry>
</map>
</constructor-arg>
<constructor-argname="setType">
<set>
<value>Element1</value>
<value>Element2</value>
</set>
</constructor-arg>
</bean>
Theaboveexamplelistingshows:
·        the value of anotherPropertiesType (of type java.util.Properties) is specified using the
<props>sub-elementof<constructor-arg>element.Each<prop>elementspecifiesakey-value
pair;thekeyattributespecifiesthekeyvalueandthecontentof<prop>elementisthevaluefor
thekey.Insteadofusing<props>element,youcanuse<value>sub-elementof<constructor-arg>
elementtospecifythevalueforanotherPropertiesTypeargument.
·thevalueoflistTypeconstructorargument(oftypejava.util.List)isspecifiedusingthe<list>
sub-element of <constructor-arg>. The <value> sub-elements of <list> element specify items
contained in the list. The <list> element’s value-type attribute specifies the Java type of the
elements that the java.util.List type constructor argument accepts. As the listType constructor
argumentisoftypeList<Integer>(referexamplelisting3-26),thevalue-typeattribute’svalueis
specifiedasjava.lang.Integer.Thevalue-typeattributeisoptional,andisparticularlyusefulif
you are using a parameterized List type, like List<Integer>. If you specify the value-type
attribute,Springcontainerusestheregisteredpropertyeditorstoperformconversionofvalues
tothetypespecifiedbythevalue-typeattribute,followedbyconverting(ifrequired)thevalues
tothetypeacceptedbytheparameterizedListtype.Ifyoudontspecifythevalue-typeattribute,
Springcontainersimplyusestheregisteredpropertyeditorstoperformconversionofvaluesto
thetypeacceptedbytheparameterizedListtype.
·thevalueofmapTypeconstructorargument(oftypejava.util.Map) is specified usingthe
<map>sub-elementof<constructor-arg>.The <entry>sub-elementof <map> specifies a key-
valuepaircontainedintheMap;the<key>elementspecifiesthekeyandthe<value>element
specifiesthevalueforthekey.Thekey-typeandvalue-typeattributesof<map>elementspecify
the Java type of keys and values that java.util.Map accepts. The key-type and value-type
attributes are optional, and especially useful if you are using parameterized Map type, like
Map<Integer,Integer>.Springcontainerusesregisteredpropertyeditorstoperformconversion
of keys and values to the types specified by the key-type and value-type attributes, and to the
typesacceptedbytheparameterizedMaptype.
·thevalueofthesetTypeconstructorargument(oftypejava.util.Set)isspecifiedusingthe
<set> sub-element of <constructor-arg>. Each <value> sub-element of <set> specifies an
elementcontainedintheSet.Thevalue-typeattributeof<set>elementspecifiestheJavatypeof
elementsthatjava.util.Setaccepts.Thevalue-typeattributeisoptional,andisusefulifyouare
using parameterized Set type, like Set<Integer>. Spring container uses registered property
editorstoperformconversionofvaluestothetypespecifiedbythevalue-typeattribute,andto
thetypeacceptedbytheparameterizedSettype.
InDataTypesExample class (refer example listing 3-26 and 3-27), constructor arguments of type List,
Map and Set contained elements of type String or Integer. In an application, a collection may contain
elements of type Map, Set, Class, Properties, or any other Java type. The elements contained in the
collectioncanalsobebeanreferences.Toaddresssuchscenarios,Springallowsyoutouseelementslike
<map>,<set>,<list>,<props>,<ref>,andsoon,assub-elementsof<list>,<map>and<set>elements.
LetsnowlookatexamplesthatdemonstratehowtoadddifferenttypesofelementstoMap,ListandSet
typeconstructorargumentsandbeanproperties.
AddingelementsoftypeList,Map,SetandPropertiestocollectiontypes
IfabeanpropertyorconstructorargumentisoftypeList<List>,simplyuseanested<list>element,as
shownhere:
Examplelisting3-28–Configurationexample:ListinsideaList
<constructor-argname="nestedList">
<list>
<list>
<value>AsimpleStringvalueinthenestedlist</value>
<value>AnothersimpleStringvalueinnestedlist</value>
</list>
</list>
</constructor-arg>
The <constructor-arg> element shown in the above example listing supplies value for a constructor
argumentnamednestedListwhichisoftypeList<List>.Thenested<list>elementrepresentsanelement
oftypeList.Similarly, you can use <map>,<set>and<props>elements inside a<list> element to set
value of properties or constructor arguments of type List<Map>, List<Set> and List<Properties>,
respectively.Aswiththe<list>element,a<set>elementcancontain<set>,<list>,<map>or<props>
element.Incaseofa<map>element,youcanuse<map>,<set>,<list>or<props>elementtospecifykey
andvalueofanentry.
ThefollowingexamplelistingshowshowyoucanspecifyvaluesforaMap<List,Set>typeconstructor
argument:
Examplelisting3-29–Configurationexample:MapcontainingListtypeaskeyandSettypeasvalue
<constructor-argname="nestedListAndSetMap">
<map>
<entry>
<key>
<list>
<value>aListelement</value>
</list>
</key>
<set>
<value>aSetelement</value>
</set>
</entry>
</map>
</constructor-arg>
The above example listing shows that the nestedListAndSetMap constructor argument is of Map type
whosekeyisoftypeListandvalueisoftypeSet.The<key>elementcanhaveeitherofthefollowing
elements as its sub-element: <map>,<set>,<list> and <props>. The value for the key can be defined
using<map>,<set>,<list>or<props>element.
Addingbeanreferencestocollectiontypes
Youcanuse<ref>elementsinside<list>and<set>elementstoaddreferencestobeansintoproperties
andconstructorargumentsoftypeListandSet,respectively.
The following example listing shows how references to beans are added to a List type constructor
argument:
Examplelisting3-30–Configurationexample:Listcontainingreferencetobeans
<bean.....>
<constructor-argname="myList">
<list>
<refbean="aBean"/>
<refbean="bBean"/>
</list>
</constructor-arg>
</bean>
<beanid="aBean"class="somepackage.ABean"/>
<beanid="bBean"class="somepackage.BBean"/>
Theaboveexamplelistingshows that the myList constructorargumentis of typeListand it contains 2
elements-areferencetoaBeanbeanandareferencetobBeanbean.The<ref>elementsbeanattribute
specifiesthenameofthebeanreferencedbythe<ref>element.
Aswiththe<list>element,youcanuse<ref>elementsinside<set>elementtoaddbeanreferencestoa
Set type constructor argument or bean property. In case of <map> element, you can use <ref> element
insidea<key>elementtospecifyabeanreferenceasakey,andusethe<ref>elementtospecifyabean
referenceasavalueforthekey.ThefollowingexamplelistingshowsaMaptypeconstructorargument
thatcontainsasinglekey-valuepairinwhichbothkeyandvaluearereferencestobeans:
Examplelisting3-31–Configurationexample:Mapcontainingbeanreferencesaskeysandvalues
<bean.....>
<constructor-argname="myMapWithBeanRef">
<map>
<entry>
<key>
<refbean="aBean"/>
</key>
<refbean="bBean"/>
</entry>
</map>
</constructor-arg>
</bean>
<beanid="aBean"class="somepackage.ABean"/>
<beanid="bBean"class="somepackage.BBean"/>
The above example listing shows that myMapWithBeanRef constructor argument is of type Map and it
contains a key-value pair in which the key is a reference to aBean bean and corresponding value is a
referencetobBeanbean.
Addingbeannamestocollectiontypes
Ifyouwanttoaddabeanname(asspecifiedbytheidattributeof<bean>element)toaList,MaporSet
type constructor argument or bean property, you can use the <idref>element inside <map>, <set> and
<list> elements. The following example listing shows a Map type constructor argument that contains a
singlekey-valuepair,wherebeannameisthekeyandbeanreferenceisthevalue:
Examplelisting3-32–Configurationexample:Mapcontainingbeannameaskeyandbeanreferenceas
value
<constructor-argname="myExample">
<map>
<entry>
<key>
<idrefbean="sampleBean"/>
</key>
<refbean="sampleBean"/>
</entry>
</map>
</constructor-arg>
<beanid="sampleBean"class="somepackage.SampleBean"/>
TheaboveexamplelistingshowsthatthemyExampleconstructorargumentisoftypeMapwhosekeyis
thestringvaluesampleBeanandvalueisthesampleBeanbean.Wecouldhaveused<value>elementto
setsampleBeanstringvalueasthekey,but<idref>elementisusedbecauseSpringcontainerverifies
existenceofthesampleBeanbeanwhentheapplicationisdeployed.
NOTEYoucanusethe<idref>elementinsidea<property>or<constructor-arg>elementtosetabean
nameasthevalueofabeanpropertyorconstructorargument.
Addingnullvaluestocollectiontypes
YoucanaddanullvaluetocollectionsoftypeSetandListusing<null>element.Thefollowingexample
listingshowshowtoaddanullvaluetoaSettypeconstructorargumentusing<null>element:
Examplelisting3-33–Configurationexample:Setcontaininganullelement
<constructor-argname="setWithNullElement">
<set>
<value>Element1</value>
<value>Element2</value>
<null/>
</set>
</constructor-arg>
Intheaboveexamplelisting,setWithNullElementconstructorargumentcontains3elements:Element1,
Element2andnull.
ToaddanullkeytoaMaptypeconstructorargumentorproperty,youcanuse<null>elementinsidethe
<key>element.And,toaddanullvalue,youcanadda<null>elementinsidethe<entry>element.The
following example listing shows a Map type constructor argument that contains a null key and a null
value:
Examplelisting3-34–Configurationexample:Mapcontaininganullkeyandanullvalue
<constructor-argname="mapType">
<map>
<entry>
<key>
<null/>
</key>
<null/>
</entry>
</map>
</constructor-arg>
TheaboveexamplelistingshowsthatanelementwithnullkeyandnullvalueisaddedtothemapType
constructorargumentusing<null>element.
NOTEYoucanalsouse<null>elementinside<property>and<constructor-arg>elementstosetnull
valuesforpropertiesandconstructorarguments,respectively.
Letsnowlookathowtospecifyvaluesforarraytypepropertiesandconstructorarguments.
Specifyingvaluesforarrays
If a bean class defines an array type property, you can set its value using the <array> sub-element of
<property> element. Similarly, you can set an array type constructor argument using the <array> sub-
elementof<constructor-arg>element.
Thefollowingexamplelistingshowshowyoucansetabeanpropertyoftypeint[]:
Examplelisting3-35–Configurationexample:Settingvalueofabeanpropertyoftypeint[]
<propertyname="numbersProperty">
<array>
<value>1</value>
<value>2</value>
</array>
</property>
Intheaboveexamplelisting,each<value>sub-elementofthe<array>elementrepresentsanelementin
thenumbersPropertyarray.ThepropertyeditorsregisteredwiththeSpringcontainerareusedtoconvert
thestringvaluespecifiedbyeachofthe<value>elementtointtype.Youcanuse<array>elementinside
<list>,<set>and<map>elements.Youcanalsouse<list>,<set>,<map>,<props>and<ref>elements
insidean<array>elementtocreatearraysofList,Set,Map,Propertiesandbeanreferences,respectively.
Ifyouwanttocreateanarrayofarrays,youcanuse<array>elementsinsidean<array>element.
Wediscussedthat<list>,<map>and<set>elementsareusedtosetpropertiesorconstructorarguments
of type List, Map andSet, respectively. Lets now look at the default collection implementation that is
createdbySpringforeachoftheseelements.
Defaultcollectionimplementationfor<list>,<set>and<map>elements
The following table shows the default collection implementation that is created by Spring for <list>,
<set>and<map>elements:
Collectionelement DefaultcollectionimplementationcreatedbyS pring
<list> java.util.ArrayList
<set> java.util.LinkedHashSet
<map> java.util.LinkedHashMap
Theabovetablesuggests:
·   if aproperty’s(or aconstructor arguments) value is specified using <list> element, Spring
createsaninstanceofArrayListandassignsittotheproperty(ortheconstructorargument).
·     if a propertys (or a constructor argument’s) value is specified using <set> element, Spring
createsaninstanceofLinkedHashSetandassignsittotheproperty(ortheconstructorargument).
·ifaproperty’s(oraconstructorarguments)valueisspecifiedusing<map>element,Spring
createsaninstanceofLinkedHashMapandassignsittotheproperty(ortheconstructorargument).
It is likely that you may want to substitute a different implementation of List, Set or Map to a bean
propertyoraconstructorargument.Forinstance,insteadofjava.util.ArrayList,youmaywanttoassignan
instanceofjava.util.LinkedListtoabeanpropertyoftypeList.Insuchscenarios,itisrecommendedto
use <list>, <map> and <set> elements of Springs util schema (explained in section 3-8). The <list>,
<set>and<map>elementsofSpringsutilschemaprovidetheoptiontospecifythefully-qualifiedname
oftheconcretecollectionclassthatyouwanttoassigntothepropertyorconstructorargumentofthebean.
Letsnowlookatsomeofthebuilt-inpropertyeditorsprovidedbySpring.
3-5Built-inpropertyeditors
Spring provides a couple of built-in property editors that are useful when setting bean properties and
constructor arguments. Let’s take a quick look at CustomCollectionEditor, CustomMapEditor and
CustomDateEditorbuilt-inpropertyeditors.Toviewthecompletelistofbuilt-inpropertyeditors,referto
org.springframework.beans.propertyeditorspackage.
CustomCollectionEditor
CustomCollectionEditor property editor is responsible for converting a source Collection (like,
java.util.LinkedList) type to the target Collection (like, java.util.ArrayList) type. By default,
CustomCollectionEditorisregisteredforSet,SortedSetandListtypes.
Consider the following CollectionTypesExampleclass that defines attributes (and corresponding setter
methods)oftypeSetandList:
Examplelisting3-36–CollectionTypesExampleclass
Project–ch03-simple-types-examples
Sourcelocation-src/main/java/sample/spring/chapter03/beans
packagesample.spring.chapter03.beans;
importjava.util.List;
importjava.util.Set;
publicclassCollectionTypesExample{
privateSetsetType;
privateListlistType;
.....
//--settermethodsforattributes
publicvoidsetSetType(SetsetType){
this.setType=setType;
}
.....
}
CollectionTypesExampleclassdefinessetTypeandlistTypeattributesoftypeSetandList,respectively.
ThefollowingexamplelistingshowsthebeandefinitionforCollectionTypesExampleclass:
Examplelisting3-37–applicationContext.xml-BeandefinitionforCollectionTypesExampleclass
Project–ch03-simple-types-examples
Sourcelocation-src/main/resources/META-INF/spring
<beanclass="sample.spring.chapter03.beans.CollectionTypesExample">
<propertyname="listType">
<set>
<value>setelement1</value>
<value>setelement2</value>
</set>
</property>
<propertyname="setType">
<list>
<value>listelement1</value>
<value>listelement2</value>
</list>
</property>
.....
</bean>
Youmightthinkthattheaboveconfigurationisincorrectbecause<set>elementhasbeenusedtosetthe
valueoflistType property(of type List), and <list> element has been used to set the value of setType
property(oftypeSet).
Theaboveconfigurationiscompletelylegal,andtheSpringcontainerdoesnotcomplain.Thisisbecause
CustomCollectionEditor converts the ArrayList instance (created corresponding to the <list> type
element)toLinkedHashSettype(animplementationofSettype)beforesettingthesetTypeproperty.Also,
CustomCollectionEditorconverts the LinkedHashSet instance (created corresponding to the <set> type
element)toArrayListtype(animplementationofListtype)beforesettingthelistTypeproperty.
Figure3-4–CustomCollectionEditorconvertstheLinkedHashSettoArrayListtype
Figure3-4showsthattheCustomCollectionEditorconvertstheLinkedHashSettypetoArrayListtosetthe
value of CollectionTypesExample’slistType property. The figure shows the sequence of steps that are
performed by Spring to set the value of listType property. First, Spring creates an instance of
LinkedHashSetcorrespondingtothe<set>element.AsthelistTypepropertyisoftypeList(referexample
listing3-36),theCustomCollectionEditorcomesintopictureforsettingthelistTypepropertysvalue.If
the type of the bean property is List, CustomCollectionEditor creates an instance of ArrayList and
populatesitwiththeelementsfromtheLinkedHashSet.Intheend,thevalueofthelistTypevariableisset
totheArrayListimplementationcreatedbyCustomCollectionEditor.
Itisimportanttonotethatifapropertyorconstructorargumenttypeisaconcretecollectionclass(like
LinkedList),CustomCollectionEditorsimplycreatesaninstanceoftheconcretecollectionclassandadds
elements to it from the source collection. The following figure shows a scenario in which the bean
propertyisoftypejava.util.Vector(aconcretecollectionclass):
Figure3-5CustomCollectionEditorconvertstheArrayListtoVectortype
The above figure shows that the CustomCollectionEditor creates an instance of Vector (a concrete
collectionclass)andaddselementstoitfromthesourcecollection,ArrayList.
LetsnowlookatCustomMapEditorpropertyeditor.
CustomMapEditor
CustomMapEditorpropertyeditordealswithconvertingasourceMaptype(likeHashMap) toa target
Maptype(likeTreeMap).Bydefault,CustomMapEditorisregisteredonlyforSortedMaptype.
Figure3-6showsascenarioinwhichCustomMapEditorconvertsLinkedHashMap(thesourceMaptype)
toTreeMap(animplementationofSortedMaptype).
Figure3-6showsthesequenceofstepsperformedbySpringtosetthevalueofmapTypeproperty.First,
Spring creates an instance of LinkedHashMap corresponding to the <map> element. As the mapType
propertyisoftypeSortedMap,CustomMapEditorcomesintopicturewhilesettingthevalueofmapType
property. CustomMapEditor creates an instance of TreeMap (a concrete implementation of SortedSet
interface),addskey-valuepairsfromLinkedHashMaptothenewlycreatedTreeMapinstanceandassigns
theTreeMapinstancetothemapTypeproperty.
Figure3-6CustomMapEditorconvertstheLinkedHashMap(thesourceMaptype)toTreeMap(thetarget
Maptype)type
CustomDateEditor
CustomDateEditorisapropertyeditorforjava.util.Datetypebeanpropertiesandconstructorarguments.
CustomDateEditorsupportsacustomjava.text.DateFormatthatisusedforformattingadate/timestringto
a java.util.Date type object, and parsing a java.util.Date type object to a date/time string. In the next
section,we’llseehowCustomDateEditorisusedforsettingbeanpropertiesandconstructorargumentsof
typejava.util.Date.In ch03-simple-types-examples project,CustomDateEditor converts the string value
ofabeanproperty(referdateOfInceptionattributeofBankDetailsclass)orconstructorargument(refer
dateTypeconstructorargumentofDataTypesExampleclass)tojava.util.Datetype.
Inch03-simple-types-examples project, some of the other built-in property editors that are utilized by
beans include: ByteArrayPropertyEditor - for converting a string value to byte[] (refer
bankPrimaryBusinessattributeofBankDetailsclass),CurrencyEditor–forconvertingacurrencycodeto
a java.util.Currency object (refer primaryCurrency attribute of BankDetails class),
CharacterArrayPropertyEditor – for converting a string value to a char[] (refer headOfficeAddress
attributeofBankDetailsclass),andsoon.
LetsnowlookathowtoregisterpropertyeditorswiththeSpringcontainer.
3-6RegisteringpropertyeditorswiththeSpringcontainer
SpringsBeanWrapperImplclassregistersacoupleofbuilt-inpropertyeditorswiththeSpringcontainer.
Forinstance,CustomCollectionEditor,CustomMapEditor,CurrencyEditor,ByteArrayPropertyEditorand
CharacterArrayEditor property editors are registered by default with the Spring container. But,
CustomDateEditor property editor isnot registered by default with the Spring container. To register
propertyeditorswith the Springcontainer,youcanuseSprings CustomEditorConfigurerspecial bean.
CustomEditorConfigurer class implements Springs BeanFactoryPostProcessor interface (explained in
detailinsection5-4ofchapter5),anditisautomaticallydetectedandexecutedbytheSpringcontainer.
In ch03-simple-types-examples project, BankDetails class (refer example listing 3-24) defines a
dateOfInceptionpropertyoftypejava.util.Date.ThevaluespecifiedforthedateOfInceptionpropertyis
‘30-01-2012’ (refer example listing 3-25). To convert the string value ‘30-01-2012’ to java.util.Date
type,youmustregisteracustompropertyeditorforjava.util.DatetypeoryoucanregisterSpringsbuilt-
inCustomDateEditorpropertyeditorwiththeSpringcontainer.
ToregisterpropertyeditorswiththeSpringcontainer,youneedtodothefollowing:
1.    Create a class that implements Springs PropertyEditorRegistrar interface. This class is
responsibleforregisteringpropertyeditorswiththeSpringcontainer.
2.ConfigurethePropertyEditorRegistrarimplementationasaSpringbeanintheapplicationcontext
XMLfile.
3.ConfigureSpringsCustomEditorConfigurerspecialbeanintheapplicationcontextXMLfile,and
provideitwithreferencetothePropertyEditorRegistrarimplementation(thatyoucreatedinstep1
andconfiguredinstep2).
Lets now see how CustomDateEditor is registered with the Spring container in ch03-simple-types-
examplesproject.
CreatingaPropertyEditorRegistrarimplementation
The following example listing shows the MyPropertyEditorRegistrar class that implements
PropertyEditorRegistrarinterface:
Examplelisting3-38–MyPropertyEditorRegistrarclass
Project–ch03-simple-types-examples
Sourcelocation-src/main/java/sample/spring/chapter03/beans
packagesample.spring.chapter03.beans;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importorg.springframework.beans.PropertyEditorRegistrar;
importorg.springframework.beans.PropertyEditorRegistry;
importorg.springframework.beans.propertyeditors.CustomDateEditor;
publicclassMyPropertyEditorRegistrarimplementsPropertyEditorRegistrar{
@Override
publicvoidregisterCustomEditors(PropertyEditorRegistryregistry){
registry.registerCustomEditor(Date.class,newCustomDateEditor(
newSimpleDateFormat("dd-MM-yyyy"),false));
}
}
The above example listing shows that the MyPropertyEditorRegistrar class implements Springs
PropertyEditorRegistrar interface, and provides implementation for registerCustomEditors method
defined in the PropertyEditorRegistrar interface. The PropertyEditorRegistry instance passed to the
registerCustomEditors method is used for registering property editors. PropertyEditorRegistrys
registerCustomEditor method is used for registering a PropertyEditor implementation with the Spring
container. In the above example listing, PropertyEditorRegistrys registerCustomEditor is used for
registeringaCustomDateEditorpropertyeditorwiththeSpringcontainer.
ConfiguringtheCustomEditorConfigurerclass
The following example listing shows how the CustomEditorConfigurer class is configured in the
applicationcontextXMLfile:
Examplelisting3-39–applicationContext.xml-CustomEditorConfigurerconfiguration
Project–ch03-simple-types-examples
Sourcelocation-src/main/resources/META-INF/spring
<beanid="myPropertyEditorRegistrar"
class="sample.spring.chapter03.beans.MyPropertyEditorRegistrar"/>
<beanid="editorConfigurer"
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<propertyname="propertyEditorRegistrars">
<list>
<refbean="myPropertyEditorRegistrar"/>
</list>
</property>
</bean>
In the above example listing, myPropertyEditorRegistrar bean definition configures
MyPropertyEditorRegistrarclassasaSpringbean.MyPropertyEditorRegistrarclassimplementsSprings
PropertyEditorRegistrar interface, and is responsible for registering additional property editors with
Spring container. CustomEditorConfigurers propertyEditorRegistrars property specifies a list of
PropertyEditorRegistrar implementations. In the above example listing, myPropertyEditorRegistrar is
specified as one of the values of propertyEditorRegistrars property. CustomEditorConfigurer bean is
automaticallydetectedandexecutedbytheSpringcontainer,resultinginregistrationofpropertyeditors
bytheMyPropertyEditorRegistrarinstance.
Lets now look at how to use p-namespace (for bean properties) and c-namespace (for constructor
arguments)towriteconcisebeandefinitionsinapplicationcontextXMLfiles.
3-7Concisebeandefinitionswithpandcnamespaces
To make bean definitions less verbose in application context XML files, Spring provides p and c
namespaces tospecify values for bean properties andconstructor arguments, respectively. Thep and c
namespacesarealternativestousing<property>and<constructor-arg>elements,respectively.
Letsfirstlookatp-namespace.
IMPORTchapter3/ch03-namespaces-example(ThisprojectshowsaSpringapplicationinwhichbean
properties and constructor arguments are set using p- and c-namespaces, respectively. To run the
application,executethemainmethodoftheSampleAppclassofthisproject)
p-namespace
Tousep-namespacetosetbeanproperties,specifybeanpropertiesasattributesofthe<bean>element,
andspecifyeachbeanpropertytobeinthep-namespace.
Thefollowingbeandefinitionshowshowtousep-namespacetosetbeanproperties:
Examplelisting3-40–applicationContext.xml-p-namespaceexample
Project–ch03-namespaces-example
Sourcelocation-src/main/resources/META-INF/spring
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation=".....">
<beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails"
p:bankName="MyPersonalBank"p:bankPrimaryBusiness="Retailbanking"
p:headOfficeAddress="Addressofheadoffice"p:privateBank="Y"
p:primaryCurrency="INR"p:dateOfInception="30-01-2012"
p:branchAddresses-ref="branchAddresses"/>
.....
</beans>
In the application context XML file shown above, p-namespace is specified via xmlns attribute. The
bankDetailsbeandefinitionmakesuseofthepprefixforthep-namespacetospecifybeanproperties.If
you compare the above example listing with the example listing 3-25, youll notice that the above
examplelistingislessverbose.Eventhoughitispossibletouseamixof<property>elementsand p-
namespace to specify bean properties, it’s recommended that you choose one style for specifying bean
propertiesanduseitconsistentlyinbeandefinitions.
NOTE As p-namespace is implemented as part of Spring, there isno schema corresponding to p-
namespace. For this reason, you dont see any schema reference corresponding to p-namespace in
example listing 3-40. If you want your IDE to autocomplete bean property names when using p-
namespace,considerusingIntelliJIDEAorSpringSourceToolSuite(STS).
Ifabeanpropertyisnotareferencetoanotherbean,itisspecifiedusingthefollowingsyntax:
p:<property-name>="<property-value>"
here,<property-name>isthenameofthebeanproperty,and<property-value>isthevalueofthebean
property.
Ifabeanpropertyisareferencetoanotherbean,itisspecifiedusingthefollowingsyntax:
p:<property-name>-ref="<bean-reference>"
here,<property-name>isthenameofthebeanproperty,and<bean-reference>istheid(orname)of
thereferencedbean.Itisimportanttonotethatthenameofthebeanpropertyisfollowedby--ref.Asthe
branchAddressespropertyofBankDetailsbeanrepresentsareferencetothebranchAddressesbean,the
branchAddressespropertyisspecifiedasp:branchAddresses-refinexamplelisting3-40.
Letsnowlookathowc-namespaceisusedforsettingconstructorarguments.
c-namespace
To use c-namespace to supply values for constructor arguments, specify constructor arguments as
attributesofthe<bean>element,andspecifyeachconstructorargumenttobeinthec-namespace.
ThefollowingexamplelistingshowstheBankStatementclassthatwellconfigureasaSpringbeanusing
c-namespace.
Examplelisting3-41–BankStatementclass
Project–ch03-namespaces-example
Sourcelocation-src/main/java/sample/spring/chapter03/beans
packagesample.spring.chapter03.beans;
importjava.beans.ConstructorProperties;
publicclassBankStatement{
.....
@ConstructorProperties({"transactionDate","amount","transactionType",
"referenceNumber"})
publicBankStatement(DatetransactionDate,doubleamount,
StringtransactionType,StringreferenceNumber){
this.transactionDate=transactionDate;
this.amount=amount;
.....
}
.....
}
ThefollowingbeandefinitionfortheBankStatementclassshowsusageofc-namespaceforsettingvalues
ofconstructorarguments:
Examplelisting3-42–applicationContext.xml-c-namespaceexample
Project–ch03-namespaces-example
Sourcelocation-src/main/resources/META-INF/spring
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation=".....">
.....
<beanid="bankStatement"class="sample.spring.chapter03.beans.BankStatement"
c:transactionDate="30-01-2012"
c:amount="1000"
c:transactionType="Credit"
c:referenceNumber="1110202"/>
.....
</beans>
In the above example listing, c-namespace is specified via xmlns attribute. The bankStatement bean
definition makes use of the c prefix for the c-namespace to specify constructor arguments. The syntax
followedforspecifyingconstructorargumentsusingc-namespaceissimilartowhatwesawincaseofp-
namespace.
NOTE As c-namespace is implemented as part of Spring, there isno schema corresponding to c-
namespace. For this reason, you dont see any schema reference corresponding to c-namespace in
examplelisting 3-42.If youwantyour IDEtoautocompleteconstructorargumentnames whenusingc-
namespace,considerusingIntelliJIDEAorSpringSourceToolSuite(STS).
Ifaconstructorargumentisnotareferencetoanotherbean,itisspecifiedusingthefollowingsyntax:
c:<constructor-argument-name>="<constructor-argument-value>"
here, <constructor-argument-name> is the name of the constructor argument, and <constructor-
argument-value>isthevalueoftheconstructorargument.
Ifaconstructorargumentisareferencetoanotherbean,itisspecifiedusingthefollowingsyntax:
c:<constructor-argument-name>-ref="<bean-reference>"
here,<constructor-argument-name>isthenameoftheconstructorargument,and<bean-reference>is
theid(orname)ofthereferencedbean.Itisimportanttonotethatthenameoftheconstructorargumentis
followedby--ref.Forinstance,ifaconstructorargumentnamedmyargumentrepresentsareferencetoa
beanwithid‘x’,youspecifymyargumentconstructorargumentas:
c:myargument-ref="x"
As mentioned earlier, if a class is compiled with debug flag enabled, constructor argument names are
preserved in the generated .class file. If the BankStatement class is not compiled with the debug flag
enabled,theconfigurationshowninexamplelisting3-42willnotwork.Insuchcases,yousupplyvalues
forconstructorargumentsusingtheirindex,asshownhere:
Examplelisting3-43–Supplyingvaluesforconstructorargumentsusingtheirindex
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation=".....">
.....
<beanid="bankStatement"class="sample.spring.chapter03.beans.BankStatement"
c:_0="30-01-2012"
c:_1="1000"
c:_2="Credit"
c:_3="1110202"/>
.....
</beans>
The above example listing shows bean definition for the BankStatement class, which uses constructor
argument index instead of constructor arguments name to supply values. It is important to note that the
indexoftheconstructorargumentisprefixedwithanunderscorebecauseattributenamesinXMLcannot
beginwithanumericvalue.Ifaconstructorargumentisareferencetoanotherbean,-refmustbeaddedto
the index of the constructor argument. For instance, if the constructor argument at index 0 represents
referencetoanotherbean,itisspecifiedasc:_0-ref.Eventhoughit’spossibletouseacombinationof
<constructor-arg>elementsandc-namespacetospecifyconstructorarguments,it’srecommendedthatyou
chooseonestyleofspecifyingconstructorargumentsanduseitconsistentlyinbeandefinitions.
Wesawearlierhow<list>,<map>and<set>elementsareusedtosetpropertiesorconstructorarguments
oftypeList,Map andSet, respectively. Lets now look at Springs util schema that simplifies creating
collectiontypes,Propertiestype,constants,andsoon,andexposingthemasaSpringbeans.
3-8Spring’sutilschema
Springs util schema simplifies configuring beans by providing a concise way to perform common
configurationtasks.Thefollowingtabledescribesthevariouselementsofutilschema:
Element Description
<list> Createsajava.util.Listtype,andexposesitasabean
<map> Createsajava.util.Maptype,andexposesitasabean
<set> Createsajava.util.Settype,andexposesitasabean
<constant> Exposesapublicstaticfieldonatypeasabean
<property-path> Exposesabeanpropertyasabean
<properties> Createsajava.util.Propertiesfromapropertiesfile,andexposesitasabean
NOTE All the elements of Springs util schema accept a scope attribute that identifies whether the
exposedbeanisasingleton-orprototype-scoped.
SpringprovidesaFactoryBeaninterfacethatcanbeimplementedtocreateafactoryobjectresponsible
forcreatingbeaninstances.Insteadofusingutilschema’selementsmentionedintheabovetable,youcan
useanout-of-the-boxFactoryBeanimplementationprovidedbySpringtoperformthesamefunctionality.
Inthissection,we’lllookattheutilschema’selementsandthebuilt-inFactoryBeanimplementationsthat
youcanuseinsteadofutilschema’selements.
IMPORTchapter3/ch03-util-schema-examples(This project shows a Spring application that makes
useofSpringsutilschemaelementstocreatesharedinstancesofList,Set,Map,andsoon.Torunthe
application,executethemainmethodoftheSampleAppclassofthisproject)
Letsfirstlookatthe<list>element.
<list>
The<list> element ofSprings util schema is used for creating objects of type java.util.List, as shown
here:
Examplelisting3-44–applicationContext.xml-utilschema’s<list>element
Project–ch03-util-schema-examples
Sourcelocation-src/main/resources/META-INF/spring
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=".....http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="listType"ref="listType"/>
.....
</bean>
<util:listid="listType"list-class="java.util.ArrayList">
<value>AsimpleStringvalueinlist</value>
<value>AnothersimpleStringvalueinlist</value>
</util:list>
</beans>
First,youneedtoincludeSpringsutilschematoaccessitselements.Intheaboveexamplelisting,the
<list>elementofutilschemacreatesaninstanceofjava.util.ArrayListandexposesitasabean.Theid
attribute specifies the bean id with which the java.util.ArrayList instance is exposed, and list-class
attribute specifies the concrete implementation of java.util.List that you want to create. If you dont
specify the list-class attribute, an instance of java.util.ArrayList is created by default. The <value>
elementofSpringsbeansschemaisusedtospecifyindividualelementsofthelist.
As util schema’s <list> element exposes a List instance as a bean, you can refer to the exposed List
instancefromotherbeans.Forinstance,intheaboveexamplelisting,thelistTypeconstructorargument
(oftypejava.util.List) of DataTypesExamplebeanspecifies listType as the value of the ref attribute to
refertotheListinstancecreatedbytheutilschema’s<list>element.
If you compare the util schema’s <list> element shown in the above example listing with the beans
schema’s<list>element(referexamplelisting3-27),youllnoticethattheutilschema’s<list>element
gives youcontrol over the List implementation to create.  For instance, if you want to create a Vector
insteadofanArrayListinstance,specifyjava.util.Vectorasthevalueofthelist-classattribute.
LetsnowlookatSpringsListFactoryBeanwhichyoucanuseinsteadofutilschema’s<list>element.
ListFactoryBean
Analternativetousingutilschema’s<list>elementisSpringsListFactoryBean–afactorythatisused
forcreatinginstancesofjava.util.ListandmakingthemavailableasSpringbeans.
ThefollowingexamplelistingshowshowtheListFactoryBeancanbeusedinsteadoftheutilschema’s
<list>element:
Examplelisting3-45–ListFactoryBeanexample
<beans.....>
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="listType"ref="listType"/>
.....
</bean>
<beanid="listType"class="org.springframework.beans.factory.config.ListFactoryBean">
<propertyname="sourceList">
<list>
<value>AsimpleStringvalueinlist</value>
<value>AnothersimpleStringvalueinlist</value>
</list>
</property>
</bean>
</beans>
Intheaboveexamplelisting,thesourceListpropertyofListFactoryBeanspecifiestheelementsinthelist.
Bydefault,ListFactoryBeancreatesaninstanceofjava.util.ArrayList.IfyouwanttheListFactoryBeanto
createaninstanceofanyotherListimplementation(likeVector),settheListFactoryBean’stargetListClass
property.ThetargetListClasspropertyspecifiesthefully-qualifiednameoftheconcreteimplementation
classofjava.util.ListinterfacethatshouldbecreatedbytheListFactoryBean.
Ifyoucompareexamplelistings3-44and3-45,youllnoticethatusingutilschema’s<list>elementisa
lotsimplerthanusingtheListFactoryBeantocreateaListinstanceandexposeitasabean.
<map>
The <map> element of Springs util schema is used for creating an object of type java.util.Map and
exposingitasabean,asshownhere:
Examplelisting3-46–applicationContext.xml-utilschema’s<map>element
Project–ch03-util-schema-examples
Sourcelocation-src/main/resources/META-INF/spring
<beans.....
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=".....http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="mapType"ref="mapType"/>
.....
</bean>
<util:mapid="mapType"map-class="java.util.TreeMap">
<entrykey="mapkey1"value="mapkey1’svalue"/>
</util:map>
.....
</beans>
Intheaboveexamplelisting,utilschema’s<map>elementcreatesaninstanceofjava.util.TreeMapand
exposes it as a bean. The id attribute specifies the id with which the bean is made available to other
beans,andmap-classattributespecifiesthefully-qualifiednameoftheconcreteimplementationclassof
java.util.Map interface that should be created by the <map> element. The <entry> element of Springs
beansschemaspecifiesakey-valuepairinthecreatedMapinstance.
Asthe<map>elementexposesaMapinstanceasabean,theexposedMapinstancecanbereferenced
fromotherbeans.Forinstance,intheaboveexamplelisting,DataTypesExample’smapTypeconstructor
argument (of type java.util.Map) specifies value of ref attribute as mapType to refer to the TreeMap
instancecreatedbythe<map>element.
NOTEWesawearlierinthischapterthat<key>and<value>sub-elementsof<entry>areusedtospecify
akey-valuepaircontainedintheMapinstance.Theexamplelisting3-46showsthatyoucanalsospecify
akey-valuepaircontainedintheMapinstancebyusing<entry>elementskeyandvalueattributes.
If you compare the util schema’s <map> element shown in the above example listing with the beans
schema’s <map> element in example listing 3-27, youll notice that the util schema’s <map> element
gives you control over the Map implementation to create.  For instance, if you want to use
LinkedHashMap instead of TreeMap, specify java.util.LinkedHashMap as the value of map-class
attribute. If you don’t specify the map-class attribute, Spring container creates an instance of
java.util.LinkedHashMapbydefault.
LetsnowlookatSpringsMapFactoryBeanthatyoucanuseinsteadofutilschema’s<map>element.
MapFactoryBean
Insteadofusingutilschema’s<map>element,youcanuseSpringsMapFactoryBean–afactorythatis
usedforcreatinginstancesofjava.util.MapandmakingthemavailableasSpringbeans.
ThefollowingexamplelistingshowshowMapFactoryBeanisused:
Examplelisting3-47–MapFactoryBeanexample
<beans.....>
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="mapType"ref="mapType"/>
.....
</bean>
<beanid="mapType"class="org.springframework.beans.factory.config.MapFactoryBean">
<propertyname="sourceMap">
<map>
<entrykey="mapkey1"value="mapkey1’svalue"/>
</map>
</property>
</bean>
.....
</beans>
In the above example listing, MapFactoryBean’s sourceMap property specifies the key-value pairs
containedintheMapinstancecreatedbytheMapFactoryBean.Bydefault,MapFactoryBeancreatesan
instanceofjava.util.LinkedHashMap.YoucancontroltheMapinstancecreatedbyMapFactoryBeanby
setting the targetMapClass property. The targetMapClass specifies the fully-qualified name of the
concreteimplementationclassofjava.util.Mapinterface.Forinstance,ifyouspecifyjava.util.HashMap
asthevalueoftargetMapClass,MapFactoryBeancreatesaninstanceofjava.util.HashMap.
If you compare example listings 3-46 and 3-47, youll notice that using util schema’s <map> element
resultsinamoreconciseconfigurationthanMapFactoryBeanforcreatingMapinstances.
<set>
The<set>elementofSpringsutilschemaisusedforcreatinganobjectoftypejava.util.Setandexposing
itasabean,asshownhere:
Examplelisting3-48–applicationContext.xml-utilschema’s<set>element
Project–ch03-util-schema-examples
Sourcelocation-src/main/resources/META-INF/spring
<beans.....
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=".....http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="setType"ref="setType"/>
</bean>
<util:setid="setType"set-class="java.util.HashSet">
<value>Element1</value>
<value>Element2</value>
</util:set>
.....
</beans>
Intheaboveexamplelisting,utilschema’s<set>elementcreatesaninstanceofHashSetandexposesitas
aSpringbeanwithidassetType.Theidattributespecifiestheidwithwhichthebeanismadeavailable
to other beans, and the set-class attribute specifies the concrete implementation class of java.util.Set
interface that should be created by the <set> element. The <value> element of Springs beans schema
specifiesanelementinthecreatedSetinstance.
TheSetinstancecreatedbythe<set>elementcanbereferencedfromotherbeans.Forinstance,inthe
aboveexamplelisting,DataTypesExample’ssetTypeconstructorargument(oftypejava.util.Set)refersto
theHashSetinstancecreatedbythe<set>element.
Insteadofusingutilschema’s<set>element,youcanuseSpringsSetFactoryBeantocreateaSetinstance
andexposeitasaSpringbean.
SetFactoryBean
SpringsSetFactoryBeanisafactoryobjectforcreatinginstancesofjava.util.Settype.
ThefollowingexamplelistingshowshowyoucanuseSetFactoryBeantoperformthesamefunctionasthe
utilschema’s<set>element:
Examplelisting3-49–SetFactoryBeanexample
<beans.....>
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="setType"ref="setType"/>
.....
</bean>
<beanid="setType"class="org.springframework.beans.factory.config.SetFactoryBean">
<propertyname="sourceSet">
<set>
<value>Element1</value>
<value>Element2</value>
</set>
</property>
</bean>
.....
</beans>
Intheaboveexamplelisting,SetFactoryBeanssourceSetpropertyspecifiestheelementscontainedinthe
SetinstancecreatedbytheSetFactoryBean.SetFactoryBeanstargetSetClasspropertyspecifiesthefully-
qualified name of the class that implements java.util.Set interface. If the targetSetClass property is
specified,SetFactoryBeancreatesaninstance of the class specified bythe targetSetClass property and
makes it available as a Spring bean. For instance, if you specify java.util.HashSet as the value of
targetSetClass,SetFactoryBeancreatesaninstanceofjava.util.HashSet.IfthetargetSetClasspropertyis
unspecified,SetFactoryBeancreatesaninstanceofjava.util.LinkedHashSet.
The above example listing shows that using util schema’s <set> element results in a more concise
configurationthanusingSetFactoryBeanforcreatingSetinstances.
<properties>
Theutilschema’s<properties>elementisusefulifyouwanttocreateaninstanceofjava.util.Properties
objectfromapropertiesfile,andexposethejava.util.Propertiesobjectasabean.
Thefollowingexamplelistingshowshowthe<properties>elementisused:
Examplelisting3-50–applicationContext.xml-utilschema’s<properties>element
Project–ch03-util-schema-examples
Sourcelocation-src/main/resources/META-INF/spring
<beans.....
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=".....http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">
.....
<propertyname="branchAddresses"ref="branchAddresses"/>
</bean>
.....
<util:propertiesid="branchAddresses"
location="classpath:META-INF/addresses.properties"/>
</beans>
Intheaboveexamplelisting,<properties>elementcreatesaninstanceofjava.util.Propertiescontaining
propertiesloadedfromtheaddresses.propertiesfile(specifiedbythelocationattribute),andexposesthe
java.util.PropertiesinstanceasabeanwithbranchAddressesastheid(specifiedbytheidattribute).The
above example listing also shows that the branchAddresses property (of type java.util.Properties) of
BankDetailsbeanreferstothebranchAddressesbeancreatedbytheutilschema’s<properties>element.
Analternativetousingthe<properties>elementisSpringsPropertiesFactoryBean.
PropertiesFactoryBean
SpringsPropertiesFactoryBeanisafactoryforcreatinginstancesofjava.util.Properties.
The following example listing shows how you can use PropertiesFactoryBean to perform the same
functionastheutilschema’s<properties>element:
Examplelisting3-51–PropertiesFactoryBeanexample
<beans.....>
<beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">
.....
<propertyname="branchAddresses"ref="branchAddresses"/>
</bean>
<beanid="branchAddresses"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<propertyname="location"value="classpath:META-INF/addresses.properties"/>
</bean>
.....
</beans>
Intheaboveexamplelisting,beandefinitionforSpringsPropertiesFactoryBeancreates an instance of
java.util.Properties from the properties loaded from addresses.properties file (specified by location
property),andexposesthejava.util.PropertiesinstanceasabeanwithbranchAddressesastheid.
<constant>
Theutilschema’s<constant>elementisusedforexposinganobjectspublicstaticfieldasaSpringbean.
Thefollowingexamplelistingshowsanexampleusageof<constant>element:
Examplelisting3-52–applicationContext.xml-utilschema’s<constant>element
Project–ch03-util-schema-examples
Sourcelocation-src/main/resources/META-INF/spring
<beans.....xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=".....http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="booleanType"ref="booleanTrue"/>
.....
</bean>
<util:constantid="booleanTrue"static-field="java.lang.Boolean.TRUE"/>
.....
</beans>
Theutilschema’s<constant>elementexposesthevaluespecifiedbyitsstatic-fieldattributeasaSpring
bean. In the above example listing, <constant> element exposes a bean whose value is
java.lang.Boolean.TRUEandidisbooleanTrue.Youcanspecifyanypublicstaticfieldasthevalueofthe
static-fieldattributeand refertoitfromotherbeansintheSpringcontainer.Forinstance,intheabove
example listing, booleanType bean is referenced by DataTypesExample’s booleanType constructor
argumentoftypeboolean.
A rather less concise way to expose public static fields as Spring beans is to use Springs
FieldRetrievingFactoryBean.
FieldRetrievingFactoryBean
SpringsFieldRetrievingFactoryBeanisafactoryforretrievingvalueofapublicstaticfieldspecifiedby
the FieldRetrievingFactoryBeans staticField property. The value retrieved by the
FieldRetrievingFactoryBeanisexposedasabean.YoucanalsousetheFieldRetrievingFactoryBeanto
retrieveanon-staticfieldvalue.
ThefollowingexamplelistingshowsanexampleusageofFieldRetrievingFactoryBean:
Examplelisting3-53–FieldRetrievingFactoryBeanexample
<beans.....>
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<constructor-argname="booleanType"ref="booleanTrue"/>
.....
</bean>
<beanid="booleanTrue"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<propertyname="staticField"value="java.lang.Boolean.TRUE"/>
</bean>
.....
</beans>
Intheaboveexamplelisting,FieldRetrievingFactoryBeanretrievesthevalueofjava.lang.Boolean.TRUE
field and exposes it as a bean. The bean exposed by the FieldRetrievingFactoryBean is referenced by
DataTypesExample’sbooleanTypeconstructorargumentoftypeboolean.
<property-path>
Theutilschema’s<property-path>elementisusedtoexposeabeanpropertyvalueasabean.
Thefollowingexamplelistingshowsanexampleusageof<property-path>element:
Examplelisting3-54–applicationContext.xml-utilschema’s<property-path>element
Project–ch03-util-schema-examples
Sourcelocation-src/main/resources/META-INF/spring
<beans.....
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=".....http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">
.....
<propertyname="dateOfInception"ref="dateType"/>
.....
</bean>
<util:property-pathid="dateType"path="dataTypes.dateType"/>
<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<propertyname="dateType"value="30-01-2012"/>
.....
</bean>
</beans>
In the above example listing, DataTypesExample’s dateType property (of type java.util.Date) value is
specified as ‘30-01-2012’. The <property-path> element retrieves the DataTypesExample’s dateType
propertyandexposesitasabeanwithidasdateType.Thepathattributeof<property-path>elementhas
thefollowingsyntax:
<bean-name>.<bean-property>
Here,<bean-name>istheidornameofthebean,and<bean-property>isthenameoftheproperty.
As<property-path>elementexposesa bean,theexposedbean canbereferencedbyother beansinthe
Spring container. For instance in the above example listing, dateType bean is referenced by
dateOfInceptionpropertyofBankDetailsbean.
Instead of using <property-path> element, you can use Springs PropertyPathFactoryBean to expose a
beanpropertyvalueasabean.
PropertyPathFactoryBean
PropertyPathFactoryBean is a factory used for creating bean instances that represent a bean property
value.
ThefollowingexamplelistingshowshowtousePropertyPathFactoryBean:
Examplelisting3-55–PropertyPathFactoryBeanexample
<beans.....
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=".....http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">
.....
<propertyname="dateOfInception"ref="dateType"/>
.....
</bean>
<beanid="dataType"
class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<propertyname="targetBeanName"value="dataTypes"/>
<propertyname="propertyPath"value="dateType"/>
</bean>

<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">
.....
<propertyname="dateType"value="30-01-2012"/>
.....
</bean>
</beans>
In the above example listing, PropertyPathFactoryBean is used to create an instance of a bean that
representsthevalueofdateTypepropertyofdataTypesbean.PropertyPathFactoryBeanstargetBeanName
attributespecifiestheidornameofthebeanthatcontainstheproperty,andPropertyPathFactoryBeans
propertyPath attribute specifies thename ofthe property whose valueis tobeexposed as a bean. The
bean instance created by PropertyPathFactoryBean can be accessed by other beans in the Spring
container. In the above example listing, the dataType bean created by PropertyPathFactoryBean is
referencedbydateOfInceptionproperty(oftypejava.util.Date)ofBankDetailsbean.
Now, that we have taken an in-depth look at util schema elements, lets look at Springs FactoryBean
interface.
3-9FactoryBeaninterface
SpringsFactoryBeaninterfaceisimplementedbyclassesthatactasafactoryforcreatingbeaninstances.
Intheprevioussection,wesawthattheclassesthatimplementtheFactoryBeaninterfaceareconfigured
intheapplicationcontextXMLfilelikeanyotherbean.FactoryBeanisparticularlyusefulifyouwantto
performcomplicatedconditionalcheckstodecideonwhichbeantypetocreate,andtoexecutecomplex
beaninitializationlogic.
Letsnowlookatanapplicationscenarioinwhichwe’lluseFactoryBeanforselectingabeantype,and
thencreatingit.
MyBankapplication–Storingeventsinthedatabase
In MyBank application, important events, like credit and debit transactions, open and liquidate fixed
deposits,andsoon,aresavedinthedatabase.MyBankmaydirectlysavetheseeventsinthedatabaseor
indirectlybyfirstsendingtheeventstoamessagingmiddlewareorawebservice.Thefollowingtable
describestheclassesthataredefinedbytheMyBankapplicationfordirectlyorindirectlysavingevents:
Class Description
DatabaseEventSender
Classthatcontainsthefunctionalityforsavingeventsinthedatabase
MessagingEventSender Classthatcontainsthefunctionalityforsendingeventstoamessagingmiddleware
WebServiceEventSender Classthatcontainsthefunctionalityforsendingeventstoaremotewebservice
Thedecisiontodirectlysavetheeventsinthedatabaseortosendthemtoamessagingmiddlewareora
web service is based on configuration. For instance, if MyBank finds that there exists a
database.properties file, MyBank reads the configuration information (like database url, username and
password)fromthedatabase.propertiesfileandcreatestheDatabaseEventSenderinstance.Similarly,ifa
messging.propertiesfileexists,MyBankcreatesaninstanceofMessagingEventSenderinstance,andifa
webservice.propertiesfileexists,aninstanceofWebServiceEventSenderiscreated.
Initializing DatabaseEventSender, MessagingEventSender and WebServiceEventSender instances may
require executing complex initialization logic. For instance, you need to create (or obtain from JNDI)
javax.jms.ConnectionFactory and javax.jms.Destination instances and set them on the
MessagingEventSender instance so that the MessagingEventSender can send JMS messages to the
messagingmiddleware.
The following class diagram shows that the FixedDepositServiceImpl class of MyBank uses either
DatabaseEventSender or MessagingEventSender or WebServiceEventSender instance to directly or
indirectlysaveeventsrelatedtofixeddepositsinthedatabase:
Figure3-7FixedDepositServiceImplclassusesoneoftheimplementationsofEventSenderinterface.
Intheaboveclassdiagram,sendEventmethodofEventSenderinterfacedefinesthecontractfordirectly
or indirectly saving events in the database. DatabaseEventSender, MessagingEventSender and
WebServiceEventSender classes implement the EventSender interface and provide an appropriate
implementationforthesendEventmethod.
LetsnowlookathowFactoryBeansimplifieschoosingtherightimplementationofEventSenderinterface
andinitializingit.
IMPORTchapter3/ch03-bankapp-factorybean(ThisprojectshowstheMyBankapplicationthatusesa
FactoryBean implementation to create objects of type EventSender. To run the application, execute the
mainmethodoftheBankAppclassofthisproject)
MyBankFactoryBeanexample
In MyBank, selecting the right EventSender implementation and initializing it is an involved task;
therefore,itrepresentsanidealscenarioforusingaFactoryBeanimplementation.FactoryBeaninterface
definesthefollowingmethodsthatyouneedtoimplement:
·getObjectType:returnsthetypeoftheobjectmanagedbytheFactoryBeanimplementation.In
caseofMyBank,theFactoryBeanimplementationcreatesandreturnsobjectsoftypeEventSender.
·getObject:returnstheobjectmanagedbytheFactoryBeanimplementation.IncaseofMyBank,
the getObject method returns an instance of DatabaseEventSender or MessagingEventSender or
WebServiceEventSender.
· isSingleton:returnstrueiftheFactoryBean implementation is afactoryfor singleton-scoped
objects.IftheisSingletonmethodreturnstrue,theobjectreturnedbythegetObjectmethodiscached
bytheSpringcontainerandthesameinstanceisreturnedonsubsequentrequests.IftheFactoryBean
implementationisafactoryforprototype-scopedobjects,returnfalsefromtheisSingletonmethod.
IftheisSingletonmethod returns false, a fresh instance is created by getObject method on every
request. In case of MyBank, FactoryBean implementation returns an instance of
DatabaseEventSender or MessagingEventSender or WebServiceEventSender class. Once created,
the same instance is used throughout the lifetime of the MyBank application; therefore, the
isSingletonmethodreturnstrueincaseofMyBank.
ThefollowingexamplelistingshowstheEventSenderFactoryBean–theFactoryBeanimplementationthat
createsandreturnsobjectsoftypeEventSender:
Examplelisting3-56–EventSenderFactoryBeanclass
Project–ch03-bankapp-factorybean
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/event
packagesample.spring.chapter03.bankapp.event;
importorg.springframework.beans.factory.FactoryBean;
importorg.springframework.beans.factory.FactoryBeanNotInitializedException;
importorg.springframework.core.io.ClassPathResource;
.....
publicclassEventSenderFactoryBeanimplementsFactoryBean<EventSender>{
privateStringdatabasePropertiesFile;
privateStringwebServicePropertiesFile;
privateStringmessagingPropertiesFile;
.....
publicEventSendergetObject()throwsException{
EventSendereventSender=null;
Propertiesproperties=newProperties();
ClassPathResourcedatabaseProperties=null;
if(databasePropertiesFile!=null){
databaseProperties=newClassPathResource(databasePropertiesFile);
}
.....
if(databaseProperties!=null&&databaseProperties.exists()){
InputStreaminStream=databaseProperties.getInputStream();
properties.load(inStream);
eventSender=newDatabaseEventSender(properties);
}
elseif(webServiceProperties!=null&&webServiceProperties.exists()){.....}
elseif(messagingProperties!=null&&messagingProperties.exists()){.....}
returneventSender;
}
publicClass<?>getObjectType(){
returnEventSender.class;
}
publicbooleanisSingleton(){
returntrue;
}
}
The above example listing shows that the EventSenderFactoryBean implements FactoryBean interface.
The EventSender parameter in FactoryBean<EventSender> indicates that the FactoryBeans getObject
returns objects of type EventSender. The databasePropertiesFile, webServicePropertiesFile and
messagingPropertiesFile are properties of the EventSenderFactoryBean class, and they represent the
locationofdatabase.properties,webservice.propertiesandmessaging.propertiesfilesintheclasspath.
ThegetObjectmethodusesSpringsClassPathResourceclasstoverifywhetherthespecifiedproperties
file exists in the classpath or not. If the properties file exists, properties from that file are loaded and
passed as to the EventSender implementation classs constructor. For instance, in the above example
listing,ifdatabase.propertiesfile(representedbydatabasePropertiesFileproperty)exists,propertiesare
loaded from the database.properties file and passed as an argument to the DatabaseEventSenders
constructor.ThegetObjectTypemethodreturnsEventSendertypebecausetheEventSenderFactoryBeans
getObjectmethodreturnsobjectsoftypeEventSender.TheisSingletonmethodreturnstrue,whichmeans
thattheobjectreturnedbygetObjectmethodiscachedbySpringandthesameinstanceisreturnedevery
timeEventSenderFactoryBeansgetObjectmethodisinvoked.
Now, that you have seen how EventSenderFactoryBean class is implemented in the MyBank, you can
guesshowSpring’sbuilt-inFactoryBeanimplementations,likeListFactoryBean(forcreatinginstancesof
Listtype),MapFactoryBean(forcreatinginstancesofMaptype),SetFactoryBean(forcreatinginstances
ofSettype),andsoon,areimplemented.
The following example listing shows how EventSenderFactoryBean is configured in the application
contextXMLfile:
Examplelisting3-57–applicationContext.xml-EventSenderFactoryBeanconfiguration
Project–ch03-bankapp-factorybean
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
<beanid="service"
class="sample.spring.chapter03.bankapp.service.FixedDepositServiceImpl">
.....
<propertyname="eventSender"ref="eventSenderFactory"/>
</bean>
.....
<beanid="eventSenderFactory"
class="sample.spring.chapter03.bankapp.event.EventSenderFactoryBean">
<propertyname="databasePropertiesFile"value="META-INF/config/database.properties"/>
</bean>
</beans>
The above example listing shows thattheEventSenderFactoryBean is configured likeanyother Spring
bean.EventhoughaFactoryBeanimplementationisconfiguredlikeanyotherSpringbean,itistreated
differentlybytheSpringcontainer.Oneofthemostimportantdifferencesisthatifabeanisdependenton
a FactoryBean implementation, the Spring container invokes the getObject method of the FactoryBean
implementationandinjectsthereturnedobjectintothedependentbean.
NOTEYoushouldnotethatFactoryBeansgetObjectmethodisinvokedonlyoncebytheSpring
containeriftheisSingletonmethodreturnstrue.
In the above example listing, bean definition for the FixedDepositServiceImpl class shows that it is
dependent on the EventSenderFactoryBean – a FactoryBean implementation. So, the Spring container
invokestheEventSenderFactoryBeansgetObjectmethodandinjectsthereturnedEventSenderobjectinto
theFixedDepositServiceImplinstance.
The following example listing shows the FixedDepositServiceImpl class that requires EventSender
instancecreatedbyEventSenderFactoryBean:
Examplelisting3-58–FixedDepositServiceImplclass
Project–ch03-bankapp-factorybean
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp/service
packagesample.spring.chapter03.bankapp.service;
importsample.spring.chapter03.bankapp.event.EventSender;
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
privateEventSendereventSender;
publicvoidsetEventSender(EventSendereventSender){
this.eventSender=eventSender;
}
.....
publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){
.....
eventSender.sendEvent(event);
}
}
The above example listing shows that the FixedDepositServiceImpl class depends on an EventSender
instanceandnotontheEventSenderFactoryBeaninstance.TheSpringcontainerobtainstheEventSender
instancebyinvokingEventSenderFactoryBean’sgetObjectmethod,andinjectstheobtainedEventSender
instanceintotheFixedDepositServiceImplinstance.
Letsnow lookathowto access theFactoryBean itself and not the bean it creates and returns via the
getObjectmethod.
AccessingtheFactoryBeaninstance
If you want to obtain the FactoryBean itself from the Spring container, prefix the name (or id) of the
factorybeanwithampersand‘&’.
LetssaythattheFixedDepositServiceImplclassrequiresaccesstotheEventSenderFactoryBeanitself,
asshownhere:
Example listing 3-59 – FixedDepositServiceImpl class that depends on the EventSenderFactoryBean
itself
packagesample.spring.chapter03.bankapp.service;
importsample.spring.chapter03.bankapp.event.EventSenderFactoryBean;
importsample.spring.chapter03.bankapp.event.EventSender;
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
privateEventSenderFactoryBeaneventSenderFactoryBean;
publicvoidsetEventSenderFactoryBean(EventSenderFactoryBeaneventSenderFactoryBean){
this.eventSenderFactoryBean=eventSenderFactoryBean;
}
.....
publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){
.....
EventSendereventSender=eventSenderFactoryBean.getObject();
evenSender.sendEvent(event);
}
}
Intheaboveexamplelisting,theFixedDepositServiceImplclassdependsontheEventSenderFactoryBean
itself,andusesitsgetObjectmethodtoobtainaninstanceofEventSenderobject.
Wesawinexamplelisting3-57thatwhenyoudefinetheEventSenderFactoryBeanbeanasadependency
of FixedDepositServiceImpl bean, the Spring container invokes the getObject method of
EventSenderFactoryBeanandinjectsthereturnedEventSenderobjectintotheFixedDepositServiceImpl
bean. To instruct the Spring container to inject the EventSenderFactoryBean itself, add ampersand ‘&’
prefixtotheid(orname)ofthebeanspecifiedbytherefattribute,asshowninthefollowingexample
listing:
Examplelisting3-60–InjectingtheEventSenderFactoryBeaninstanceintotheFixedDepositServiceImpl
bean
<beans.....>
<beanid="service"class="sample.spring.chapter03.bankapp.service.FixedDepositServiceImpl">
.....
<propertyname="eventSenderFactoryBean"ref="&amp;eventSenderFactory"/>
</bean>
.....
<beanid="eventSenderFactory"
class="sample.spring.chapter03.bankapp.event.EventSenderFactoryBean">
<propertyname="databasePropertiesFile"value="META-INF/config/database.properties"/>
</bean>
</beans>
In the above example listing, the following <property> element specifies that the
FixedDepositServiceImplbeanisdependentonEventSenderFactoryBean:
<propertyname="eventSenderFactoryBean"ref="&amp;eventSenderFactory"/>
Noticethattherefattribute’svalueis"&amp;eventSenderFactory".The&amp;prefixinstructstheSpring
containertoinjecttheEventSenderFactoryBeaninstanceitselfintotheFixedDepositServiceImplbean.
The use of ampersand ‘&’ is also required when you want to retrieve the FactoryBean instance itself
usingApplicationContext’sgetBeanmethod.ThefollowingexamplelistingshowstheBankAppclassof
MyBankapplicationthatretrievestheEventSenderobjectcreatedbytheEventSenderFactoryBean, and
theEventSenderFactoryBeaninstanceitself:
Examplelisting3-61–BankAppclass
Project–ch03-bankapp-factorybean
Sourcelocation-src/main/java/sample/spring/chapter03/bankapp
packagesample.spring.chapter03.bankapp;
.....
publicclassBankApp{
privatestaticLoggerlogger=Logger.getLogger(BankApp.class);

publicstaticvoidmain(Stringargs[]){
ApplicationContextcontext=newClassPathXmlApplicationContext(
.....
logger.info("InvokinggetBean(\"eventFactory\")returns:"+
context.getBean("eventSenderFactory"));
logger.info("InvokinggetBean(\"&eventFactory\")returns:"+
context.getBean("&eventSenderFactory"));
}
}
If you execute the main method of the BankApp class shown above, youll find that calling
getBean("eventSenderFactory") returns an instance of DatabaseEventSender class, and
getBean("&eventSenderFactory")returnsEventSenderFactoryBeaninstance.
3-10Summary
In this chapter, we saw how you can use bean definition inheritance to create less verbose and easily
manageablebeandefinitions.Themajorityofthischapterfocusedonhowtosetdifferenttypesofbean
properties andconstructorargumentsusingbuilt-inFactoryBeanimplementations,Springsutil schema,
and p- and c-namespaces. We also looked at some of the built-in PropertyEditor implementations in
SpringandhowtoregisteradditionalpropertyeditorswiththeSpringcontainer.Inthenextchapter,well
takeanin-depthlookatdependencyinjectionfeatureofSpring.
Chapter4-Dependencyinjection
4-1Introduction
In the previous chapter, we looked at how to configure beans using Springs util schema, p- and c-
namespaces,FactoryBeanimplementations,andsoon.Inthischapterwefocusondifferentdependency
injectionscenarios which we typically come across inreal world application development efforts and
howSpringaddressesthesescenarios.
We’llbeginthischapterwithalookatinnerbeans-analternativetousingtherefattributeof<property>
and<constructor-arg> elements. Well then look at depends-on attribute of the <bean> element. In the
second half of this chapter, we’ll look at issues that may arise when singleton- and prototype-scoped
beans collaborate to provide application behavior. Well wrap this chapter with an in-depth look at
Springsautowiringfeature.
IMPORTchapter4/ch04-bankapp-dependencies(Thisprojectshowsusageofinnerbeansand<bean>
element’sdepends-onattribute.Thisprojectalsoshowsimplicationsofdefiningdependenceofsingleton-
scopedbeansonprototype-scopedbeans,andviceversa.Toruntheapplication,executethemainmethod
oftheBankAppclassofthisproject)
4-2Innerbeans
Ifadependencyofabeanisnotsharedbymultiplebeans,youcanconsiderdefiningthedependencyasan
inner bean. An inner bean is defined inside a <property> or <constructor-arg> element by using the
<bean>elementofSpringsbeansschema.Youshouldnotethataninnerbeanisonlyaccessibletothe
beandefinitionenclosingit,andnottootherbeansregisteredwiththeSpringcontainer.
Thefollowingexamplelistingshowshowwegenerallyrepresentbeandependencies:
Examplelisting4-1–Dependencyspecifiedusing<property>elementsrefattribute
<beanid="service"
class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl">
<propertyname=“fixedDepositDao"ref="dao"/>
</bean>
<beanid="dao"class="sample.spring.chapter04.bankapp.dao.FixedDepositDaoImpl"/>
Theaboveexamplelistingshowsthattheservicebeanisdependentondaobean.Ifservicebeanisthe
onlybeanthatisdependentonthedaobean,thenyoucandefinethedaobeanasaninnerbeanofservice
bean.
Examplelisting4-2–applicationContext.xml-Innerbeanexample
Project–ch04-bankapp-dependencies
Sourcelocation-src/main/resources/META-INF/spring
<beanid="service"
class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl">
<propertyname=“fixedDepositDao">
<beanclass="sample.spring.chapter04.bankapp.dao.FixedDepositDaoImpl"/>
</property>
</bean>
In the above example listing, the bean definition for the FixedDepositDaoImpl class is inside the
<property>elementofservicebean.Ifyoucomparetheaboveexamplelistingwith4-1,youllnoticethat
the<property> element no longer specifies the ref attribute, and the <bean> element corresponding to
FixedDepositDaoImplclassdoesnthavetheidattributeanymore.
The<bean>elementcorrespondingtoaninnerbeandefinitiondoesn’tspecifyanidattributebecausean
inner bean is not registered with the Spring container. If you specify an id attribute for an inner bean
definition,itisignoredbytheSpringcontainer.Aninnerbeanisalwaysprototype-scoped;therefore,if
the <bean> element corresponding to an inner bean definition specifies the scope attribute, then it is
ignoredbytheSpringcontainer.Itisimportanttonotethataninnerbeanisanonymousinnature,andits
not accessible to other beans (except the bean that contains the inner bean definition) in the Spring
container.
NOTEAsincaseofnormalbeandefinition,youcanuse<property>,<constructor-arg>,andsoon,
elementsinsidethe<bean>elementoftheinnerbeandefinition.
Inthepreviouschapter,wesawthatSpringsutilschemaelementsareusedtocreatebeansthatrepresent
a List, Set, Map, and so on. We saw that the beans created by Springs util schema elements are
referenced by other beans. The concept of inner beans makes it possible to use Springs util schema
elements inside <property> and <constructor-arg> elements also, as shown in the following example
listing:
Examplelisting4-3–utilschema’s<list>elementdefinesaninnerbean
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=".....http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<beanid="someBean"class="com.sample.SomeBean">
.....
<constructor-argname="listType">
<util:listlist-class="java.util.ArrayList">
<value>AsimpleStringvalueinlist</value>
<value>AnothersimpleStringvalueinlist</value>
</util:list>
</constructor-arg>
.....
</bean>
</beans>
Intheaboveexamplelisting,thelistTypeconstructorargumentisoftypejava.util.List.Thevaluepassed
tothelistTypeconstructorargumentisspecifiedbytheutilschema’s<list>element.Notethatwedidnt
specifytheidattributeofthe<list>elementbecauseSpringcontainerignoresidsofinnerbeans.
Letsnowlookatdepends-onattributeof<bean>element.
4-3Explicitlycontrollingthebeaninitializationorderwithdepends-on
attribute
Insection1-4ofchapter1,wediscussedthatbeansarecreatedintheorderinwhichtheyaredefinedin
theapplicationcontextXMLfile.Theorderinwhichbeansarecreatedisalsodecidedbasedontheinter-
dependenciesofbeans.Forinstance,ifbeanAacceptsaninstanceofbeanBasaconstructorargument,
theSpringcontainerwillcreatebeanBbeforebeanAirrespectiveoftheorderinwhichtheyaredefined
intheapplicationcontextXMLfile.ThisbehavioroftheSpringcontainerensuresthatthedependencies
ofabean(beanBisadependencyinourexample)arecompletelyconfiguredbeforetheyareinjectedinto
thedependentbean(beanAisadependentbeaninourexample).
In some application scenarios, bean dependencies are not explicitly specified via <property> and
<constructor-arg> elements. If the bean dependencies arenot explicit, you can use <bean> element’s
depends-on attribute to explicitly specify dependencies of a bean. Spring container ensures that bean
dependencies specified by the depends-on attribute are initialized before the bean that specifies the
depends-onattribute.
Letsnowlookatanexamplescenarioinwhichdepends-onattributeisusedtocontroltheinitialization
orderofbeans.
MyBankimplieddependenciesbetweenbeans
IntheMyBankapplicationofthepreviouschapter,aFactoryBeanimplementationcreatedanEventSender
objectthatwasusedbytheFixedDepositServiceImplinstancetodirectlyorindirectlystoreeventsinthe
database (refer section 3-9 of chapter 3 for details). Lets say that instead of using a FactoryBean
implementation for creating an EventSender implementation, the approach shown in the following
diagramisadopted:
Figure4-1EventSenderSelectorServiceImplclasswritesthenameoftheEventSenderimplementation
intheappConfig.propertiesfile,whichislaterreadbytheFixedDepositServiceImplinstance
Theabovediagramshowsthat:
·anEventSenderSelectorServiceImplclassisusedtodecideontheEventSenderimplementation
(DatabaseEventSender or WebServiceEventSender or MessagingEventSender) to be used by the
FixedDepositServiceImplclass
·        EventSenderSelectorServiceImpl class stores the fully-qualified name of the EventSender
implementationintheappConfig.propertiesfile
·        FixedDepositServiceImpl class reads the fully-qualified name of the EventSender
implementationfromtheappConfig.propertiesfile,createstheEventSenderobjectandusesitfor
storingfixeddepositeventsinthedatabase
The above approach suggests that the FixedDepositServiceImpl instance wont work correctly if
EventSenderSelectorServiceImpl fails to save the fully-qualified name of the EventSender
implementation in the appConfig.properties file. This means that the FixedDepositServiceImpl class is
implicitlydependentontheEventSenderSelectorServiceImplclass.
Lets now look at the implication of implicit dependence of FixedDepositServiceImpl instance on the
EventSenderSelectorServiceImplinstance.
Implicitdependencyproblem
Consider the following application context XML file that contains bean definitions for
FixedDepositServiceImplandEventSenderSelectorServiceImplclasses:
Examplelisting4-4–applicationContext.xml-Implicitdependencyexample
Project–ch04-bankapp-dependencies
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
<beanid="service"
class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl">
.....
<constructor-argindex="0"value="META-INF/config/appConfig.properties"/>
</bean>
<beanid="eventSenderSelectorService"
class="sample.spring.chapter04.bankapp.service.EventSenderSelectorServiceImpl">
<constructor-argindex="0"value="META-INF/config/appConfig.properties"/>
</bean>
</beans>
The above application context XML file shows that both FixedDepositServiceImpl and
EventSenderSelectorServiceImplclasssconstructoracceptlocationoftheappConfig.propertiesfile.The
EventSenderSelectorServiceImplinstanceusestheappConfig.propertiesfileforcommunicatingthefully-
qualifiednameoftheEventSenderimplementationclasstotheFixedDepositServiceImplinstance.Asan
explicit dependence doesn’t exist between service and eventSenderSelectorService beans, Spring
containercreates theirinstancesintheorder inwhich theyare defined intheapplicationcontextXML
file. As the service bean is defined before the eventSenderSelectorService bean,
FixedDepositServiceImplinstance is created before EventSenderSelectorServiceImpl instance. We’ll
soon see that if FixedDepositServiceImplinstance is created before EventSenderSelectorServiceImpl
instance,theFixedDepositServiceImplinstancewillnotbeabletoreadthenameofthefully-qualified
EventSenderimplementationclassfromtheappConfig.propertiesfile.
Lets now take an in-depth look at the EventSenderSelectorServiceImpl and FixedDepositServiceImpl
classes,andtheappConfig.propertiesfile.
EventSenderSelectorServiceImplthewriter
ThefollowingexamplelistingshowstheEventSenderSelectorServiceImplclass:
Examplelisting4-5–EventSenderSelectorServiceImplclass
Project–ch04-bankapp-dependencies
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
importorg.springframework.core.io.ClassPathResource;
importsample.spring.chapter04.bankapp.Constants;
publicclassEventSenderSelectorServiceImpl{
publicEventSenderSelectorServiceImpl(StringconfigFile)throwsException{
ClassPathResourceresource=newClassPathResource(configFile);
OutputStreamos=newFileOutputStream(resource.getFile());
Propertiesproperties=newProperties();
properties
.setProperty(Constants.EVENT_SENDER_CLASS_PROPERTY,
"sample.spring.chapter04.bankapp.event.DatabaseEventSender");
properties.store(os,null);
.....
}
}
TheaboveexamplelistingshowsthatthelocationofappConfig.propertiesfileispassedasaconstructor
argument to the EventSenderSelectorServiceImpl classs constructor. The
EventSenderSelectorServiceImpl class’sconstructorwritesa property namedeventSenderClass (which
is the value of EVENT_SENDER_CLASS_PROPERTYconstant defined in the Constants class) to the
appConfig.properties file. The eventSenderClass property specifies the fully-qualified name of the
EventSender implementation to be used by the FixedDepositServiceImpl instance for directly or
indirectly saving events in the database. For the sake of simplicity, EventSenderSelectorServiceImpl
classs constructor sets the fully-qualified name of the DatabaseEventSender class as the value of
eventSenderClassproperty.
appConfig.properties
The following is the entry that gets added to the appConfig.propertiesfile by
EventSenderSelectorServiceImplclass:
eventSenderClass=sample.spring.chapter04.bankapp.event.DatabaseEventSender
FixedDepositServiceImplthereader
The eventSenderClass property written by the EventSenderSelectorServiceImpl instance is read by the
FixedDepositServiceImplinstance,asshowninthefollowingexamplelisting:
Examplelisting4-6–FixedDepositServiceImplclass
Project–ch04-bankapp-dependencies
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
importorg.springframework.core.io.ClassPathResource;
importsample.spring.chapter04.bankapp.Constants;
publicclassFixedDepositServiceImplimplementsFixedDepositService{
privateFixedDepositDaofixedDepositDao;
privateEventSendereventSender;
publicFixedDepositServiceImpl(StringconfigFile)throwsException{
ClassPathResourceconfigProperties=newClassPathResource(configFile);
if(configProperties.exists()){
InputStreaminStream=configProperties.getInputStream();
Propertiesproperties=newProperties();
properties.load(inStream);
StringeventSenderClassString=
properties.getProperty(Constants.EVENT_SENDER_CLASS_PROPERTY);
if(eventSenderClassString!=null){
Class<?>eventSenderClass=Class.forName(eventSenderClassString);
eventSender=(EventSender)eventSenderClass.newInstance();
logger.info("CreatedEventSenderclass");
}else{
logger.info("appConfig.propertiesfiledoesn'tcontaintheinformation"+
"aboutEventSenderclass");
}
}
}
publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{
.....
eventSender.sendEvent(event);
}
}
The above example listing shows following sequence of actions are performed by the constructor of
FixedDepositServiceImplclass:
·        loads properties from the appConfig.properties file. The configFile constructor argument
representsthelocationoftheappConfig.propertiesfile.
·        obtains property named eventSenderClass (represented by
EVENT_SENDER_CLASS_PROPERTY constant defined in the Constants class) from the
properties loaded fromtheappConfig.propertiesfile. The value of eventSenderClass property is
the fully-qualified name of the EventSender implementation class that FixedDepositServiceImpl
needstouse.ThevalueofeventSenderClasspropertyisstoredintheeventSenderClassStringlocal
variable.
·        creates an instance of the EventSender implementation class whose fully-qualified name is
stored in the eventSenderClassString variable, and stores the newly created instance into an
instance variable named eventSender. The eventSender variable is later used by the
FixedDepositServiceImplscreateFixedDepositmethod(refertothecreateFixedDepositmethodin
theaboveexamplelisting)todirectlyorindirectlystoreeventsinthedatabase.
YoushouldnotethatifapropertynamedeventSenderClassisnotfoundintheappConfig.propertiesfile,
theeventSenderClassStringvariableisnot set. In this case, the FixedDepositServiceImpls constructor
printsthefollowingmessageontheconsole:‘appConfig.propertiesfiledoesn'tcontaintheinformation
aboutEventSenderclass’.
In example listing 4-4, we looked at bean definitions for EventSenderSelectorServiceImpl and
FixedDepositServiceImplclasses, and concluded that the FixedDepositServiceImpl instance is created
beforeEventSenderSelectorServiceImplinstancebecauseSpringcontainerinitializesbeansintheorder
inwhichtheyappearintheapplicationcontextXMLfile.Wesawinexamplelisting4-5thatthecreation
of EventSenderSelectorServiceImpl instance results in writing an eventSenderClass property to the
appConfig.properties file. So, if the FixedDepositServiceImpl instance is created before the
EventSenderSelectorServiceImpl instance, the FixedDepositServiceImpl instance willnot find any
eventSenderClasspropertyintheappConfig.propertiesfile.ThisshowsthattheFixedDepositServiceImpl
class isimplicitly dependent on the EventSenderSelectorServiceImpl class; therefore, the
EventSenderSelectorServiceImplinstancemustbecreatedbeforetheFixedDepositServiceImplinstance.
Howtoaddressimplicitdependencyproblem?
Wecansolvetheimplicitdependencyproblemintwoways:
·        we change the order in which bean definitions for EventSenderSelectorServiceImpl and
FixedDepositServiceImpl classes are defined in the application context XML file. If the bean
definitionfortheEventSenderSelectorServiceImplclassappearsbeforethebeandefinitionforthe
FixedDepositServiceImpl class, the EventSenderSelectorServiceImpl instance will be created
beforetheFixedDepositServiceImplinstance.
·        use <bean> elements depends-on attribute to explicitly specify that the service bean
(corresponding to the FixedDepositServiceImpl class) is dependent on the
eventSenderSelectorServicebean(correspondingtotheEventSenderSelectorServiceImplclass).
Thefollowingexamplelistingshowstheusageof<bean>element’sdepends-onattribute:
Examplelisting4-7–<bean>elementsdepends-onattribute
<beans.....>
<beanid="service"
class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl"
depends-on="eventSenderSelectorService">
.....
</bean>
<beanid="eventSenderSelectorService"
class="sample.spring.chapter04.bankapp.service.EventSenderSelectorServiceImpl">
.....
</bean>
</beans>
In the above example listing, the service bean uses depends-on attribute to explicitly specify that it is
dependentontheeventSenderSelectorServicebean.Thedepends-onattributespecifiestheidsornames
of the beans on which the bean is dependent. As the service bean specifies that it is dependent on the
eventSenderSelectorService bean, Spring container creates eventSenderSelectorService bean
(corresponding to the EventSenderSelectorServiceImpl class) instance before service bean
(correspondingtotheFixedDepositServiceImplclass)instance.
NOTE If you execute the main method of the BankApp class of ch04-bankapp-dependencies project,
you’ll find that the FixedDepositServiceImpl instance is created before EventSenderSelectServiceImpl
instance. For this reason, the following message is printed on the console:‘appConfig.properties file
doesn'tcontaintheinformationaboutEventSenderclass’.
Multipleimplicitdependencies
Ifabeanhasmultipleimplicitdependencies,youcanspecifyidsornamesofallthosedependenciesas
thevalueofdepends-onattribute,asshownhere:
Examplelisting4-8–depends-onattributeexample-multipleimplicitdependencies
<beans.....>
<beanid="abean".....depends-on="bBean,cBean">
.....
</bean>
.....
</beans>
Theaboveexamplelistingshowsthatyoucanspecifymultiplebeanidsornamesasthevalueofdepends-
onattribute.
depends-onattributeandbeandefinitioninheritance
It is important to note that the depends-on attribute isnot inherited by child bean definitions. The
following example listing shows anabstract serviceTemplate parent bean definition that uses the
depends-onattributetospecifybaseServicebeanasadependency:
Examplelisting4-9–depends-onattribute–beandefinitioninheritance
<beanid="serviceTemplate"class=".....ServiceTemplate"depends-on="baseService"
abstract="true"/>

<beanid="someService"class=".....SomeServiceImpl"parent="serviceTemplate"/>
<beanid="someOtherService"class=".....SomeOtherServiceImpl"parent="serviceTemplate"/>
<beanid="baseService"class=".....BaseServiceImpl"/>
Intheaboveexamplelisting,someServiceandsomeOtherServicechildbeandefinitionsdon’tinheritthe
depends-on attribute from the serviceTemplate parent bean definition. As the Spring container creates
beansintheorderinwhichtheyaredefinedintheapplicationcontextXMLfile,thebaseServicebeanis
createdafterthecreationofsomeServiceandsomeOtherServicebeans.
Lets now look at how the Spring container manages dependencies of singleton- and prototype-scoped
beans.
4-4Singleton-andprototype-scopedbeansdependencies
Asingleton-scopedbean(anditssingleton-scopeddependencies)iscreatedwhentheApplicationContext
instance is created. And, a prototype-scoped bean (and its prototype-scoped dependencies) is created
eachtimeApplicationContextsgetBeanmethodisinvokedtoobtaintheprototype-scopedbean.
If a singleton-scoped bean is dependent on a prototype-scoped bean, or vice versa, things get a bit
complicated.Forinstance,ifasingleton-scopedbeanisdependentonaprototype-scopedbean,youmight
ask the question whether the Spring container will create the prototype-scoped bean (the dependency)
beforethesingleton-scopedbean(thedependentbean)?ortheSpringcontainerwillcreateandinjectthe
prototype-scopedbeaninstanceonlywhenyoucalltheApplicationContextsgetBeanmethodtoretrieve
the singleton-scoped bean instance? The answers to these questions lies in the way singleton- and
prototype-scopeddependenciesofabeanaremanagedbytheSpringcontainer,asexplainednext.
Singleton-scopedbean’sdependencies
The following example listing shows the singleton-scoped customerRequestService bean of MyBank
application,anditsdependencies:
Examplelisting4-10–applicationContext.xml-DependenciesofcustomerRequestServicebean
Project–ch04-bankapp-dependencies
Sourcelocation-src/main/resources/META-INF/spring
<beanid="customerRequestService"
class="sample.spring.chapter04.bankapp.service.CustomerRequestServiceImpl">
<constructor-argname="customerRequestDetails"ref="customerRequestDetails"/>
<constructor-argname="customerRequestDao"ref="customerRequestDao"/>
</bean>
<beanid="customerRequestDetails"
class="sample.spring.chapter04.bankapp.domain.CustomerRequestDetails"
scope="prototype"/>
<beanid="customerRequestDao"
class="sample.spring.chapter04.bankapp.dao.CustomerRequestDaoImpl"/>
TheaboveexamplelistingshowsthatthecustomerRequestService (singleton-scoped)beandepends on
customerRequestDetails (prototype-scoped) and customerRequestDao (singleton-scoped) beans.
CustomerRequestServiceobject(representedbythecustomerRequestServicebean)representsaservice
that is invoked when a bank customer creates a new request, like a cheque book request.
CustomerRequestServiceputsthedetailsofthecustomerrequestintoaCustomerRequestDetails object
(represented by the customerRequestDetails bean) and saves it in the data store using
CustomerRequestDaoobject(representedbythecustomerRequestDaobean).
ThefollowingexamplelistingshowsthemainmethodofBankAppclassthatloadsthebeandefinitions
showninexamplelisting4-10:
Examplelisting4-11–BankAppclass
Project–ch04-bankapp-dependencies
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp
packagesample.spring.chapter04.bankapp;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassBankApp{
privatestaticLoggerlogger=Logger.getLogger(BankApp.class);
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
.....
logger.info("BeginningwithaccessingCustomerRequestService");
CustomerRequestServicecustomerRequestService_1
=context.getBean(CustomerRequestService.class);
.....
CustomerRequestServicecustomerRequestService_2
=context.getBean(CustomerRequestService.class);
.....
logger.info("DonewithaccessingCustomerRequestService");
}
}
The above example listing shows that after the ApplicationContext instance is created,
ApplicationContextsgetBeanmethodisinvokedtwicetoobtainreferencetothecustomerRequestService
bean.
IfyouexecutethemainmethodoftheBankAppclass,you’llseethefollowingoutput:
CreatedCustomerRequestDetailsinstance
CreatedCustomerRequestDaoImplinstance
CreatedCustomerRequestServiceImplinstance
.....
BeginningwithaccessingCustomerRequestService
DonewithaccessingCustomerRequestService
TheCreated.....’messagesshownintheaboveoutputareprintedbytheconstructorsoftherespective
bean classes. The above output shows that the customerRequestDetails (prototype-scoped) and
customerRequestDao(singleton-scoped)dependenciesofthecustomerRequestService(singleton-scoped)
bean are created and injected into the customerRequestService instance when the Spring container is
created.AsnoCreated.....’message was printed on the console betweenBeginning.....’ and ‘Done
.....’ messages, no bean instances were created by the Spring container when ApplicationContext’s
getBeanmethodwasinvokedtoretrievethecustomerRequestServicebean.
Figure4-2showsthesequencediagramthatdepictsthesequenceofeventsthatoccurwhenBankApp’s
main method (refer example listing 4-11) is executed. Figure 4-2 shows that when Spring container is
created, the customerRequestDetails (prototype-scoped) and customerRequestDao (singleton-scoped)
beansarefirstcreated,followedbycreationofcustomerRequestService(singleton-scoped).Constructor-
based DI is used to inject the customerRequestDetails and customerRequestDao beans into the
customerRequestServicebean.Asasingleton-scopedbeaniscreatedonlyoncebytheSpringcontainer,
theSpringcontainerhasonlyoneopportunitytoinjectcustomerRequestServicebeansdependencies.For
thisreason,theSpringcontainerinjectsprototype-scopedcustomerRequestDetailsbeaninstanceintothe
customerRequestService beanonly once. The implication of this behavior is that the
customerRequestServicebeanendsupholdingreferencetothesamecustomerRequestDetailsbeanduring
itslifetime.
Figure 4-2 -The sequence of events that occur when the Spring container is created and the
customerRequestServicebeanisretrievedfromtheSpringcontainer
It is important to note that even if setter-based DI was used to inject the prototype-scoped
customerRequestDetails dependency of the customerRequestService bean, the Spring container would
have called the setter method onlyonce during the lifetime of the customerRequestService bean. This
meansthatirrespectiveofwhethersetter-orconstructor-basedDIisused,asingletonbeaniscreatedand
configuredonlyonceduringitslifetime.
Now,oncetheSpringcontaineriscreated,anyrequestforthesingleton-scopedcustomerRequestService
beanreturnsthesamecachedinstanceofthecustomerRequestServicebean.Forthisreason,no‘Created
.....’messagewaswrittenouttotheconsolebetweenBeginning.....’andDone.....’messageswhenwe
executedBankApp’smainmethod(referexamplelisting4-11).
As the singleton-scoped customerRequestService bean always holds reference to the same prototype-
scopedcustomerRequestDetailsbean, itmay adversely affectthe behavior ofMyBank application.For
instance, if multiple customers simultaneously submit request to the CustomerRequestServiceImpl
instance,alltherequestswillresultinmodifyingthesameinstanceoftheCustomerRequestDetailsobject
heldbytheCustomerRequestService.Ideally,CustomerRequestServiceImplshouldcreateanewinstance
ofCustomerRequestDetailsobjectoneveryrequest.Insection4-5,we’llseewhatmodificationsweneed
tomaketothebeanclassofasingleton-scopedbeansothatitcanretrieveanewinstanceofaprototype-
scopedbeanoneverymethodcall.
LetsnowlookathowtheSpringcontainermanagesprototype-andsingleton-scopeddependenciesofa
prototype-scopedbean.
Prototype-scopedbean’sdependencies
In MyBank, a customer registers with the MyBank application by following a sequence of steps. For
instance, a customer first enters personal information and his account details, and if the MyBank
application finds a matching record, the customer is asked for his debit card details. The
CustomerRegistrationServiceImplclassofMyBankapplicationcontainsthenecessarybusinesslogicto
registercustomers.AsthecustomersfollowasequenceofstepstoregisterwiththeMyBankapplication,
theCustomerRegistrationServiceImplobjectmaintainsconversationalstatebetweenmethodcalls.
The following example listing shows the prototype-scoped customerRegistrationService bean
(representingtheCustomerRegistrationServiceImplclass)ofMyBankapplication,anditsdependencies:
Examplelisting4-12–applicationContext.xml-customerRegistrationServicebeananditsdependencies
Project–ch04-bankapp-dependencies
Sourcelocation-src/main/resources/META-INF/spring
<beanid="customerRegistrationService"
class="sample.spring.chapter04.bankapp.service.CustomerRegistrationServiceImpl"
scope="prototype">
<constructor-argname="customerRegistrationDetails"ref="customerRegistrationDetails"/>
<constructor-argname="customerRegistrationDao"ref="customerRegistrationDao"/>
</bean>
<beanid="customerRegistrationDetails"
class="sample.spring.chapter04.bankapp.domain.CustomerRegistrationDetails"
scope="prototype"/>
<beanid="customerRegistrationDao"
class="sample.spring.chapter04.bankapp.dao.CustomerRegistrationDaoImpl"/>
TheaboveexamplelistingshowsthatthecustomerRegistrationService(prototype-scoped)beandepends
on customerRegistrationDetails (prototype-scoped) and customerRegistrationDao (singleton-scoped)
beans.
CustomerRegistrationServiceImpl instance maintains progress of the registration process, and stores
information provided by the customer during the registration process in a CustomerRegistrationDetails
object(representedbythecustomerRegistrationDetailsbean).AsbothCustomerRegistrationServiceImpl
and CustomerRegistrationDetails objects are stateful in nature, both customerRegistrationService and
customerRegistrationDetailsbeansaredefinedasprototype-scopedbeans.
ThefollowingexamplelistingshowsthemainmethodofBankAppclassthatloadscustomerregistration
relatedbeans(referexamplelisting4-12)andperformsregistrationsfor2customers:
Examplelisting4-13–BankAppclass
Project–ch04-bankapp-dependencies
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp
packagesample.spring.chapter04.bankapp;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassBankApp{
privatestaticLoggerlogger=Logger.getLogger(BankApp.class);
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
.....
logger.info("BeginningwithaccessingCustomerRegistrationService");
CustomerRegistrationServicecustomerRegistrationService_1=context
.getBean(CustomerRegistrationService.class);
customerRegistrationService_1.setAccountNumber("account_1");
customerRegistrationService_1.setAddress("address_1");
customerRegistrationService_1.setDebitCardNumber("debitCardNumber_1");
customerRegistrationService_1.register();
logger.info("registeredcustomerwithidaccount_1");
CustomerRegistrationServicecustomerRegistrationService_2=context
.getBean(CustomerRegistrationService.class);

.....
logger.info("registeredcustomerwithidaccount_2");
logger.info("DonewithaccessingCustomerRegistrationService");
}
}
The above example listing shows that the BankApp’smain method calls ApplicationContexts getBean
method twice to obtain reference to customerRegistrationService bean. Once the
customerRegistrationService bean instance is retrieved, the setAccountNumber, setAddress,
setDebitCardNumber and register methods are invoked on it. If you execute BankApp’s main method,
you’llseethefollowingoutputontheconsole:
CreatedCustomerRegistrationDaoImplinstance
.....
BeginningwithaccessingCustomerRegistrationService
CreatedCustomerRegistrationDetailsinstance
CreatedCustomerRegistrationServiceImplinstance
registeredcustomerwithidaccount_1
CreatedCustomerRegistrationDetailsinstance
CreatedCustomerRegistrationServiceImplinstance
registeredcustomerwithidaccount_2
DonewithaccessingCustomerRegistrationService
TheCreated.....’messagesshownintheaboveoutputareprintedbytheconstructorsoftherespective
bean classes. The above output shows that the singleton-scoped customerRegistrationDao bean
(representingtheCustomerRegistrationDaoImplclass)iscreatedonlyoncewhentheApplicationContext
instance is created. TheCreated.....’ messages between‘Beginning.....’ and Done.....’ messages
indicatethateachtimeApplicationContextsgetBeanmethod isinvokedto obtaintheprototype-scoped
customerRegistrationService bean, a new instance of the customerRegistrationService bean and its
prototype-scopeddependency(thecustomerRegistrationDetailsbean)iscreatedbytheSpringcontainer.
Figure4-3showsthesequencediagramthatdepictsthesequenceofeventsthatoccurwhenBankApp’s
main method (refer example listing 4-13) is executed. The figure shows that the singleton-scoped
customerRegistrationDaobeaniscreatedonlyoncewhenApplicationContextinstanceiscreated.When
theprototype-scopedcustomerRegistrationServicebeanisrequestedfromtheSpringcontainer,theSpring
container first creates an instance of customerRegistrationDetails bean (which is the prototype-scoped
dependency of the customerRegistrationService bean), followed by the creation of the
customerRegistrationServicebean.Thisshowsthatifaprototype-scopedbeanXisdependentonanother
prototype-scopedbeanY,SpringcontainerwillcreateanewinstanceofXandYeachtimeyourequest
beanXfromtheSpringcontainer.
Figure 4-3 – The sequence of events that occur when the Spring container is created and the
customerRegistrationServicebeanisretrievedfromtheSpringcontainer
Earlierinthissection,wesawthatifasingleton-scopedbeanisdependentonaprototype-scopedbean,
then throughout its lifetime the singleton-scoped bean is associated with the same instance of the
prototype-scopedbean.Letsnowlookatdifferentwaysinwhichasingleton-scopedbeancanretrievea
newinstanceofaprototype-scopedbeanfromtheSpringcontainer.
4-5Obtainingnewinstancesofprototypebeansinsidesingletonbeans
In the previous section, we saw that the prototype-scoped dependency of a singleton-scoped bean is
injectedatthetimeofcreationofthesingleton-scopedbean(referfigure4-2).Springcontainercreates
instanceofasingleton-scopedbeanonlyonce;therefore,thesingleton-scopedbeanholdsreferencetothe
sameprototype-scopedbeaninstanceduringitslifetime.Asingleton-scopedbean’smethodscanretrieve
a new instance of their prototype-scoped dependency from the Spring container using any one of the
followingapproaches:
·makethesingleton-scopedbeansclassimplementSpringsApplicationContextAwareinterface
·usethe<lookup-method>elementofSpringsbeansschema
·usethe<replaced-method>elementofSpringsbeansschema
NOTEItispossibletousethenewkeywordtocreateaninstanceoftheprototype-scopedbeansclassin
asingleton-scopedbeansmethodanduseit.Astheresponsibilityofcreatingabeaninstanceiswiththe
Springcontainer,weshouldnotattempttodirectlycreateabeaninstanceusingthenewkeyword.
IMPORTchapter4/ch04-bankapp-context-aware(Thisprojectshowsascenarioinwhichasingleton-
scopedbeanimplementsSpringsApplicationContextAwareinterfacetoobtaininstancesofaprototype-
scopedbeanfromtheSpringcontainer.Toruntheapplication,executethemainmethodoftheBankApp
classofthisproject)
LetsfirstbeginbylookingattheApplicationContextAwareinterface.
ApplicationContextAwareinterface
Springs ApplicationContextAware interface is implemented by beans that require access to the
ApplicationContext instance in which they are running. ApplicationContextAware interface defines a
single method, setApplicationContext, which provides the implementing beans with an instance of the
ApplicationContextobject.
ApplicationContextAwareinterfaceisalifecycleinterface,whichmeansthattheSpringcontainercalls
thebeansimplementingtheApplicationContextAwareinterfaceatappropriatetimesduringtheirlifetime.
Forinstance,ApplicationContextAware’ssetApplicationContextmethodiscalledbytheSpringcontainer
afterthebeaninstanceiscreatedbutbeforethebeaninstanceiscompletelyinitialized.Abeaninstanceis
consideredcompletelyinitializedonlyafteritsinitializationmethod(refersection5-2ofchapter5)is
calledbytheSpringcontainer.Itisimportanttonotethatafterabeaninstanceiscompletelyinitialized,it
is injected into the dependent bean instances by the Spring container. In chapter 5, we’ll look at some
morelifecycleinterfacesinSpring.
AbeanthatimplementstheApplicationContextAwareinterfacecanaccessotherbeansregisteredwiththe
ApplicationContextinstancebycallingApplicationContextsgetBeanmethod.Thismeansthatifthebean
class of a singleton-scoped bean implements ApplicationContextAware interface, it can fetch a new
instanceofaprototype-scopedbeanfromtheSpringcontainerbycallingApplicationContextsgetBean
method.Asthesingleton-scopedbeanexplicitlyobtainsitsprototype-scopeddependencyfromtheSpring
containerbycallingApplicationContext’sgetBeanmethod,youdontneedtodefinetheprototype-scoped
beanasadependencyofthesingleton-scopedbeanintheapplicationcontextXMLfile.
ThefollowingexamplelistingshowstheCustomerRequestServiceImplclassthatneedsanewinstanceof
CustomerRequestDetails object each time CustomerRequestServiceImpls submitRequest method is
called:
Examplelisting4-14–CustomerRequestServiceImplclass
Project–ch04-bankapp-context-aware
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
importsample.spring.chapter04.bankapp.dao.CustomerRequestDao;
importsample.spring.chapter04.bankapp.domain.CustomerRequestDetails;
publicclassCustomerRequestServiceImplimplementsCustomerRequestService{
privateCustomerRequestDetailscustomerRequestDetails;
privateCustomerRequestDaocustomerRequestDao;
@ConstructorProperties({"customerRequestDetails","customerRequestDao"})
publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,
CustomerRequestDaocustomerRequestDao){
this.customerRequestDetails=customerRequestDetails;
this.customerRequestDao=customerRequestDao;
}
publicvoidsubmitRequest(StringrequestType,StringrequestDescription){
//--populateCustomerRequestDetailsobjectandsaveit
customerRequestDetails.setType(requestType);
customerRequestDetails.setDescription(requestDescription);
customerRequestDao.submitRequest(customerRequestDetails);
}
}
TheaboveexamplelistingshowsthattheCustomerRequestDetailsandCustomerRequestDaoobjectsare
passedasargumentstotheCustomerRequestServiceImplclasssconstructor.ThesubmitRequestmethod
populates the CustomerRequestDetails instance and saves it into the database by calling
CustomerRequestDao’ssubmitRequest method.Ifmultiplecustomers simultaneouslysubmitrequest, the
submitRequest method will end up modifying the same instance of the CustomerRequestDetails object,
resulting in undesired behavior of MyBank application. To address this issue, the submitRequest must
obtainanewinstanceoftheCustomerRequestDetailsobjectfromtheSpringcontaineroneachinvocation.
The following example listing shows the CustomerRequestServiceContextAwareImpl class (a modified
versionofCustomerRequestServiceImplclassthatwesawinexamplelisting4-14)thatimplementsthe
ApplicationContextAwareinterface:
Example listing 4-15 – CustomerRequestServiceContextAwareImpl class that implements Springs
ApplicationContextAwareinterface
Project–ch04-bankapp-context-aware
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.ApplicationContextAware;
publicclassCustomerRequestServiceContextAwareImplimplements
CustomerRequestService,ApplicationContextAware{

privateCustomerRequestDaocustomerRequestDao;
privateApplicationContextapplicationContext;
@ConstructorProperties({"customerRequestDao"})
publicCustomerRequestServiceContextAwareImpl(CustomerRequestDaocustomerRequestDao)
{
this.customerRequestDao=customerRequestDao;
}
publicvoidsetApplicationContext(ApplicationContextapplicationContext)
throwsBeansException{
this.applicationContext=applicationContext;
}

publicvoidsubmitRequest(StringrequestType,StringrequestDescription){
CustomerRequestDetailscustomerRequestDetails=applicationContext
.getBean(CustomerRequestDetails.class);
customerRequestDetails.setType(requestType);
customerRequestDetails.setDescription(requestDescription);
customerRequestDao.submitRequest(customerRequestDetails);
}
}
In the above example listing, setApplicationContext method provides
CustomerRequestServiceContextAwareImpl with an instance of ApplicationContext object. The
ApplicationContext instance is later used by the submitRequest method to obtain an instance of
CustomerRequestDetailsobjectfromtheSpringcontainer.
As the CustomerRequestServiceContextAwareImpl class explicitly obtains CustomerRequestDetails
object from the Spring container, youdon’t need to use Springs DI mechanism to inject
CustomerRequestDetails instance intotheCustomerRequestServiceContextAwareImpl instance. For this
reason, CustomerRequestServiceContextAwareImpl classs constructor (refer example listing 4-15)
doesntspecifyCustomerRequestDetailsobjectasanargument.Ifyounowgotoch04-bankapp-context-
awareprojectandexecuteBankApp’smainmethod,youllfindthatoneachinvocationofsubmitRequest
methodanewinstanceofCustomerRequestDetailsobjectisfetchedfromtheSpringcontainer.
InthecontextofMyBank,wesawthattheApplicationContextAwareinterfaceisusefulifabeanrequires
access to other beans. The downside of implementing the ApplicationContextAware interface is that it
couples your bean class to Spring Framework. You can avoid coupling your bean classes with Spring
FrameworkandstillaccessotherbeansfromtheSpringcontainerbyusingmethodinjectiontechniques
offeredby<lookup-method>and<replaced-method>elementsofSpringsbeansschema.
Letsfirstlookatthe<lookup-method>element.
IMPORT chapter 4/ch04-bankapp-lookup-method (This project shows the MyBank application that
uses<lookup-method>elementofSpringsbeansschema.Toruntheapplication,executethemainmethod
oftheBankAppclassofthisproject)
<lookup-method>element
Ifabeanclassdefinesabeanlookupmethodwhosereturntyperepresentsabean,the<lookup-method>
element instructs the Spring container to provide implementation for this method. The method
implementationprovidedbytheSpringcontainerisresponsibleforretrievingthebeaninstancefromthe
Springcontainerandreturningit.
The <lookup-method> element’s bean attribute specifies the name of the bean to be looked-up and
returnedbythemethodimplementation,andthenameattribute specifies the nameof themethodwhose
implementation is to be provided by the Spring container. It is important to note that the bean lookup
methoddefinedbythebeanclasscanbeanabstractoraconcretemethod.
NOTETheuseof<lookup-method>elementtoinstructtheSpringcontainertoprovideimplementation
forabeanlookupmethodisreferredtoasaMethodInjectiontechinique’becausethe<lookup-method>
elementinjectsabeanlookupmethodimplementationintothebeanclass.
The following example listing shows CustomerRequestServiceImpls getCustomerRequestDetails
abstractmethodthatreturnsaninstanceofCustomerRequestDetailsinstance:
Examplelisting4-16–CustomerRequestServiceImplclass–definingabeanlookupmethod
Project–ch04-bankapp-lookup-method
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
publicabstractclassCustomerRequestServiceImplimplementsCustomerRequestService{
privateCustomerRequestDaocustomerRequestDao;
@ConstructorProperties({"customerRequestDao"})
publicCustomerRequestServiceImpl(CustomerRequestDaocustomerRequestDao){
this.customerRequestDao=customerRequestDao;
}
publicabstractCustomerRequestDetailsgetCustomerRequestDetails();
@Override
publicvoidsubmitRequest(StringrequestType,StringrequestDescription){
//--populateCustomerRequestDetailsobjectandsaveit
CustomerRequestDetailscustomerRequestDetails=getCustomerRequestDetails();
.....
}
}
The above example listing shows that the CustomerRequestServiceImpl class is defined as abstract
becauseitcontainsanabstractbeanlookupmethod,getCustomerRequestDetails.Insteadofabstract,we
could have very well defined the getCustomerRequestDetails method as a concrete method. The
submitRequest method invokes the getCustomerRequestDetails method to access a
CustomerRequestDetailsinstance.
The following example listing shows bean definitions for CustomerRequestServiceImpl and
CustomerRequestDetailsclasses:
Examplelisting4-17–applicationContext.xml-<lookup-method>elementusage
Project–ch04-bankapp-lookup-method
Sourcelocation-src/main/resources/META-INF/spring
<beanid="customerRequestService"
class="sample.spring.chapter04.bankapp.service.CustomerRequestServiceImpl">
<constructor-argname="customerRequestDao"ref="customerRequestDao"/>
<lookup-methodbean="customerRequestDetails"name="getCustomerRequestDetails"/>
</bean>
<beanid="customerRequestDetails"
class="sample.spring.chapter04.bankapp.domain.CustomerRequestDetails"
scope="prototype"/>
The above example listing shows that the bean definition for the CustomerRequestServiceImpl class
contains a <lookup-method> element. The value of <lookup-method> elements name attribute is
getCustomerRequestDetails, which instructs the Spring container to provide implementation for the
getCustomerRequestDetailslookupmethod(referexamplelisting4-16)ofCustomerRequestServiceImpl
class.Thevalueof<lookup-method> elements beanattributeiscustomerRequestDetails, which means
that the implementation of getCustomerRequestDetails method retrieves a bean with id (or name) as
customerRequestDetails from the Spring container and returns it to the calling method. As the
customerRequestDetails bean represents a CustomerRequestDetails object (refer to the
customerRequestDetails bean definition in example listing 4-17), the implementation of
getCustomerRequestDetailsmethodreturnsaCustomerRequestDetailsobject.
In example listing 4-16, the CustomerRequestServices submitRequest method invokes the
getCustomerRequestDetails bean lookup method to obtain a CustomerRequestDetails instance. As
CustomerRequestDetailsclassisrepresentedasaprototype-scopedbeanintheapplicationcontextXML
file (refer example listing4-17), each invocation of thesubmitRequest methodresultsin retrieval ofa
newinstanceofCustomerRequestDetailsobjectfromtheSpringcontainer.
To check that the <lookup-method> element provides correct implementation for the
CustomerRequestServices getCustomerRequestDetails bean lookup method, the main method of
BankAppclassobtainsaninstanceofCustomerRequestServicefromtheSpringcontainerandinvokesits
submitRequestmethodmultipletimes.IfeachinvocationofthesubmitRequestmethodresultsinretrieval
of a fresh instance of CustomerRequestDetails object from the Spring container, then it means that the
<lookup-method> element provides correct implementation for the CustomerRequestService’s
getCustomerRequestDetailsmethod.
ThefollowingexamplelistingshowstheBankApp’smainmethodthatinvokesCustomerRequestServices
submitRequestmethodmultipletimes:
Examplelisting4-18–BankAppclass
Project–ch04-bankapp-lookup-method
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp
packagesample.spring.chapter04.bankapp;
.....
publicclassBankApp{
privatestaticLoggerlogger=Logger.getLogger(BankApp.class);
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
.....
logger.info("BeginningwithaccessingCustomerRequestService");
CustomerRequestServicecustomerRequestService_1=context
.getBean(CustomerRequestService.class);
customerRequestService_1.submitRequest("checkBookRequest",
"Requesttosenda50-leafcheckbook");
customerRequestService_1.submitRequest("checkBookRequest",
"Requesttosenda100-leafcheckbook");
.....
logger.info("DonewithaccessingCustomerRequestService");
}
}
IfyouexecutetheBankApp’smainmethod,you’llseethefollowingoutputontheconsole:
BeginningwithaccessingCustomerRequestService
CreatedCustomerRequestDetailsinstance
CreatedCustomerRequestDetailsinstance
.....
DonewithaccessingCustomerRequestService
TheCreated.....’messagesshownintheaboveoutputareprintedbytheconstructorsoftherespective
beanclasses.TheaboveoutputshowsthateachinvocationofCustomerRequestServicessubmitRequest
methodresultedinretrievalofanewCustomerRequestDetailsinstancefromtheSpringcontainer.
AstheimplementationofthebeanlookupmethodisprovidedbytheSpringcontainer,somerestrictions
applytothesignatureofthebeanlookupmethods.Forinstance,thebeanlookupmethodmustbedefined
aspublicorprotected,anditmustnotacceptanyarguments.Asthebeanclasscontainingthebeanlookup
methodissubclassedatruntimebytheSpringcontainertoprovidetheimplementationforthebeanlookup
method,thebeanclassandthebeanlookupmethodmustnotbedefinedasfinal.
NOTE As the bean class containing the bean lookup method needs to be subclassed at runtime by the
Springcontainertoprovideimplementationforthebeanlookupmethod,theSpringcontainerusesCGLIB
(http://cglib.sourceforge.net/)librarytoperformsubclassingofthebeanclass.StartingwithSpring3.2,
the CGLIB classes are packaged within the spring-core JAR file itself; therefore, you dont need to
explicitlyspecifythatyourprojectisdependentonCGLIBJARfile.
The<lookup-method> element provides a method injection technique in which a bean class defines a
beanlookupmethodwhoseimplementationisprovidedbytheSpringcontainer.Insteadofusing<lookup-
method> element, you can consider using <replaced-method> element of Springs beans schema to
performmethodinjection.
IMPORTchapter4/ch04-bankapp-replaced-method(ThisprojectshowstheMyBankapplicationthat
uses <replaced-method> element of Springs beans schema. To run the application, execute the main
methodoftheBankAppclassofthisproject)
<replaced-method>element
The<replaced-method>elementallowsyoutoreplaceanyarbitrarymethodinabeanclass
with a different implementation. The following example listing shows the
CustomerRequestServiceImpl class that we’ll be using as an example to demonstrate use of
<replaced-method>element:
Examplelisting4-19–CustomerRequestServiceImplclass
Project–ch04-bankapp-replaced-method
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
.....
publicclassCustomerRequestServiceImplimplementsCustomerRequestService{
privateCustomerRequestDaocustomerRequestDao;
.....
publicObjectgetMyBean(StringbeanName){
returnnull;
}
@Override
publicvoidsubmitRequest(StringrequestType,StringrequestDescription){
//--populateCustomerRequestDetailsobjectandsaveit
CustomerRequestDetailscustomerRequestDetails=
(CustomerRequestDetails)getMyBean("customerRequestDetails");
customerRequestDetails.setType(requestType);
customerRequestDetails.setDescription(requestDescription);
customerRequestDao.submitRequest(customerRequestDetails);
}
}
The above example listing shows that the CustomerRequestServiceImpl class defines a getMyBean
method.ThegetMyBeanmethodacceptsnameofabeanasanargument,andinsteadofreturningthebean
instance corresponding to the bean name argument, the getMyBean method returns null. The
submitRequestmethodpassescustomerRequestDetailsstringasargumenttothegetMyBeanmethodand
assumes that the getMyBean method returns an instance of customerRequestDetails bean. Using
<replaced-method>element,youcanoverridethegetMyBeanmethodwithamethodthatreturnsthebean
instancecorrespondingtothebeannameargument.
The <replaced-method> element needs information about the overridden method (which is
CustomerRequestServiceImpl getMyBean method in our example scenario) and theoverriding method.
TheoverridingmethodisprovidedbytheclassthatimplementsSpringsMethodReplacerinterface.The
following example listing shows MyMethodReplacer class that implements the MethodReplacer
interface:
Examplelisting4-20–MyMethodReplacerclass
Project–ch04-bankapp-replaced-method
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
importorg.springframework.beans.factory.support.MethodReplacer;
importorg.springframework.context.ApplicationContextAware;
publicclassMyMethodReplacerimplementsMethodReplacer,ApplicationContextAware{
privateApplicationContextapplicationContext;
@Override
publicObjectreimplement(Objectobj,Methodmethod,Object[]args)throwsThrowable{
returnapplicationContext.getBean((String)args[0]);
}
@Override
publicvoidsetApplicationContext(ApplicationContextapplicationContext)
throwsBeansException{
this.applicationContext=applicationContext;
}
}
SpringsMethodReplacerinterfacedefinesareimplementmethodwhoseimplementationisprovidedby
the MyMethodReplacer class. The reimplement method represents the overriding method.
MyMethodReplacer class also implements Springs ApplicationContextAware interface so that the
reimplement method can access the ApplicationContext instance. The reimplement method uses the
ApplicationContextsgetBeanmethodtoretrievebeansfromtheSpringcontainer.
Thereimplementmethodacceptsthefollowingarguments:
·Objectobj–identifiestheobjectwhosemethodweareoverriding.Inourexamplescenario,the
objobjectistheCustomerRequestServiceImplobject.
·        Methodmethod – identifies the bean class’s method that is overridden by the reimplement
method.Inourexamplescenario,thisisCustomerRequestServiceImplsgetMyBeanmethod.
·Object[]args–identifiesargumentspassedtothemethodthatweareoverriding.Inourexample
scenario,args represents the arguments passed to the CustomerRequestServiceImpls getMyBean
method.Inexamplelisting4-20,args[0]inthereimplementmethodrefersthebeannameargument
passedtotheCustomerRequestServiceImplsgetMyBeanmethod.
IfyounowlookatMyMethodReplacersreimplementmethodinexamplelisting4-20,youcaninferthatit
usesargs argument to first obtain bean name passed to the CustomerRequestServiceImpls getMyBean
method,andthencallsApplicationContext’sgetBeanmethodtoobtainthecorrespondingbeaninstance.
As MyMethodReplacers reimplement method overrides CustomerRequestServiceImpls getMyBean
method,calltogetMyBeanmethod at runtime returns thebeaninstance whose name was passed tothe
getMyBeanmethod.
The <replaced-method> element informs the Spring container that MyMethodReplacers reimplement
methodoverridesCustomerRequestServiceImplsgetMyBeanmethod,asshowninthefollowingexample
listing:
Examplelisting4-21–applicationContext.xml-<replaced-method>elementusage
Project–ch04-bankapp-replaced-method
Sourcelocation-src/main/resources/META-INF/spring
<beanid="customerRequestService"
class="sample.spring.chapter04.bankapp.service.CustomerRequestServiceImpl">
<constructor-argname="customerRequestDao"ref="customerRequestDao"/>
<replaced-methodname="getMyBean"replacer="methodReplacer"/>
</bean>
<beanid="methodReplacer"
class="sample.spring.chapter04.bankapp.service.MyMethodReplacer"/>
The above example listing shows bean definitions for MyMethodReplacer and
CustomerRequestServiceImplclasses.The<replace-method>elementsnameattributespecifiesnameof
the method that you want to override, and the replacer attribute specifies reference to the bean that
implementstheMethodReplacerinterface.Themethodspecifiedbythenameattributeisoverriddenby
thereimplementmethodofthebeanreferencedbythereplacerattribute.
As in case of <lookup-method> element, the main method of the BankApp class of ch04-bankapp-
replaced-methodproject validates whether or not the <replaced-method> element overrides the
CustomerRequestServices getMyBean method with the MyMethodReplacers reimplement method.
BankAppclassofch04-bankapp-replaced-methodprojectissameastheonewesawinexamplelisting
4-18 for ch04-bankapp-lookup-methodproject. If you execute the main method of the BankApp class,
you’llfindthat<replaced-method>elementoverridesCustomerRequestServiceImplsgetMyBeanmethod
withMyMethodReplacersreimplement method; therefore, a fresh instance of CustomerRequestDetails
instanceisretrievedfromtheSpringcontainereachtimeCustomerRequestServiceImplssubmitRequest
method(referexamplelisting4-19)isinvoked.
It is important to note that you can use <replaced-method> element to replace an abstract or concrete
method of a bean class with a different method implementation. For instance, we could have defined
getMyBeanmethodasanabstractmethodandusedthe<replaced-method>elementinthesamewayas
describedinthissection.
NOTEAsthebeanclassneedstobesubclassedatruntimebytheSpringcontainertoreplaceabean
methodwithadifferentmethod,theSpringcontainerusesCGLIB(http://cglib.sourceforge.net/)libraryto
performsubclassingofthebeanclass.StartingwithSpring3.2,theCGLIBclassesarepackagedwithin
thespring-coreJARfileitself;therefore,youdon’tneedtoexplicitlyspecifythatyourprojectis
dependentonCGLIBJARfile.
Letsnowlookathow<replaced-method>elementuniquelyidentifiesthebeanmethodtobeoverridden.
Uniquelyidentifyingthebeanmethod
You may come across scenarios in which the bean method that you want to replace using <replaced-
method>elementcan’tbeuniquelyidentifiedbyname.Forinstance,thefollowingexamplelistingshows
abeanclassthatcontainsoverloadedperformmethods:
Examplelisting4-22–Overloadedmethodsinabeanclass
publicclassMyBean{
publicvoidperform(Stringtask1,Stringtask2){.....}
publicvoidperform(Stringtask){.....}
publicvoidperform(my.Tasktask){.....}
}
In theabove examplelisting, theMyBean class contains multiplemethods named perform. To uniquely
identifythebeanmethodtobeoverridden,the<replaced-method>elementuses<arg-type>sub-elements
to specify method argument types. For instance, the following example listing shows how <replaced-
method>elementspecifiesthattheperform(String,String)methodofMyBeanclassshouldbereplaced:
Examplelisting4-23–<replaced-method>elementwith<arg-type>sub-element
<beanid="mybean"class="MyBean">
<replaced-methodname="perform"replacer=".....">
<arg-type>java.lang.String</arg-type>
<arg-type>java.lang.String</arg-type>
</replaced-method>
</bean>
Insteadofusingthefully-qualifiednameasthevalueof<arg-type>element,youcanuseasubstringofthe
fully-qualifiednameasthevalue.Forinstance,insteadofusingjava.lang.String,youcanspecifyStror
Stringasthevalueof<arg-type>elementintheaboveexamplelisting.
LetsnowlookatSpringsautowiringfeaturethatsavesyoutheeffortofspecifyingbeandependenciesin
theapplicationcontextXMLfile.
4-6Autowiringdependencies
In Spring, you have the option to either explicitly specify bean dependencies using <property> and
<constructor-arg>elementsorletSpringautomaticallyresolvebeandependencies.Theprocessinwhich
dependenciesareautomaticallyresolvedbySpringisreferredtoas‘autowiring.
IMPORTchapter4/ch04-bankapp-autowiring(This project shows the MyBank application that uses
Springsautowiringfeaturefordependencyinjection.Toruntheapplication,executethemainmethodof
theBankAppclassofthisproject)
The<bean>element’sautowireattributespecifieshowabeansdependenciesareautomaticallyresolved
by Spring. The autowire attribute can take any one of the following values: default, byName, byType,
constructorandno.Let’snowlookateachoftheseattributevaluesindetail.
NOTEYoushouldnotethatthe<bean>element’sautowireattributeisnotinheritedbychildbean
definitions.
byType
Ifyouspecifyautowireattribute’svalueasbyType,Springautowiresbeanpropertiesbasedontheirtype.
For instance, if a bean A defines a property of type X, Spring finds a bean of type X in the
ApplicationContextandinjectsitintobeanA.LetslookatanexampleusageofbyTypeautowiringinthe
MyBankapplication.
ThefollowingexamplelistingshowstheMyBankapplicationsCustomerRegistrationServiceImplclass:
Examplelisting4-24–CustomerRegistrationServiceImplclass
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
publicclassCustomerRegistrationServiceImplimplementsCustomerRegistrationService{
privateCustomerRegistrationDetailscustomerRegistrationDetails;
privateCustomerRegistrationDaocustomerRegistrationDao;
....
publicvoidsetCustomerRegistrationDetails(
CustomerRegistrationDetailscustomerRegistrationDetails){
this.customerRegistrationDetails=customerRegistrationDetails;
}
publicvoidsetCustomerRegistrationDao(
CustomerRegistrationDaocustomerRegistrationDao){
this.customerRegistrationDao=customerRegistrationDao;
}
.....
}
The above example listing shows that the CustomerRegistrationServiceImpl class defines properties
namedcustomerRegistrationDetails(oftypeCustomerRegistrationDetails)andcustomerRegistrationDao
(of type CustomerRegistrationDao). This means that the CustomerRegistrationDetails and
CustomerRegistrationDaoobjectsaredependenciesofCustomerRegistrationServiceImplobject.
The following example listing shows bean definitions for CustomerRegistrationServiceImpl,
CustomerRegistrationDetails and CustomerRegistrationDaoImpl (an implementation of
CustomerRegistrationDaointerface)classes:
Examplelisting4-25–applicationContext.xml-autowiringbyTypeconfiguration
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/resources/META-INF/spring
<beanid="customerRegistrationService"
class="sample.spring.chapter04.bankapp.service.CustomerRegistrationServiceImpl"
scope="prototype"autowire="byType"/>
<beanid="customerRegistrationDetails"
class="sample.spring.chapter04.bankapp.domain.CustomerRegistrationDetails"
scope="prototype"/>
<beanid="customerRegistrationDao"
class="sample.spring.chapter04.bankapp.dao.CustomerRegistrationDaoImpl"/>
Intheaboveexamplelisting,thecustomerRegistrationServicebeandefinitiondoesn’tcontain<property>
elementsforsettingcustomerRegistrationDetailsandcustomerRegistrationDaoproperties(referexample
listing4-24).Instead,the<bean>elementspecifiesautowireattribute’svalueasbyTypetoinstructSpring
to automatically resolve dependencies of the customerRegistrationService bean based on theirtype.
Spring looks for beans of types CustomerRequestDetails and CustomerRegistrationDao in the
ApplicationContext, and injects them into the customerRegistrationService bean. As
customerRegistrationDetails and customerRegistrationDao beans represent beans of types
CustomerRegistrationDetails and CustomerRegistrationDao, the Spring container injects
customerRegistrationDetailsandcustomerRegistrationDaobeansintocustomerRegistrationServicebean.
It may happen that Spring doesnt find any bean registered with the ApplicationContext whose type
matches the property type. In such cases, no exception is thrown and the bean property is not set. For
instance, if a bean defines a property x of type Y, and there is no bean of type Y registered with the
ApplicationContext instance, the property x is not set. If Spring finds multiple beans in the
ApplicationContextthatmatchthepropertytype,anexceptionisthrown.Insuchcases,insteadofusing
autowiringfeature,use<property>elementstoexplicitlyidentifybeandependenciesorsetabeanasthe
primarycandidateforautowiringbysettingthevalueofprimaryattributeof<bean>elementtotrue.
constructor
If you specify autowire attribute’s value as constructor, Spring autowires bean classs constructor
argumentsbasedontheirtype.Forinstance,ifbeanAsconstructoracceptsargumentsoftypeXandY,
SpringfindsbeansoftypesXandYintheApplicationContextandinjectsthemasargumentstobeanA’s
constructor.Let’slookatanexampleusageofconstructorautowiringintheMyBankapplication.
ThefollowingexamplelistingshowstheMyBankapplicationsCustomerRequestServiceImplclass:
Examplelisting4-26–CustomerRequestServiceImplclass
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
publicclassCustomerRequestServiceImplimplementsCustomerRequestService{
privateCustomerRequestDetailscustomerRequestDetails;
privateCustomerRequestDaocustomerRequestDao;
@ConstructorProperties({"customerRequestDetails","customerRequestDao"})
publicCustomerRequestServiceImpl(
CustomerRequestDetailscustomerRequestDetails,
CustomerRequestDaocustomerRequestDao){
this.customerRequestDetails=customerRequestDetails;
this.customerRequestDao=customerRequestDao;
}
.....
}
The CustomerRequestServiceImpl class defines a constructor that accepts arguments of type
CustomerRequestDetailsandCustomerRequestDao.
The following example listing shows bean definitions for CustomerRequestServiceImpl,
CustomerRequestDetails and CustomerRequestDaoImpl (an implementation of CustomerRequestDao
interface)classes:
Examplelisting4-27–applicationContext.xml-constructorautowiring
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/resources/META-INF/spring
<beanid="customerRequestService"
class="sample.spring.chapter04.bankapp.service.CustomerRequestServiceImpl"
autowire="constructor">
</bean>
<beanid="customerRequestDetails"
class="sample.spring.chapter04.bankapp.domain.CustomerRequestDetails"scope="prototype"/>
<beanid="customerRequestDao"
class="sample.spring.chapter04.bankapp.dao.CustomerRequestDaoImpl"/>
In theaboveexamplelisting,thecustomerRequestServicebeandefinitionspecifiesautowire attribute’s
value as constructor, which means that Spring locates beans of types CustomerRequestDetails and
CustomerRequestDao in the ApplicationContext, and passes them as arguments to
CustomerRequestServiceImpl classs constructor. As customerRequestDetails and customerRequestDao
beans are of type CustomerRequestDetails and CustomerRequestDao, Spring automatically injects
instancesofthesebeansintocustomerRequestServicebean.
IfSpringdoesntfindanybeanintheApplicationContextwhosetypematchestheconstructorargument
type, the constructor argument is not set. If Spring finds multiple beans in the ApplicationContext that
match the constructor argument type, an exception is thrown; therefore, in such scenarios use
<constructor-arg> elements to explicitly identify bean dependencies or set a bean as theprimary
candidateforautowiringbysettingvalueofprimaryattributeof<bean>elementtotrue.
byName
If you specify autowire attribute’s value as byName, Spring autowires bean properties based on their
names. For instance, if a bean A defines a property named x, Spring finds a bean named x in the
ApplicationContextandinjectsitintobeanA.Let’slookatanexampleusageofbyNameautowiringinthe
MyBankapplication.
ThefollowingexamplelistingshowstheMyBankapplicationsFixedDepositServiceImplclass:
Examplelisting4-28–FixedDepositServiceImplclass
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
importsample.spring.chapter04.bankapp.dao.FixedDepositDao;
importsample.spring.chapter04.bankapp.domain.FixedDepositDetails;
publicclassFixedDepositServiceImplimplementsFixedDepositService{
privateFixedDepositDaomyFixedDepositDao;
publicvoidsetMyFixedDepositDao(FixedDepositDaomyFixedDepositDao){
this.myFixedDepositDao=myFixedDepositDao;
}
.....
}
The above example listing shows that FixedDepositServiceImpl class defines a property named
myFixedDepositDaooftypeFixedDepositDao.
The following example listing shows bean definitions for FixedDepositServiceImpl and
FixedDepositDaoImpl(animplementationofFixedDepositDaointerface)classes:
Examplelisting4-29–applicationContext.xml-byNameautowiring
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/resources/META-INF/spring
<beanid="FixedDepositService"
class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl"
autowire="byName"/>
<beanid="myFixedDepositDao"
class="sample.spring.chapter04.bankapp.dao.FixedDepositDaoImpl"/>
Intheaboveexamplelisting,FixedDepositServicebeandefinitionspecifiesautowireattribute’svalueas
byName, which means properties of FixedDepositService bean are automatically resolved by Spring
basedontheirnames.Inlisting4-28,wesawthattheFixedDepositServiceImplclassdefinesaproperty
named myFixedDepositDao; therefore, Spring looks for a bean named myFixedDepositDao in the
ApplicationContext and injects it into FixedDepositService bean. In the above example listing,
myFixedDepositDao bean definition represents the FixedDepositDaoImpl class, which means that an
instance of FixedDepositDaoImpl is injected for property named myFixedDepositDao in the
FixedDepositServicebean.
default/no
Ifyouspecifyautowireattribute’svalueasdefaultorno,autowiringfeatureisdisabledforthebean.As
Springs default behavior is to use no autowiring for beans, specifying autowire attribute’s value as
defaultmeansnoautowiringwillbeperformedforthebean.Youcanexplicitlyspecifythatabeanmust
notuseSpringsautowiringfeaturebyspecifyingautowireattribute’svalueasno.
NOTEYoucanchangethedefaultautowiringbehaviorofbeansbysettingthedefault-autowireattribute
of<beans>element.For instance, if you set default-autowire attribute’s value tobyType, it effectively
meanssettingvalueofautowireattributeofallthe<bean>elementsintheapplicationcontextXMLfileto
byType.Youshouldnotethatifa<bean>elementsautowireattributespecifiesadifferentvaluethanthe
<beans>elementsdefault-autowireattribute,the<bean>element’sautowireattributevalueappliestothe
bean.
The following example listing shows the bean definition for the MyBank applications
CustomerRegistrationServiceImplclassthatspecifiesautowireattribute’svalueasno:
Examplelisting4-30–applicationContext.xml-noautowiring
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/resources/META-INF/spring
<beanid="customerRegistrationService_"
class="sample.spring.chapter04.bankapp.service.CustomerRegistrationServiceImpl"
scope="prototype"autowire="no"/>
Example listing 4-24 showed that the CustomerRegistrationServiceImpl class defines
customerRegistrationDetails(oftypeCustomerRegistrationDetails)andcustomerRegistrationDao(oftype
CustomerRegistrationDao) properties. As the autowire attributes value is specified as no for
customerRegistrationService_bean,autowiringisdisabledforcustomerRegistrationService_bean.This
means that the customerRegistrationDetails and customerRegistrationDao properties of
customerRegistrationService_beanarenotsetbySpring.
So far in this section we have seen different ways in which bean dependencies can be autowired by
Spring.Letsnowlookathowwecanmakeabeanunavailableforautowiringpurposesusing<bean>
element’sautowire-candidateattribute.
Makingbeansunavailableforautowiring
ThedefaultbehavioroftheSpringcontaineristomakebeansavailableforautowiring.Youcanmakea
beanunavailabletootherbeansforautowiringpurposesbysettingautowire-candidateattribute’svalueto
false.
In MyBank application, the AccountStatementServiceImpl class defines a property of type
AccountStatementDao.ThefollowingexamplelistingshowstheAccountStatementServiceImplclass:
Examplelisting4-31–AccountStatementServiceImplclass
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/service
packagesample.spring.chapter04.bankapp.service;
importsample.spring.chapter04.bankapp.dao.AccountStatementDao;
importsample.spring.chapter04.bankapp.domain.AccountStatement;
publicclassAccountStatementServiceImplimplementsAccountStatementService{
privateAccountStatementDaoaccountStatementDao;

publicvoidsetAccountStatementDao(AccountStatementDaoaccountStatementDao){
this.accountStatementDao=accountStatementDao;
}
.....
}
The following example listing shows bean definitions for AccountStatementServiceImpl and
AccountStatementDaoImpl(animplementationofAccountStatementDaointerface)classes:
Examplelisting4-32–applicationContext.xml-autowire-candidateattribute
Project–ch04-bankapp-autowiring
Sourcelocation-src/main/resources/META-INF/spring
<beanid="accountStatementService"
class="sample.spring.chapter04.bankapp.service.AccountStatementServiceImpl"
autowire="byType"/>
<beanid="accountStatementDao"
class="sample.spring.chapter04.bankapp.dao.AccountStatementDaoImpl"
autowire-candidate="false"/>
Intheaboveexamplelisting,theaccountStatementServicebeandefinitionspecifiesautowireattribute’s
valueas byType, which means AccountStatementDaopropertytype ofaccountStatementService bean is
autowiredbytype.AsaccountStatementDaobeanisoftypeAccountStatementDao,you mightthink that
Spring will inject accountStatementDao bean instance into accountStatementService bean. But, Spring
won’t consider accountStatementDao bean for autowiring purposes because the accountStatementDao
beandefinitionspecifiesautowire-candidateattribute’svalueasfalse.
NOTEYoushouldnotethatabeanthatisunavailabletootherbeansforautowiringpurposescanitself
makeuseofSpringsautowiringfeaturetoautomaticallyresolveitsdependencies.
As mentioned earlier, the default behavior of the Spring container is to make beans available for
autowiring purposes. To make only only a select set of beans available for autowiring purposes, set
<beans> elements default-autowire-candidates attribute. The default-autowire-candidates attribute
specifies a bean name pattern, and only beans whose names match the specified pattern are made
available for autowiring. The followingexamplelisting shows anexample usageof default-autowire-
candidatesattribute:
Examplelisting4-33–default-autowire-candidatesattributeexample
<beansdefault-autowire-candidates="*Dao">
.....
<beanid="customerRequestDetails"
class="sample.spring.chapter04.bankapp.domain.CustomerRequestDetails"
scope="prototype"autowire-candidate="true"/>
<beanid="customerRequestDao"
class="sample.spring.chapter04.bankapp.dao.CustomerRequestDaoImpl"/>
<beanid="customerRegistrationDao"
class="sample.spring.chapter04.bankapp.dao.CustomerRegistrationDaoImpl"/>
.....
</beans>
Intheaboveexamplelisting,default-autowire-candidatesvalueissetto*Dao,whichmeansthatbeans
whose names end with Dao (like customerRequestDao and customerRegistrationDao beans) will be
available for autowiring purposes. If a bean name doesnt match the pattern specified by the default-
autowire-candidates attribute (like customerRequestDetails bean), you can still make it available for
autowiringpurposesbysettingtheautowire-candidateattributeofthecorresponding<bean>elementto
true.
Letsnowlookatlimitationsofusingautowiringinapplications.
Autowiringlimitations
Wesawthatautowiringfeaturesavestheefforttoexplicitlyspecifybeandependenciesusing<property>
and<constructor-arg>elements.Thedownsidesofusingautowiringfeatureare:
·Youcan’tuseautowiringtosetpropertiesorconstructorargumentsthatareofsimpleJavatypes
(likeint,long,boolean,String,Date, and so on). You canautowire arrays, typed collections and
mapsiftheautowireattribute’svalueissettobyTypeorconstructor.
·        As bean dependencies are automatically resolved by Spring, it results in hiding the overall
structureoftheapplication.Ifyouuse<property>and<constructor-arg>elementstospecifybean
dependencies,itresultsinexplicitlydocumentingtheoverallstructureoftheapplication.Youcan
easily understand and maintain an application in which bean dependencies are explicitly
documented.Forthisreason,itisnotrecommendedtouseautowiringinlargeapplications.
4-7Summary
Inthischapter,welookedathowSpringcaterstodifferentdependencyinjectionscenarios.Welookedat
how you can use ApplicationContextAware interface, <replaced-method> and <lookup-method> sub-
elementsof<bean> element toprogrammaticallyretrieve abean instance from the ApplicationContext.
We also looked at how Spring’s autowiring feature can save the effort for explicitly specifying bean
dependencies in the application context XML file. In the next chapter, we’ll look at how to customize
beansandbeandefinitions.
Chapter5-Customizingbeansandbeandefinitions
5-1Introduction
SofarinthisbookwehaveseenexamplesinwhichtheSpringcontainercreatedabeaninstancebasedon
thebeandefinitionspecifiedintheapplicationcontextXMLfile.Inthischapter,we’llgoastepfurther
andlookat:
·howtoincorporatecustominitializationanddestructionlogicforabean
·howtointeractwithanewlycreatedbeaninstancebyimplementingSpringsBeanPostProcessor
interface
·howtomodifybeandefinitionsbyimplementingSpringsBeanFactoryPostProcessorinterface
5-2Customizingbean’sinitializationanddestructionlogic
We saw in earlier chapters that the Spring container is responsible for creating a bean instance and
injectingitsdependencies.Aftercreatingabeaninstancebyinvokingtheconstructorofthebeanclass,the
Springcontainersetsbeanpropertiesbyinvokingbeanssettermethods.Ifyouwanttoexecutecustom
initialization logic (like opening a file, creating a database connection, and so on)after the bean
propertiesaresetbutbeforethebeaniscompletelyinitializedbytheSpringcontainer,youcandosoby
specifyingthenameoftheinitializationmethodasthevalueofinit-methodattributeof<bean>element.
Similarly,ifyou wantto executecustomcleanuplogic before the Spring container containingthe bean
instance is destroyed, you can specify the name of the cleanup method as the value of destroy-
methodattributeof<bean>element.
IMPORT chapter 5/ch05-bankapp-customization (This project shows the MyBank application that
uses <bean> element’s init-method and destroy-method elements to specify custom initialization and
destructionmethods.Totestwhethertheinitializationmethodisexecuted,executethemainmethodofthe
BankApp class of this project. To test whether the destruction method is executed, execute the main
methodoftheBankAppWithHookclassofthisproject.)
The following example listing shows the MyBanks FixedDepositDaoImpl class that defines an
initializationmethodnamedinitializeDbConnectionforobtainingconnectiontoMyBanksdatabase,anda
destructionmethodnamedreleaseDbConnectionforreleasingtheconnection:
Examplelisting5-1–FixedDepositDaoImplclass-Custominitializationanddestructionlogic
Project–ch05-bankapp-customization
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/dao
packagesample.spring.chapter05.bankapp.dao;
publicclassFixedDepositDaoImplimplementsFixedDepositDao{
privatestaticLoggerlogger=Logger.getLogger(FixedDepositDaoImpl.class);
privateDatabaseConnectionconnection;
publicFixedDepositDaoImpl(){
logger.info("FixedDepositDaoImpl'sconstructorinvoked");
}
publicvoidinitializeDbConnection(){
logger.info("FixedDepositDaoImpl’sinitializeDbConnectionmethodinvoked");
connection=DatabaseConnection.getInstance();
}
publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){
logger.info("FixedDepositDaoImpl’screateFixedDepositmethodinvoked");
//--savethefixeddepositsandthenreturntrue
returntrue;
}
publicvoidreleaseDbConnection(){
logger.info("FixedDepositDaoImpl’sreleaseDbConnectionmethodinvoked");
connection.releaseConnection();
}
}
In the above example listing, the DatabaseConnection object is used for interacting with the MyBanks
database. FixedDepositDaoImpl class defines an initializeDbConnection method that initializes the
DatabaseConnection object, which is later used by the createFixedDeposit method for saving fixed
depositdetailsintheMyBanksdatabase.
The following example listing shows the MyBank’s FixedDepositServiceImpl class that uses
FixedDepositDaoImplinstancetocreatenewfixeddeposits:
Examplelisting5-2–FixedDepositServiceImplclass
Project–ch05-bankapp-customization
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/service
packagesample.spring.chapter05.bankapp.service;
publicclassFixedDepositServiceImplimplementsFixedDepositService{
privatestaticLoggerlogger=Logger.getLogger(FixedDepositServiceImpl.class);
privateFixedDepositDaomyFixedDepositDao;
publicvoidsetMyFixedDepositDao(FixedDepositDaomyFixedDepositDao){
logger.info("FixedDepositServiceImpl'ssetMyFixedDepositDaomethodinvoked");
this.myFixedDepositDao=myFixedDepositDao;
}
@Override
publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{
//--createfixeddeposit
myFixedDepositDao.createFixedDeposit(fixedDepositDetails);
}
}
The above example listing shows that the FixedDepositDaoImpl instance is a dependency of
FixedDepositServiceImpl, and is passed as an argument to the setMyFixedDepositDao setter-method.
And, if FixedDepositServiceImpls createFixedDeposit method is invoked, it results in invocation of
FixedDepositDaoImplscreateFixedDepositmethod.
The following example listing shows bean definitions for FixedDepositDaoImpl and
FixedDepositServiceImplclasses:
Examplelisting5-3–applicationContext.xml–usageofinit-methodanddestroy-methodattributes
Project–ch05-bankapp-customization
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
<beanid="FixedDepositService"
class="sample.spring.chapter05.bankapp.service.FixedDepositServiceImpl">
<propertyname="myFixedDepositDao"ref="myFixedDepositDao"/>
</bean>
<beanid="myFixedDepositDao"
class="sample.spring.chapter05.bankapp.dao.FixedDepositDaoImpl"
init-method="initializeDbConnection"destroy-method="releaseDbConnection"/>
</beans>
The above example listing shows that the <bean> element corresponding to the FixedDepositDaoImpl
class specifies initializeDbConnection and releaseDbConnection as the values of init-method and
destroy-methodattributes,respectively.
NOTEItisimportanttonotethattheinitializationanddestructionmethodsspecifiedbytheinit-method
anddestroy-methodattributesof<bean>elementmustnotacceptanyarguments,butcanbedefinedto
throwexceptions.
The following example listing shows BankApp class whose main method retrieves
FixedDepositServiceImplinstancefromtheApplicationContextandinvokesFixedDepositServiceImpls
createFixedDepositmethod:
Examplelisting5-4–BankAppclass
Project–ch05-bankapp-customization
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp
packagesample.spring.chapter05.bankapp;
publicclassBankApp{
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,
12,"someemail@somedomain.com"));
}
}
IfyounowexecutetheBankApp’smainmethod,youllseethefollowingoutputontheconsole:
FixedDepositDaoImpl'sconstructorinvoked
FixedDepositDaoImplsinitializeDbConnectionmethodinvoked
FixedDepositServiceImpl'ssetMyFixedDepositDaomethodinvoked
FixedDepositDaoImplscreateFixedDepositmethodinvoked
TheaboveoutputshowsthattheSpringcontainerfirstcreatesFixedDepositDaoImplsinstance,andthen
invokes initializeDbConnection method. After the invocation of initializeDbConnection method, the
FixedDepositDaoImplinstanceisinjectedintotheFixedDepositServiceImplinstance.Thisshowsthatthe
Springcontainerinjectsadependency(theFixedDepositDaoImplinstance)intothedependentbean(the
FixedDepositServiceImpl instance)after the initialization method of the dependency is invoked by the
Springcontainer.
YoumayhavenoticedthattheoutputfromexecutingBankApp’smainmethoddidn’tcontainthefollowing
message:FixedDepositDaoImpl’sreleaseDbConnectionmethodinvoked(referFixedDepositDaoImpls
releaseDbConnection method in example listing 5-1). This means that the FixedDepositDaoImpls
releaseDbConnection method was not called by the Spring container when BankApp’s main method
exited.Inarealworldapplicationdevelopmentscenario,thismeansthatthedatabaseconnectionheldby
FixedDepositDaoImpl instance is never released. Let’s now see how you can make Spring gracefully
destroysingleton-scopedbeaninstancesbycallingthecleanupmethodspecifiedbythe<bean>element’s
destroy-methodattribute.
MakingSpringinvokecleanupmethodspecifiedbythedestory-methodattribute
The web version of ApplicationContext implementation is represented by Springs
WebApplicationContextobject.WebApplicationContextimplementationhasthenecessarylogictoinvoke
thecleanupmethod(specifiedbythedestroy-methodattribute)ofsingleton-scopedbeaninstancesbefore
thewebapplicationisshutdown.
NOTETheapproachdescribedinthissectiononmakingSpringgracefullydestroysingleton-scopedbean
instancesbycallingthecleanupmethodisspecifictostandaloneapplications.
ThefollowingexamplelistingshowstheBankAppWithHookclass(amodifiedversionofBankAppclass
shown in example listing 5-4) whose main method ensures that cleanup methods (specified by <bean>
element’sdestroy-methodattribute)ofallsingleton-scopedbeansregisteredwiththeSpringcontainerare
invokedwhenthemainmethodexits:
Examplelisting5-5–BankAppWithHookclass–registeringashutdownhookwithJVM
Project–ch05-bankapp-customization
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp
packagesample.spring.chapter05.bankapp;
publicclassBankAppWithHook{
publicstaticvoidmain(Stringargs[])throwsException{
AbstractApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
context.registerShutdownHook();
FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,
12,"someemail@somedomain.com"));
}
}
Springs AbstractionApplicationContext class implements ApplicationContext interface and defines a
registerShutdownHook method that registers a shutdown hook with the JVM. The shutdown hook is
responsibleforclosingtheApplicationContextwhentheJVMisshutdown.Intheaboveexamplelisting,
you’ll notice that the ClassPathXmlApplicationContext instance is assigned to
AbstractionApplicationContext type, and the AbstractionApplicationContext’s registerShutdownHook is
calledtoregisterashutdownhookwiththeJVM.WhentheBankAppWithHooksmainmethodexists,the
shutdownhookdestroysallcachedsingletonbeaninstancesandclosestheApplicationContextinstance.
IfyouexecuteBankAppWithHooksmainmethodofch05-bankapp-customizationproject,youllseethe
followingoutputontheconsole:
FixedDepositDaoImpl'sconstructorinvoked
FixedDepositDaoImplsinitializeDbConnectionmethodinvoked
FixedDepositServiceImpl'ssetMyFixedDepositDaomethodinvoked
FixedDepositDaoImpl'sreleaseDbConnectionmethodinvoked
ThemessageFixedDepositDaoImpl'sreleaseDbConnectionmethod invoked’ on theconsoleconfirms
that the FixedDepositDaoImpls releaseDbConnection method (refer FixedDepositDaoImpls
releaseDbConnection method in example listing 5-1) was invoked. As you can see, registering a
shutdown hook with the JVM resulted in invocation of the cleanup method of the singleton-scoped
myFixedDepositDaobean(correspondingtotheFixedDepositDaoImplclass).
Letsnowlookattheimpactofshutdownhookonprototype-scopedbeans.
Cleanupmethodsandprototype-scopedbeans
In case of prototype-scoped beans, destroy-method attribute is ignored by the Spring container. The
destroy-methodattributeisignoredbecausetheSpring containerexpectsthattheobjectthatfetches the
prototype-scoped bean instance from the ApplicationContext is responsible for explicitly calling the
cleanupmethodontheprototype-scopedbeaninstance.
NOTELifecyclesofprototype-andsingleton-scopedbeansaresame,exceptthattheSpringcontainer
willnotcallthecleanupmethod(specifiedbythedestroy-initattribute)oftheprototype-scopedbean
instance.
Lets now look at how you can specify default initialization and destruction methods for all the beans
containedintheapplicationcontextXMLfile.
Specifyingdefaultbeaninitializationanddestructionmethodsforallbeans
Youcanusethedefault-init-methodanddefault-destroy-methodattributesof<beans>elementtospecify
defaultinitializationanddestructionmethodsforbeans,asshowninthefollowingexamplelisting:
Examplelisting5-6–default-init-methodanddefault-destroy-methodattributes
<beans.....default-init-method="initialize"default-destroy-method="release">
<beanid="A"class="....."init-method="initializeService"/>
<beanid="B"class="....."/>
</beans>
If multiple beans define initialization or cleanup methods with the same name, it makes sense to use
default-init-methodanddefault-destroy-methodattributes.Byspecifyinginit-methodanddestroy-method
attributes,a<bean>elementcanoverridethevaluesspecifiedby<beans>element’sdefault-init-method
anddefault-destroy-methodattributes.Forinstance,intheaboveexamplelisting,beanAspecifiesinit-
method attribute value as initializeService, which means initializeService method (and not initialize
methodspecifiedbythedefault-init-methodattributeof<beans>element)istheinitializationmethodof
beanA.
Instead of using init-method and destroy-method attributes of <bean> element to specify custom
initialization and destruction methods, you can use Springs InitializingBean and DisposableBean
lifecycleinterfaces.
InitializingBeanandDisposableBeanlifecycleinterfaces
Abeanthatimplementslifecycleinterfaces,likeApplicationContextAware(refersection4-5ofchapter
4),InitializingBeanandDisposableBean,receivescallbacksfromtheSpringcontainertogiveachanceto
the bean instance to perform some action, or to provide bean instance with some information. For
instance, if a bean implements ApplicationContextAware interface, container invokes
setApplicationContext method of the bean instance to provide the bean with a reference to the
ApplicationContextinwhichthebeanisdeployed.
InitializingBeaninterface defines an afterPropertiesSet method that is invoked by the Spring container
afterthebeanpropertiesareset.BeansperforminitializationworkintheafterPropertiesSetmethod,like
obtainingconnectiontoadatabase,openingaflatfileforreading,andsoon.DisposableBeaninterface
definesadestroymethodthatisinvokedbytheSpringcontainerwhenthebeaninstanceisdestroyed.
NOTE As with the ApplicationContextAware lifecycle interface, beans should avoid implementing
InitializingBeanandDisposableBeaninterfacesbecauseitcouplesapplicationcodewithSpring.
Lets now look at JSR 250’s @PostConstruct and @PreDestroy annotations for specifying bean
initializationanddestructionmethods.
JSR250s@PostConstructand@PreDestroyannotations
JSR250(CommonAnnotationsfortheJavaPlatform)definesstandardannotationsthatareusedacross
different Java technologies. JSR 250’s @PostConstruct and @PreDestroy annotations identify
initialization and destruction methods of an object. A bean class in Spring can set a method as an
initializationmethodbyannotatingitwith@PostConstruct,andsetamethodasadestructionmethodby
annotatingitwith@PreDestroyannotation.
NOTEReferJSR250homepage(http://jcp.org/en/jsr/detail?id=250)formoredetails.
IMPORTchapter5/ch05-bankapp-jsr250(This project shows the MyBank application that uses JSR
250’s @PostConstruct and @PreDestroy annotations to identify custom initialization and destruction
methods,respectively.Totestwhethertheinitializationmethodisexecuted,executethemainmethodof
theBankAppclassofthisproject.Totestwhetherthedestructionmethodisexecuted,executethemain
methodoftheBankAppWithHookclassofthisproject.)
ThefollowingexamplelistingshowstheFixedDepositDaoImplclassofch05-bankapp-jsr250projectthat
uses@PostConstructand@PreDestroyannotations:
Examplelisting5-7–FixedDepositDaoImplclass-@PostConstructand@PreDestroyannotations
Project–ch05-bankapp-jsr250
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/dao
packagesample.spring.chapter05.bankapp.dao;
importjavax.annotation.PostConstruct;
importjavax.annotation.PreDestroy;
publicclassFixedDepositDaoImplimplementsFixedDepositDao{
privateDatabaseConnectionconnection;
.....
@PostConstruct
publicvoidinitializeDbConnection(){
logger.info("FixedDepositDaoImplísinitializeDbConnectionmethodinvoked");
connection=DatabaseConnection.getInstance();
}
.....
@PreDestroy
publicvoidreleaseDbConnection(){
logger.info("FixedDepositDaoImpl'sreleaseDbConnectionmethodinvoked");
connection.releaseConnection();
}
}
In the above example listing, the FixedDepositDaoImpl class uses @PostConstruct and @PreDestroy
annotations toidentify initializationanddestructionmethods.You should note that @PostConstruct and
@PreDestroyannotationsarenotspecifictoSpring.
NOTEJavaSE6providesannotationsdefinedbyJSR250;ifyouareusingJavaSE6orlater,youdont
needtoincludeJSR250JARfileinyourapplicationsclasspath.IfyouareusingJavaSE5,youneedto
includeJSR250JARfileandtherelatedJARfilesinyourapplicationsclasspath.
Touse@PostConstructand@PreDestroyannotationsinyourapplication,youneedtoconfigureSprings
CommonAnnotationBeanPostProcessorclassintheapplicationcontextXMLfile,asshownhere:
Examplelisting5-8–applicationContext.xml–CommonAnnotationBeanPostProcessorconfiguration
Project–ch05-bankapp-jsr250
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
<beanid="FixedDepositService"
class="sample.spring.chapter05.bankapp.service.FixedDepositServiceImpl">
<propertyname="myFixedDepositDao"ref="myFixedDepositDao"/>
</bean>
<beanid="myFixedDepositDao"
class="sample.spring.chapter05.bankapp.dao.FixedDepositDaoImpl"/>
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
</beans>
CommonAnnotationBeanPostProcessor implements Springs BeanPostProcessor interface (explained in
thenextsection),andisresponsibleforprocessingJSR250annotations.
If you execute the main method of BankApp and BankAppWithHook classes, you’ll notice that the
@PostConstruct and @PreDestroy annotated methods of FixedDepositDaoImpl class are executed at
creationanddestructionofFixedDepositDaoImplinstance,respectively.
We’llnowlookatSpringsBeanPostProcessorinterfacethatallowsyoutointeractwithnewlycreated
beaninstancesbeforeoraftertheyareinitializedbytheSpringcontainer.
5-3 Interacting with newly created bean instances using
BeanPostProcessor
BeanPostProcessor is used to interact with newly created bean instancesbefore and/orafter their
initialization method (refer section 5-2) is invoked by the Spring container. You can use
BeanPostProcessortoexecutecustomlogicbeforeand/orafterbeansinitializationmethodisinvokedby
theSpringcontainer.
NOTEAbeanthatimplementsSpringsBeanPostProcessorinterfaceisaspecialbeantype;
theSpringcontainerautomaticallydetectsandexecutesaBeanPostProcessorbean.
BeanPostProcessorinterfacedefinesthefollowingmethods:
·        ObjectpostProcessBeforeInitialization(Object bean, String beanName) – this method is
invokedbeforetheinitializationmethodofabeaninstanceisinvoked
·        Object postProcessAfterInitialization(Object bean, String beanName) – this method is
invokedaftertheinitializationmethodofabeaninstanceisinvoked
BeanPostProcessorsmethodsacceptnewlycreatedbeaninstanceanditsnameasarguments,andreturn
thesameormodifiedbeaninstance.Forinstance,ifyouhaveconfiguredaFixedDepositDaoImplclassas
abeanwithidvalueasmyFixedDepositDaointheapplicationcontextXMLfile(referexamplelisting5-
8), the BeanPostProcessors methods receive an instance of FixedDepositDaoImpl class and
myFixedDepositDaostringvalueasarguments.TheBeanPostProcessorsmethodsmayreturntheoriginal
bean instance as-is or they may modify the bean instance or they may return an object that wraps the
originalbeaninstance.
You configure a BeanPostProcessor implementation in the application context XML file like any other
Spring bean. Spring containerautomaticallydetects beans thatimplement BeanPostProcessor interface,
and createstheir instance before creating instance of any other bean defined in the application context
XML file. Once the BeanPostProcessor beans are created, the Spring container invokes each
BeanPostProcessorspostProcessBeforeInitializationandpostProcessAfterInitializationmethodsforeach
beaninstancecreatedbytheSpringcontainer.
Lets say that you have defined a singleton-scoped bean ABean and a BeanPostProcessor bean,
MyBeanPostProcessor, in theapplication context XML file. Figure 5-1 shows a sequence diagram that
depictsthesequenceinwhichMyBeanPostProcessorsmethodsareinvokedbytheSpringcontainer.
Theinitmethodcallinthesequencediagramrepresentsacalltotheinitializationmethodofthebean.The
sequence diagram shows that the MyBeanPostProcessor instance is created before the ABean bean
instance is created. As a BeanPostProcessor implementation is configured like any other bean, if
MyBeanPostProcessordefinesaninitializationmethod,containerinvokestheinitializationmethodofthe
MyBeanPostProcessorinstance.AfterABeansinstanceiscreated,settermethodsoftheABeaninstance
areinvokedbytheSpringcontainertosatisfyitsdependencies,andtoprovidethebeaninstancewiththe
requiredconfigurationinformation.Afterpropertiesareset,butbeforeABeansinitializationmethodis
invoked, the Spring container invokes MyBeanPostProcessors postProcessBeforeInitialization method.
After ABeans initialization method is invoked, MyBeanPostProcessors postProcessAfterInitialization
methodiscalledbytheSpringcontainer.
Figure 5-1 – The Spring container invokes MyBeanPostProcessors methodsbefore and after the
initializationofABeansinitializationmethod
Its only after invocation of postProcessAfterInitialization method, a bean instance is considered
completely initialized by the Spring container. For instance, if a BBean bean is dependent on ABean,
container will inject ABean instance into BBean only after MyBeanPostProcessors
postProcessAfterInitializationisinvokedforbothABeanandBBeaninstances.
YoushouldnotethatifthebeandefinitionforaBeanPostProcessorbeanspecifiesthatitshouldbelazily
created (refer <bean> element’s lazy-init attribute or <beans> elements default-lazy-init attribute in
section 2-5 of chapter 2), the Spring container ignores lazy initialization configuration and creates the
BeanPostProcessor bean instance before creating instances of singleton-scoped beans defined in the
applicationcontextXMLfile.YoushouldnotethatthebeansthatimplementBeanFactoryPostProcessor
interface (explained in section 5-4) are created before the beans that implement BeanPostProcessor
interface.
LetsnowlookatsomeexamplescenariosinwhichyoucanuseSpringsBeanPostProcessor.
IMPORT chapter 5/ch05-bankapp-beanpostprocessor (This project shows the MyBank application
that uses BeanPostProcessor implementations to validate bean instances and to resolve bean
dependencies.ToverifythattheBeanPostProcessorimplementationsfunctioncorrectly,executethemain
methodoftheBankAppclassofthisproject.)
BeanPostProcessorexampleValidatingbeaninstances
InaSpringapplication,youmaywanttoverifythatabeaninstanceisconfiguredcorrectlybeforeitis
injectedintodependentbeansoraccessedbyotherobjectsintheapplication.Letsseehowwecanusea
BeanPostProcessor implementation to give an opportunity to each bean instance to validate its
configurationbeforethebeaninstanceismadeavailabletodependentbeansorotherapplicationobjects.
ThefollowingexamplelistingshowstheMyBank’sInstanceValidatorinterfacethatmustbeimplemented
bybeanswhoseconfigurationwewanttovalidateusingaBeanPostProcessorimplementation:
Examplelisting5-9–InstanceValidatorinterface
Project–ch05-bankapp-beanpostprocessor
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/common
packagesample.spring.chapter05.bankapp.common;
publicinterfaceInstanceValidator{
voidvalidateInstance();
}
InstanceValidatorinterfacedefinesavalidateInstancemethodthatverifieswhetherthebeaninstancewas
correctly initialized or not. We’ll soon see that the validateInstance method is invoked by a
BeanPostProcessorimplementation.
ThefollowingexamplelistingshowstheFixedDepositDaoImplclassthatimplementsInstanceValidator
interface:
Examplelisting5-10–FixedDepositDaoImplclass
Project–ch05-bankapp-beanpostprocessor
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/dao
packagesample.spring.chapter05.bankapp.dao;
importorg.apache.log4j.Logger;
importsample.spring.chapter05.bankapp.common.InstanceValidator;
publicclassFixedDepositDaoImplimplementsFixedDepositDao,InstanceValidator{
privatestaticLoggerlogger=Logger.getLogger(FixedDepositDaoImpl.class);
privateDatabaseConnectionconnection;
publicFixedDepositDaoImpl(){
logger.info("FixedDepositDaoImpl'sconstructorinvoked");
}
publicvoidinitializeDbConnection(){
logger.info("FixedDepositDaoImplísinitializeDbConnectionmethodinvoked");
connection=DatabaseConnection.getInstance();
}
@Override
publicvoidvalidateInstance(){
logger.info("ValidatingFixedDepositDaoImplinstance");
if(connection==null){
logger.error("FailedtoobtainDatabaseConnectioninstance");
}
}
}
Intheaboveexamplelisting,theinitializeDbConnectionmethodistheinitializationmethodthatretrieves
aninstanceofDatabaseConnectionbycallinggetInstancestaticmethodofDatabaseConnectionclass.The
connection attribute is null if FixedDepositDaoImpl instance fails to retrieve an instance of
DatabaseConnection. Ifconnection attribute is null, the validateInstance method logs an error message
indicating that the FixedDepositDaoImpl instance is not correctly initialized. As the
initializeDbConnection initialization method sets the value of connection attribute, the validateInstance
method must be invoked after the initializeDbConnection method. In a real world application
developmentscenario,ifabeaninstanceisnotconfiguredcorrectly,thevalidateInstancemethodmaytake
some corrective action or throw a runtime exception to stop the application from starting up. For
simplicity, the validateInstance method logs an error message if a bean instance is not configured
correctly.
The following example listing shows the InstanceValidationBeanPostProcessor class that implements
SpringsBeanPostProcessorinterface,andisresponsibleforinvokingvalidateInstancemethodofnewly
createdbeans:
Examplelisting5-11–InstanceValidationBeanPostProcessorclass
Project–ch05-bankapp-beanpostprocessor
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/postprocessor
packagesample.spring.chapter05.bankapp.postprocessor;
importorg.springframework.beans.BeansException;
importorg.springframework.beans.factory.config.BeanPostProcessor;
importorg.springframework.core.Ordered;
publicclassInstanceValidationBeanPostProcessorimplementsBeanPostProcessor,Ordered{
privatestaticLoggerlogger=Logger.getLogger(InstanceValidationBeanPostProcessor.class);
privateintorder;
publicInstanceValidationBeanPostProcessor(){
logger.info("CreatedInstanceValidationBeanPostProcessorinstance");
}
@Override
publicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)
throwsBeansException{
logger.info("postProcessBeforeInitializationmethodinvoked");
returnbean;
}
@Override
publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)
throwsBeansException{
logger.info("postProcessAfterInitializationmethodinvoked");
if(beaninstanceofInstanceValidator){
((InstanceValidator)bean).validateInstance();
}
returnbean;
}
publicvoidsetOrder(intorder){
this.order=order;
}
@Override
publicintgetOrder(){
returnorder;
}
}
The above example listing shows that the InstanceValidationBeanPostProcessor class implements
SpringsBeanPostProcessorandOrderedinterfaces.ThepostProcessBeforeInitializationmethodsimply
returnsthebeaninstancepassedtothemethod.InthepostProcessAfterInitializationmethod,ifthebean
instanceisfoundtobeoftypeInstanceValidator,thebeaninstance’svalidateInstancemethodisinvoked.
This means that if a bean implements InstanceValidator interface, InstanceValidationBeanPostProcessor
callsvalidateInstancemethodofthebeaninstanceaftertheinitializationmethodofthebeaninstanceis
invokedbytheSpringcontainer.
The Ordered interface defines a getOrder method which returns an integer value. The integer value
returned by the getOrder method determines the priority of a BeanPostProcessor implementation with
respectto other BeanPostProcessor implementations configured inthe applicationcontextXMLfile. A
BeanPostProcessorwithhigherordervalueisconsideredatalowerpriority,andisexecutedafterthe
BeanPostProcessorimplementationswithlowerordervaluesareexecuted.Aswewanttheintegervalue
returned by the getOrder method to be configured as a bean property, a setOrder method and an order
instancevariablearedefinedintheInstanceValidationBeanPostProcessorclass.
ThefollowingexamplelistingshowsbeandefinitionsforInstanceValidationBeanPostProcessorclass:
Examplelisting5-12–InstanceValidationBeanPostProcessorbeandefinition
Project–ch05-bankapp-beanpostprocessor
Sourcelocation-src/main/resources/META-INF/spring
<beanclass="…...bankapp.postprocessor.InstanceValidationBeanPostProcessor">
<propertyname="order"value="1"/>
</bean>
Intheabovebeandefinition,<bean>element’sidattributeisnot specified because we typically dont
want InstanceValidationBeanPostProcessor to be a dependency of any other bean. The <property>
elementsetsthevalueoforderpropertyto1.
LetsnowlookataBeanPostProcessorimplementationthatisusedforresolvingbeandependencies.
BeanPostProcessorexampleResolvingbeandependencies
In chapter 4, we saw that if a bean implements Springs ApplicationContextAware interface, it can
programmatically obtain bean instances using ApplicationContexts getBean method. Implementing
ApplicationContextAwareinterfacecouplestheapplicationcodewithSpring,andforthatreasonitisnot
recommended to implement ApplicationContextAware interface. In this section, we’ll look at a
BeanPostProcessorimplementationthatprovidesbeanswithanobjectthatwrapsanApplicationContext
instance, resulting in application code that isnot directly dependent on ApplicationContextAware and
ApplicationContextinterfacesofSpring.
ThefollowingexamplelistingshowstheMyBank’sDependencyResolverinterfacethatisimplementedby
beanswhowanttoprogrammaticallyretrievetheirdependenciesfromtheApplicationContext:
Examplelisting5-13–DependencyResolverinterface
Project–ch05-bankapp-beanpostprocessor
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/common
packagesample.spring.chapter05.bankapp.common;
publicinterfaceDependencyResolver{
voidresolveDependency(MyApplicationContextmyApplicationContext);
}
DependencyResolverdefinesaresolveDependencymethodthatacceptsaMyApplicationContextobject
a wrapper around ApplicationContext object. We’ll soon see that the resolveDependency method is
invokedbyaBeanPostProcessorimplementation.
The following example listing shows the FixedDepositServiceImpl class that implements
DependencyResolverinterface:
Examplelisting5-14–FixedDepositServiceImplclass
Project–ch05-bankapp-beanpostprocessor
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/service
packagesample.spring.chapter05.bankapp.service;
importsample.spring.chapter05.bankapp.common.DependencyResolver;
importsample.spring.chapter05.bankapp.common.MyApplicationContext;
publicclassFixedDepositServiceImplimplementsFixedDepositService,DependencyResolver{
privateFixedDepositDaofixedDepositDao;
.....
@Override
publicvoidresolveDependency(MyApplicationContextmyApplicationContext){
FixedDepositDao=myApplicationContext.getBean(FixedDepositDao.class);
}
}
TheFixedDepositServiceImplclassdefinesaFixedDepositDaoattributeoftypeFixedDepositDao.The
resolveDependency method is responsible for obtaining an instance of FixedDepositDao object from
MyApplicationContext (a wrapper around Springs ApplicationContext object) and assigning it to the
FixedDepositDaoattribute.
The following example listing shows that the DependencyResolutionBeanPostProcessor class invokes
resolveDependencymethodonbeansthatimplementDependencyResolverinterface:
Examplelisting5-15–DependencyResolutionBeanPostProcessorclass
Project–ch05-bankapp-beanpostprocessor
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/postprocessor
packagesample.spring.chapter05.bankapp.postprocessor;
importorg.springframework.beans.factory.config.BeanPostProcessor;
importorg.springframework.core.Ordered;
importsample.spring.chapter05.bankapp.common.MyApplicationContext;
publicclassDependencyResolutionBeanPostProcessorimplementsBeanPostProcessor,
Ordered{
privateMyApplicationContextmyApplicationContext;
privateintorder;

publicvoidsetMyApplicationContext(MyApplicationContextmyApplicationContext){
this.myApplicationContext=myApplicationContext;
}
publicvoidsetOrder(intorder){
this.order=order;
}

@Override
publicintgetOrder(){
returnorder;
}
@Override
publicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)
throwsBeansException{
if(beaninstanceofDependencyResolver){
((DependencyResolver)bean).resolveDependency(myApplicationContext);
}
returnbean;
}
@Override
publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)
throwsBeansException{
returnbean;
}
}
The DependencyResolutionBeanPostProcessor class implements Springs BeanPostProcessor and
Ordered interfaces. The myApplicationContext attribute (of type MyApplicationContext) represents a
dependency of DependencyResolutionBeanPostProcessor. The postProcessBeforeInitialization method
invokes resolveDependency method on bean instances that implement DependencyResolver interface,
passingtheMyApplicationContextobjectasargument.ThepostProcessAfterInitializationmethodsimply
returnsthebeaninstancepassedtothemethod.
The following example listing shows the MyApplicationContext class that acts as a wrapper around
SpringsApplicationContextobject:
Examplelisting5-16–MyApplicationContextclass
Project–ch05-bankapp-beanpostprocessor
Location-src/main/java/sample/spring/chapter05/bankapp/common
packagesample.spring.chapter05.bankapp.common;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.ApplicationContextAware;
publicclassMyApplicationContextimplementsApplicationContextAware{
privateApplicationContextapplicationContext;

@Override
publicvoidsetApplicationContext(ApplicationContextapplicationContext)
throwsBeansException{
this.applicationContext=applicationContext;
}

public<T>TgetBean(Class<T>klass){
returnapplicationContext.getBean(klass);
}
}
The MyApplicationContext class implements Springs ApplicationContextAware interface to obtain
reference to the ApplicationContext object in which the bean is deployed. The MyApplicationContext
class defines a getBean method that returns a bean instance with the given name from the
ApplicationContextinstance.
ThefollowingexamplelistingshowsthebeandefinitionsforDependencyResolutionBeanPostProcessor
andMyApplicationContextclasses:
Examplelisting5-17–applicationContext.xml
Project–ch05-bankapp-beanpostprocessor
Sourcelocation-src/main/resources/META-INF/spring
<beanclass=".....postprocessor.DependencyResolutionBeanPostProcessor">
<propertyname="myApplicationContext"ref="myApplicationContext"/>
<propertyname="order"value="0"/>
</bean>
<beanid="myApplicationContext"class=".....bankapp.common.MyApplicationContext"/>
The bean definition for DependencyResolutionBeanPostProcessor class shows that its order property
value is set to 0. Example listing 5-12 showed that the InstanceValidationBeanPostProcessors order
propertyvalueis1.Aslowerorderpropertyvaluemeanshigherpriority,theSpringcontainerapplies
DependencyResolutionBeanPostProcessor to a bean instance, followed by applying the
InstanceValidationBeanPostProcessor.
ThefollowingexamplelistingshowsthemainmethodofBankAppclassthatchecksthefunctionalityof
DependencyResolutionBeanPostProcessorandInstanceValidationBeanPostProcessor:
Examplelisting5-18–BankAppclass
Project–bankapp-beanpostprocessor
Location-src/main/java/sample/spring/chapter05/bankapp
packagesample.spring.chapter05.bankapp;
publicclassBankApp{
publicstaticvoidmain(Stringargs[])throwsException{
AbstractApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
context.registerShutdownHook();

FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,12,
"someemail@somedomain.com"));
.....
}
}
BankApp’smainmethodretrievesaninstanceofFixedDepositServicefromtheApplicationContextand
executesFixedDepositService’screateFixedDepositmethod.WhenyouexecuteBankApp’smainmethod,
you’llnoticethattheSpringcontainercreatesinstanceofDependencyResolutionBeanPostProcessorand
InstanceValidationBeanPostProcessor beans before creating instance of any other bean defined in the
application context XML file. And, the DependencyResolutionBeanPostProcessor(order value 0) is
appliedtoanewlycreatedbeaninstancebeforetheInstanceValidationBeanPostProcessor(ordervalue1)
isapplied.
You should note that the Spring container doesnt apply a BeanPostProcessor implementation to other
BeanPostProcessor implementations. For instance, in the MyBank application,
DependencyResolutionBeanPostProcessors postProcessBeforeInitializationand
postProcessAfterInitialization methods arenot invoked by the Spring container when an instance of
InstanceValidationBeanPostProcessoriscreated.
Lets now look at the behavior of a BeanPostProcessor implementation for a bean that implements
FactoryBeaninterface.
BeanPostProcessorbehaviorforFactoryBeans
In section 3-9 of chapter 3, we discussed that a bean that implements Springs FactoryBean interface
represents a factory for creating bean instances. The question that you might be asking at this time is
whether a BeanPostProcessor implementation applies to a FactoryBean implementation or to the bean
instances created by the FactoryBean implementation. Later in this section, we’ll see that a
BeanPostProcessors postProcessBeforeInitialization and postProcessAfterInitialization methods are
invoked for a FactoryBean instance created by the Spring container. And, only
postProcessAfterInitializationmethodisinvokedforbeaninstancescreatedbyaFactoryBean.
ThefollowingexamplelistingshowstheEventSenderFactoryBean(aFactoryBeanimplementation)class
ofMyBankapplicationthatcreatesinstancesofEventSenderbean:
Examplelisting5-19–EventSenderFactoryBeanclass
Project–ch05-bankapp-beanpostprocessor
Location-src/main/java/sample/spring/chapter05/bankapp/factory
packagesample.spring.chapter05.bankapp.factory;
importorg.springframework.beans.factory.FactoryBean;
importorg.springframework.beans.factory.InitializingBean;
publicclassEventSenderFactoryBeanimplementsFactoryBean<EventSender>,InitializingBean{
.....
@Override
publicEventSendergetObject()throwsException{
logger.info("getObjectmethodofEventSenderFactoryBeaninvoked");
returnnewEventSender();
}
@Override
publicClass<?>getObjectType(){
returnEventSender.class;
}
@Override
publicbooleanisSingleton(){
returnfalse;
}
@Override
publicvoidafterPropertiesSet()throwsException{
logger.info("afterPropertiesSetmethodofEventSenderFactoryBeaninvoked");
}
}
EventSenderFactoryBean class implements Springs InitializingBean and FactoryBean interfaces. The
getObject method returns an instance of EventSender object. As the isSingleton method returns false,
EventSenderFactoryBeans getObject method is invoked each time EventSenderFactoryBean receives
requestforanEventSenderobject.
The following example listing shows the main method of BankApp class of ch05-bankapp-
beanpostprocessorprojectthatretrievesEventSenderinstancesfromtheEventSenderFactoryBean:
Examplelisting5-20–BankAppclass
Project–ch05-bankapp-beanpostprocessor
Location-src/main/java/sample/spring/chapter05/bankapp
packagesample.spring.chapter05.bankapp;
publicclassBankApp{
publicstaticvoidmain(Stringargs[])throwsException{
AbstractApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
context.registerShutdownHook();
.....
context.getBean("eventSenderFactory");
context.getBean("eventSenderFactory");
}
}
In the above example listing, the ApplicationContext’sgetBean method is called twice to retrieve two
distinct EventSender instances from the EventSenderFactoryBean. If you execute BankApp’s main
method,you’llseethefollowingmessagesprintedontheconsole:
CreatedEventSenderFactoryBean
DependencyResolutionBeanPostProcessor'spostProcessBeforeInitializationmethodinvokedfor.....EventSenderFactoryBean
InstanceValidationBeanPostProcessor'spostProcessBeforeInitializationmethodinvokedfor.....EventSenderFactoryBean
afterPropertiesSetmethodofEventSenderFactoryBeaninvoked
DependencyResolutionBeanPostProcessor'spostProcessAfterInitializationmethodinvokedfor.....EventSenderFactoryBean
InstanceValidationBeanPostProcessor'spostProcessAfterInitializationmethodinvokedforbean.....EventSenderFactoryBean
The above output shows that a BeanPostProcessors postProcessBeforeInitialization and
postProcessAfterInitializationmethodsareinvokedfortheEventSenderFactoryBeaninstancecreatedby
theSpringcontainer.
ExecutionofBankApp’smainmethodalsoshowsthefollowingoutputontheconsole:
getObjectmethodofEventSenderFactoryBeaninvoked
DependencyResolutionBeanPostProcessor'spostProcessAfterInitializationmethodinvokedfor.....EventSender
getObjectmethodofEventSenderFactoryBeaninvoked
DependencyResolutionBeanPostProcessor'spostProcessAfterInitializationmethodinvokedfor.....EventSender
The above output shows thatonlythepostProcessAfterInitialization method of a BeanPostProcessor is
invokedfortheEventSenderinstancecreatedbytheEventSenderFactoryBean.Ifyouwant,youcanmake
modificationstoanEventSenderinstanceinthepostProcessAfterInitializationmethod.
LetsnowlookatSpringsbuilt-inRequiredAnnotationBeanPostProcessorthatyoucanusetoensurethat
required(ormandatory)beanpropertiesareconfiguredintheapplicationcontextXMLfile.
RequiredAnnotationBeanPostProcessor
If the setter-method for a bean property is annotated with Springs @Required annotation, Spring’s
RequiredAnnotationBeanPostProcessor (a BeanPostProcessor implementation) checks if the bean
propertyisconfiguredintheapplicationcontextXMLfile.
NOTEYoushouldnotethattheRequiredAnnotationBeanPostProcessorisnotautomaticallyregistered
withtheSpringcontainer,youneedtoregisteritexplicitlybydefiningitintheapplicationcontextXML
file.
Thefollowingexamplelistingshowsanexampleusageof@Requiredannotation:
Examplelisting5-21–@Requiredannotationusage
importorg.springframework.beans.factory.annotation.Required;
publicclassFixedDepositServiceImplimplementsFixedDepositService{
privateFixedDepositDaofixedDepositDao;
@Required
publicvoidsetFixedDepositDao(FixedDepositDaofixedDepositDao){
this.fixedDepositDao=fixedDepositDao;
}
.....
}
In the above example listing, the setFixedDepositDao setter-method for FixedDepositDao property is
annotatedwith@Requiredannotation.IfyouhavedefinedRequiredAnnotationBeanPostProcessorinthe
applicationcontextXMLfile,theRequiredAnnotationBeanPostProcessorwillcheckifyouhavespecified
a<property>element(orusedp-namespace)tosetthevalueofFixedDepositDaoproperty.Ifyouhaven’t
configuredtheFixedDepositDaopropertyinthebeandefinitionfortheFixedDepositServiceImplclassin
the application context XML file, it’ll result in an exception. This shows that you can use
RequiredAnnotationBeanPostProcessor to ensure that all bean instances in your application are
configuredproperlyintheapplicationcontextXMLfile.
RequiredAnnotationBeanPostProcessor only ensures that a bean property is configured in the bean
definition.Itdoesn’tensurethattheconfiguredpropertyvalueiscorrect.Forinstance,youcanconfigurea
propertys value as null, instead of a valid value. For this reason, beans may still need to implement
initializationmethodstocheckifthepropertiesarecorrectlyset.
Lets now look at Springs DestructionAwareBeanPostProcessor interface that is a sub-interface of
SpringsBeanPostProcessorinterface.
DestructionAwareBeanPostProcessor
SofarwehaveseenthataBeanPostProcessorimplementationisusedforinteractingwithnewlycreated
bean instances. In some scenarios you may also want to interact with a bean instance before it is
destroyed. To interact with a bean instance before it is destroyed, configure a bean that implements
Springs DestructionAwareBeanPostProcessor interface in the application context XML file.
DestructionAwareBeanPostProcessor is asub-interface ofBeanPostProcessor interface and defines the
followingmethod:
voidpostProcessBeforeDestruction(Objectbean,StringbeanName)
ThepostProcessBeforeDestructionmethodacceptsthebeaninstance,whichisabouttobedestroyedby
the Spring container, and its name as arguments. Spring container invokes the
postProcessBeforeDestructionmethodforeachsingleton-scopedbeaninstancebeforethebeaninstanceis
destroyedbytheSpringcontainer.Usually, the postProcessBeforeDestructionmethodisused toinvoke
custom destruction methods on the bean instances. It is important to note that the
postProcessBeforeDestructionmethodisnotcalledforprototype-scopedbeans.
We’llnowlookatSpringsBeanFactoryPostProcessorinterface,whichallowsyoutomakemodifications
tobeandefinitions.
5-4ModifyingbeandefinitionsusingBeanFactoryPostProcessor
SpringsBeanFactoryPostProcessorinterfaceisimplementedbyclassesthatwanttomakemodifications
to bean definitions. A BeanFactoryPostProcessor is executed after bean definitions are loaded by the
Springcontainer,butbeforeanybeaninstanceiscreated.ABeanFactoryPostProcessoriscreatedbefore
any other bean defined in the application context XML file, giving the BeanFactoryPostProcessor an
opportunity to make modifications to bean definitions of other beans. You configure a
BeanFactoryPostProcessorimplementationintheapplicationcontextXMLfilelikeanyotherSpringbean.
NOTEInsteadofbeandefinitions,ifyouwanttomodifyorinteractwithbeaninstances,usea
BeanPostProcessor(refertosection5-3)andnotaBeanFactoryPostProcessor.
BeanFactoryPostProcessor interface defines a single method - postProcessBeanFactory. This method
acceptsanargumentoftypeConfigurableListableBeanFactorythatcanbeusedtoobtainandmodifybean
definitions loaded by the Spring container. It is possible to create a bean instance inside
postProcessBeanFactorymethoditselfbycallingConfigurableListableBeanFactorysgetBeanmethod,but
bean creation inside postProcessBeanFactory method isnot recommended. It is important to note that
BeanPostProcessors (refer section 5-3) are not executed for bean instances created inside
postProcessBeanFactorymethod.
ItisimportanttonotethataConfigurableListableBeanFactoryprovidesaccesstotheSpringcontainerjust
like the ApplicationContext object. ConfigurableListableBeanFactory additionally allows you to
configure the Spring container, iterate over beans, and modify bean definitions. For instance, using
ConfigurableListableBeanFactoryobjectyoucanregisterPropertyEditorRegistrars(refersection3-6of
chapter 3), register BeanPostProcessors, and so on. Later in this section, we’ll see how
ConfigurableListableBeanFactoryobjectisusedtomodifybeandefinitions.
LetsnowlookathowwecanuseaBeanFactoryPostProcessortomodifybeandefinitions.
IMPORT chapter 5/ch05-bankapp-beanfactorypostprocessor (This project shows the MyBank
application that uses a BeanFactoryPostProcessor implementation to disable autowiring across the
application,andloganerrormessageifasingleton-scopedbeanisfoundtobedependentonaprototype-
scopedbean.ToverifythattheBeanFactoryPostProcessorimplementationfunctionscorrectly,executethe
mainmethodoftheBankAppclassofthisproject.)
BeanFactoryPostProcessorexample
In the previous chapter, we saw that autowiring hides the overall structure of the application (refer
section4-6of chapter4). Wealsodiscussedthat insteadofusing<property> elementtospecifythata
singleton-scoped bean is dependent on a prototype-scoped bean, you should use <lookup-method> or
<replaced-method>element(refersection4-4and4-5ofchapter4formoredetails)toprogrammatically
obtain a prototype-scoped dependency of a singleton-bean. We’ll now look at a
BeanFactoryPostProcessor implementation that makes beans unavailable for autowiring (refer <bean>
element’sautowire-candidateattributedescribedinsection4-6ofchapter4)andlogsanerrormessageif
itfindsasingleton-scopedbeanisdependentonaprototype-scopedbean.Forsimplicity,weassumethat
asingleton-scopedbeanuses<property> elementtospecifythat itis dependenton aprototype-scoped
bean.
NOTEAbeanthatimplementsSpringsBeanFactoryPostProcessorinterfaceisaspecialbeantype;the
SpringcontainerautomaticallydetectsandexecutesaBeanFactoryPostProcessorbean.
The following example listing shows the MyBank’s ApplicationConfigurer class that implements
BeanFactoryPostProcessorinterface:
Examplelisting5-22–ApplicationConfigurerclass–aBeanFactoryPostProcessorimplementation
Project–ch05-bankapp-beanfactorypostprocessor
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/postprocessor
packagesample.spring.chapter05.bankapp.postprocessor;
importorg.springframework.beans.factory.config.BeanDefinition;
importorg.springframework.beans.factory.config.BeanFactoryPostProcessor;
importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;
publicclassApplicationConfigurerimplementsBeanFactoryPostProcessor{
publicApplicationConfigurer(){
logger.info("CreatedApplicationConfigurerinstance");
}
@Override
publicvoidpostProcessBeanFactory(
ConfigurableListableBeanFactorybeanFactory)throwsBeansException{
String[]beanDefinitionNames=beanFactory.getBeanDefinitionNames();
//--getallthebeandefinitions
for(inti=0;i<beanDefinitionNames.length;i++){
StringbeanName=beanDefinitionNames[i];
BeanDefinitionbeanDefinition=beanFactory.getBeanDefinition(beanName);
beanDefinition.setAutowireCandidate(false);
//--obtaindependenciesofabean
if(beanDefinition.isSingleton()){
if(hasPrototypeDependency(beanFactory,beanDefinition)){
logger.error("Singleton-scoped"+beanName
+"beanisdependentonaprototype-scopedbean.");
}
}
}
}
.....
}
ThefollowingsequenceofactionsisperformedbythepostProcessBeanFactorymethod:
1.  First, the postProcessBeanFactory method calls ConfigurableListableBeanFactorys
getBeanDefinitionNamesmethodtoobtain namesofallthebeandefinitionsloadedbytheSpring
container.Youshouldnotethatthenameofabeandefinitionisthevalueof<bean>element’sid
attribute.
2.    Once the names of all the bean definitions are obtained, the postProcessBeanFactory method
invokesConfigurableListableBeanFactorysgetBeanDefinitionmethodtoobtaintheBeanDefinition
object corresponding to each bean definition. The getBeanDefinition method accepts a bean
definitionname(obtainedinstep1)asargument.
3.    A BeanDefinition object represents a bean definition, and can be used to modify bean
configuration.ForeachbeandefinitionloadedbytheSpringcontainer,thepostProcessBeanFactory
methodinvokesBeanDefinitionssetAutowireCandidatemethodtomakeallthebeansunavailable
forautowiring.
4.   BeanDefinitionsisSingleton methodreturns true if a bean definition is for a singleton-scoped
bean. If a bean definition is for a singleton-scoped bean, the postProcessBeanFactory method
invokeshasPrototypeDependencymethodtocheckifthesingleton-scopedbeanisdependentonany
prototype-scopedbean.And,ifthesingleton-scopedbeanisdependentonaprototype-scopedbean,
thepostProcessBeanFactorymethodlogsanerrormessage.
The following example listing shows the implementation of ApplicationConfigurer’s
hasPrototypeDependencymethodthatreturnstrueifabeanisdependentonaprototype-scopedbean:
Examplelisting5-23–ApplicationConfigurershasPrototypeDependencymethod
Project–ch05-bankapp-beanfactorypostprocessor
Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/postprocessor
importorg.springframework.beans.MutablePropertyValues;
importorg.springframework.beans.PropertyValue;
importorg.springframework.beans.factory.config.RuntimeBeanReference;
publicclassApplicationConfigurerimplementsBeanFactoryPostProcessor{
.....
privatebooleanhasPrototypeDependency(ConfigurableListableBeanFactorybeanFactory,
BeanDefinitionbeanDefinition){
booleanisPrototype=false;
MutablePropertyValuesmutablePropertyValues=beanDefinition.getPropertyValues();
PropertyValue[]propertyValues=mutablePropertyValues.getPropertyValues();
for(intj=0;j<propertyValues.length;j++){
if(propertyValues[j].getValue()instanceofRuntimeBeanReference){
StringdependencyBeanName=((RuntimeBeanReference)propertyValues[j]
.getValue()).getBeanName();
BeanDefinitiondependencyBeanDef=beanFactory
.getBeanDefinition(dependencyBeanName);
if(dependencyBeanDef.isPrototype()){
isPrototype=true;
break;
}
}
}
returnisPrototype;
}
}
The hasPrototypeDependency method checks if the bean represented by BeanDefinition argument is
dependentonaprototype-scopedbean.TheConfigurableListableBeanFactoryargumentprovidesaccess
to bean definitions loaded bytheSpring container. Thefollowingsequence of actions is performedby
hasPrototypeDependencymethod to find if the bean represented by the BeanDefinition argument has a
prototype-scopeddependency:
1.First,hasPrototypeDependencymethodcallsBeanDefinitionsgetPropertyValuesmethodtoobtain
bean properties defined by <property> elements. BeanDefinitions getPropertyValues returns an
objectoftypeMutablePropertyValueswhichyoucanusetomodifybeanproperties.Forinstance,
you can add additional properties to the bean definition by using addPropertyValue and
addPropertyValuesmethodsofMutablePropertyValues.
2.  As we want to iterate over all the bean properties and check if any bean property refers to a
prototype-scoped bean, the getPropertyValues method ofMutablePropertyValues is invoked to
retrieveanarrayofPropertyValueobjects.APropertyValueobjectholdsinformationaboutabean
property.
3. If abeanproperty refers to a Spring bean, calling PropertyValuesgetValue method returns an
instance of RuntimeBeanReferenceobject that holds name of the referenced bean. As we are
interested in bean properties that reference Spring beans, the return value of PropertyValue’s
getValuemethodischeckedifitrepresentsaninstanceofRuntimeBeanReferencetype.Ifitdoes,
theobjectreturnedbyPropertyValuesgetValuemethodiscasttoRuntimeBeanReferencetype,and
thenameofthereferencedbeanisobtainedbycallingtheRuntimeBeanReference’sgetBeanName
method.
4.    Now, that we have the name of the bean referenced by the bean property, the BeanDefinition
object for the referenced bean is obtained by calling ConfigurableListableBeanFactorys
getBeanDefinition method. You can check if the referenced bean is a prototype-scoped bean by
callingBeanDefinitionsisPrototypemethod.
ThefollowingsequencediagramsummarizeshowhasPrototypeDependencymethodworks:
Figure5-2–hasPrototypeDependencymethoditeratesoverbeandefinitionsofdependencies,andreturns
trueifaprototype-scopeddependencyisfound
In the above sequence diagram ConfigurableListableBeanFactory object has been depicted as ‘Bean
factoryobject.
The following example listing shows the application context XML file of ch05-bankapp-
beanfactorypostprocessor project that contains bean definitions for ApplicationConfigurer class (a
BeanFactoryPostProcessor implementation), InstanceValidationBeanPostProcessor class (a
BeanPostProcessorimplementation),alongwithbeandefinitionsforapplication-specificobjects:
Examplelisting5-24–applicationContext.xml-BeanFactoryPostProcessorbeandefinition
Project–ch05-bankapp-beanfactorypostprocessor
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
.....
<beanid="FixedDepositDao"
class="sample.spring.chapter05.bankapp.dao.FixedDepositDaoImpl".....>
<propertyname=“fixedDepositDetails"ref="FixedDepositDetails"/>
</bean>
<beanid="FixedDepositDetails"
class="sample.spring.chapter05.bankapp.domain.FixedDepositDetails"
scope="prototype"/>
<beanclass=".....postprocessor.InstanceValidationBeanPostProcessor">
<propertyname="order"value="1"/>
</bean>
<bean
class="sample.spring.chapter05.bankapp.postprocessor.ApplicationConfigurer"/>
</beans>
In the bean definitions shown above, the singleton-scoped FixedDepositDao bean is dependent on the
prototype-scopedFixedDepositDetailsbean.
If you execute the main method of BankApp class of ch05-bankapp-beanfactorypostprocessor project,
you’llseethefollowingoutputontheconsole:
CreatedApplicationConfigurerinstance
Singleton-scopedFixedDepositDaobeanisdependentonaprototype-scopedbean.
CreatedInstanceValidationBeanPostProcessorinstance
The above output shows that the Spring container creates ApplicationConfigurer (a
BeanFactoryPostProcessor) and executes ApplicationConfigurers postProcessBeanFactory method
beforecreatingInstanceValidationBeanPostProcessor(aBeanPostProcessor) instance.Itis importantto
note that the beans that implement the BeanFactoryPostProcessor interface are processed before beans
thatimplementtheBeanPostProcessorinterface.Forthisreason,youcan’tuseaBeanPostProcessor to
make modifications to a BeanFactoryPostProcessor instance. The BeanFactoryPostProcessor gives you
the opportunity to modify bean definitions loaded by the Spring container, and the
BeanFactoryPostProcessor gives you the opportunity to make modifications to newly created bean
instances.
LetsnowlookatsomeofthesimilaritiesbetweenBeanPostProcessorsandBeanFactoryPostProcessors:
· youcanconfiguremultiple BeanFactoryPostProcessors intheapplicationcontext XML file. To
control the order in which BeanFactoryPostProcessors are executed by the Spring container,
implementSpringsOrderedinterface(refersection5-3toknowmoreaboutOrderedinterface).
· evenifyouspecify thataBeanFactoryPostProcessor implementationis lazily initialized by the
Spring container, BeanFactoryPostProcessors are created when the Spring container instance is
created.
In chapter 3, we looked at CustomEditorConfigurer – a BeanFactoryPostProcessor implementation that
Spring provides out-of-the-box for registering custom property editors. Let’s now look at some more
BeanFactoryPostProcessorimplementationsthatSpringprovidesout-of-the-box.
PropertySourcesPlaceholderConfigurer
Sofarwehaveseenbeandefinitionexamplesinwhich<property>or<constructor-arg>element’svalue
attribute is used to specify the actual string value of a bean property or a constructor argument.
PropertySourcesPlaceholderConfigurer(aBeanFactoryPostProcessor)let’syouspecifytheactualstring
valueofbeanpropertiesandconstructorargumentsinapropertiesfile.Inthebeandefinition,youonly
specifyproperty placeholders (of the form ${<property_name_in_properties_file>}) as the value of
<property> or <constructor-arg> element’s value attribute. When bean definitions are loaded by the
Springcontainer,thePropertySourcesPlaceholderConfigurer pullsthe actual values fromthe properties
fileandreplacesthepropertyplaceholdersinthebeandefinitionswithactualvalues.
IMPORT chapter 5/ch05-propertySourcesPlaceholderConfigurer-example(This project shows a
SpringapplicationthatusesSpringsPropertySourcesPlaceholderConfigurertosetbeanpropertiesfrom
the properties specified in external properties files. To verify that the
PropertySourcesPlaceholderConfigurerfunctions correctly, execute the main method of the SampleApp
classofthisproject.)
The following example listing shows bean definitions for DataSource and WebServiceConfiguration
classesthatusepropertyplaceholders:
Examplelisting5-25–applicationContext.xml-Beandefinitionsthatusepropertyplaceholders
Project–ch05-propertySourcesPlaceholderConfigurer-example
Sourcelocation-src/main/resources/META-INF/spring
<beanid="datasource"class="sample.spring.chapter05.domain.DataSource">
<propertyname="url"value="${database.url}"/>
<propertyname="username"value="${database.username}"/>
<propertyname="password"value="${database.password}"/>
<propertyname="driverClass"value="${database.driverClass}"/>
</bean>
<beanid="webServiceConfiguration"
class="sample.spring.chapter05.domain.WebServiceConfiguration">
<propertyname="webServiceUrl"value="${webservice.url}"/>
</bean>
The above example listing shows that each <property> elements value attribute specifies a property
placeholder. When bean definitions are loaded by the Spring container,
PropertySourcesPlaceholderConfigurer replaces property placeholders with values from a properties
file. For instance, if a database.username property is defined in a properties file, the value of
database.usernamepropertyreplacesthe${database.username}propertyplaceholderofdataSourcebean.
The bean definition for the PropertySourcesPlaceholderConfigurer specifies properties files to be
searchedforfindingreplacementforapropertyplaceholder,asshowninthefollowingexamplelisting:
Examplelisting5-26–applicationContext.xml-PropertySourcesPlaceholderConfigurerbeandefinition
Project–ch05-propertySourcesPlaceholderConfigurer-example
Sourcelocation-src/main/resources/META-INF/spring
<bean
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<propertyname="locations">
<list>
<value>classpath:database.properties</value>
<value>classpath:webservice.properties</value>
</list>
</property>
<propertyname="ignoreUnresolvablePlaceholders"value="false"/>
</bean>
PropertySourcesPlaceholderConfigurerslocationspropertyspecifiespropertiesfilestobesearchedfor
finding the value for a property placeholder. In the above example listing,
PropertySourcesPlaceholderConfigurerlooks for the value of a property placeholder in
database.properties and webservice.properties files. The ignoreUnresolvablePlaceholdersproperty
specifieswhetherPropertySourcesPlaceholderConfigurersilentlyignoresorthrowsanexceptionincase
apropertyplaceholdervalueisnotfoundinanyofthepropertiesfilesspecifiedbythelocationsproperty.
ThevaluefalseindicatesthatthePropertySourcesPlaceholderConfigurerwillthrowanexceptionifvalue
forapropertyplaceholderisnotfoundindatabase.propertiesorwebservice.propertiesfiles.
The following example listing shows the properties defined in database.properties and
webservice.propertiesfiles:
Examplelisting5-27–Propertiesdefinedindatabase.propertiesandwebservice.propertiesfiles
Project–ch05-propertySourcesPlaceholderConfigurer-example
Sourcelocation-src/main/resources/META-INF
----------------database.propertiesfile------------------
database.url=some_url
database.username=some_username
database.password=some_password
database.driverClass=some_driverClass
----------------webservice.propertiesfile------------------
webservice.url=some_url
If you compare the properties defined in database.properties and webservice.properties files with the
property placeholders specified in datasource and webServiceConfiguration bean definitions (refer
examplelisting5-25),youllnoticethatforeachpropertyplaceholderapropertyisdefinedinoneofthe
propertiesfiles.
Themainmethod of SampleApp class of ch05-propertySourcesPlaceholderConfigurer-example project
retrievesWebServiceConfigurationand DataSource beans from the ApplicationContext and prints their
propertiesontheconsole.IfyouexecuteSampleApp’smainmethod,youllseethefollowingoutputon
theconsole:
DataSource[url=some_url,username=some_username,password=some_password,driverClass=some_driverClass]
WebServiceConfiguration[webServiceUrl=some_url]
Theaboveoutputshows:
·        DataSources url property is set to some_url, username to some_username, password to
some_passwordanddriverClasstosome_driverClass.
·WebServiceConfigurationswebServiceUrlpropertyissettosome_url.
If you remove a property from either database.properties or webservice.properties file, executing
SampleApp’smainmethodwillresultinanexception.
LetsnowlookatlocalOverridepropertyofPropertySourcesPlaceholderConfigurer.
localOverrideproperty
Ifyouwantlocalproperties(setvia<props>element)tooverridepropertiesreadfrompropertiesfile,
youcansetPropertySourcesPlaceholderConfigurerslocalOverridepropertytotrue.
IMPORT chapter 5/ch05-localoverride-example(This project shows a Spring application that uses
PropertySourcesPlaceholderConfigurerslocalOverrideproperty.Toruntheapplication,executethemain
methodoftheSampleAppclassofthisproject.)
The following example listing shows bean definitions for DataSource and WebServiceConfiguration
classes:
Examplelisting5-28–applicationContext.xml-Beandefinitionsthatusepropertyplaceholders
Project–ch05-localOverride-example
Sourcelocation-src/main/resources/META-INF/spring
<beanid="datasource"class="sample.spring.chapter05.domain.DataSource">
<propertyname="url"value="${database.url}"/>
<propertyname="username"value="${database.username}"/>
<propertyname="password"value="${database.password}"/>
<propertyname="driverClass"value="${database.driverClass}"/>
</bean>
<beanid="webServiceConfiguration"
class="sample.spring.chapter05.domain.WebServiceConfiguration">
<propertyname="webServiceUrl"value="${webservice.url}"/>
</bean>
The bean definitions for DataSource and WebServiceConfiguration classes are same as we saw in
examplelisting5-25.
The following example listing shows the properties defined in database.properties and
webservice.propertiesfiles:
Examplelisting5-29–Propertiesdefinedindatabase.propertiesandwebservice.propertiesfiles
Project–ch05-localOverride-example
Sourcelocation-src/main/resources/META-INF
----------------database.propertiesfile------------------
database.url=some_url
database.username=some_username
----------------webservice.propertiesfile------------------
webservice.url=some_url
If you compare the properties defined in database.properties and webservice.properties files with the
property placeholders specified in datasource and webServiceConfiguration bean definitions (refer
example listing 5-28), you’ll notice that properties are not defined for ${database.password} and
${database.driverClass}placeholdersinthedatabase.propertiesfile.
The following example listing shows the bean definition for PropertySourcesPlaceholderConfigurer
class:
Examplelisting5-30–applicationContext.xml-PropertySourcesPlaceholderConfigurerbeandefinition
Project–ch05-localOverride-example
Sourcelocation-src/main/resources/META-INF/spring
<bean
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<propertyname="locations">
<list>
<value>classpath:database.properties</value>
<value>classpath:webservice.properties</value>
</list>
</property>
<propertyname="properties">
<props>
<propkey="database.password">locally-set-password</prop>
<propkey="database.driverClass">locally-set-driverClass</prop>
<propkey="webservice.url">locally-set-webServiceUrl</prop>
</props>
</property>
<propertyname="ignoreUnresolvablePlaceholders"value="false"/>
<propertyname="localOverride"value="true"/>
</bean>
The properties property of PropertySourcesPlaceholderConfigurer defines local properties. The
database.password, database.driverClass and webservice.url properties are local properties. The
localOverride property specifies whether local properties take precedence over properties read from
externalpropertiesfiles.AsthevalueoflocalOverridepropertyistrue,localpropertiestakeprecedence.
The main method of SampleApp class in ch05-localOverride-example project retrieves
WebServiceConfigurationandDataSourcebeansfromtheApplicationContextandprintstheirproperties
ontheconsole.IfyouexecuteSampleApp’smainmethod,youllseethefollowingoutputontheconsole:
DataSource[url=some_url,username=some_username,password=locally-set-password,driverClass=locally-set-driverClass]
WebServiceConfiguration[webServiceUrl=locally-set-webServiceUrl]
The output shows that the value of DataSources password and driverClass properties are locally-set-
password and locally-set-driverClass, respectively. This means that the values for DataSource’s
password and driverClass properties come from the local properties defined by the
PropertySourcesPlaceholderConfigurer bean (refer example listing 5-30). This shows that if the
PropertySourcesPlaceholderConfigurercantfindapropertyforaplaceholderintheexternalproperties
files, it searches for the property in the local properties defined by
PropertySourcesPlaceholderConfigurerbean.TheoutputalsoshowsthattheWebServiceConfigurations
webServiceUrl property value comes from the local properties defined by the
PropertySourcesPlaceholderConfigurer bean (refer example listing 5-30). The value of
PropertySourcesPlaceholderConfigurers localOverride property is set to true; therefore, the locally
defined webservice.url property takesprecedence over the webservice.url property read from the
webservice.propertiesfile.
NOTEInsteadofusingPropertySourcesPlaceholderConfigurerspropertiesproperty,youcanuse
<properties>elementofSpringsutilschema(refersection3-8ofchapter3)orPropertiesFactoryBean
(refersection3-8ofchapter3)todefinelocalproperties.
Instead of directly configuring the PropertySourcesPlaceholderConfigurer bean in your application
context XML file, you can use the <property-placeholder> element of Springs context schema. The
<property-placeholder>elementconfiguresaPropertySourcesPlaceholderConfigurerinstance.Letsnow
lookatthe<property-placeholder>elementindetail.
IMPORT chapter 5/ch05-property-placeholder-element-example(This project shows a Spring
applicationthatusesthe<property-placeholder>element.Toruntheapplication,executethemainmethod
oftheSampleAppclassofthisproject.)
<property-placeholder>element
The following example listing shows how the <property-placeholder> element is used to configure a
PropertySourcesPlaceholderConfigurerinstancewiththesameconfigurationastheoneweconfiguredin
examplelisting5-30:
Examplelisting5-31–applicationContext.xml-<property-placeholder>element
Project–ch05-property-placeholder-element-example
Sourcelocation-src/main/resources/META-INF/spring
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util".....>
…..
<context:property-placeholderignore-unresolvable="false"
location="classpath:database.properties,classpath:webservice.properties"
local-override="true"order="1"properties-ref="localProps"/>

<util:propertiesid="localProps">
<propkey="database.password">locally-set-password</prop>
<propkey="database.driverClass">locally-set-driverClass</prop>
<propkey="webservice.url">locally-set-webServiceUrl</prop>
</util:properties>
</beans>
In the above example listing, reference to Springs context schema is included so that its elements are
accessible.Theaboveexamplelistingshowsthattheuseof<property-placeholder>elementresultsina
lessverboseconfigurationofPropertySourcesPlaceholderConfigurer.Theignore-unresolvable,location
andlocal-overrideattributescorrespondtoignoreUnresolvablePlaceholders,locationsandlocalOverride
properties of PropertySourcesPlaceholderConfigurer. As the PropertySourcesPlaceholderConfigurer
classimplementsSpringsOrderedinterface,theorderattribute’svalueisusedtosettheorderproperty
of PropertySourcesPlaceholderConfigurer instance. The properties-ref attribute refers to a
java.util.Properties object that represents thelocal properties. In the above example listing, the
<properties> element of Springs util schema (refer section 3-8 of chapter 3) creates an instance of
java.util.Propertiesobject,whichisreferencedbytheproperties-refattributeof<property-placeholder>
element.
LetsnowlookatSpringsPropertyOverrideConfigurer(aBeanFactoryPostProcessor)whichallowsyou
tospecifyvaluesforbeanpropertiesinexternalpropertiesfiles.
PropertyOverrideConfigurer
PropertyOverrideConfigurer is similar to PropertySourcesPlaceholderConfigurer in the sense that it
allows you to specify a bean property value in external properties file. When using
PropertyOverrideConfigurer, bean property value is specified in the following format in external
propertiesfiles:
<bean-name>.<bean-property-name>=<value>
here,<bean-name>isthenameofthebean,<bean-property-name>isthenameofthebeanproperty,
and<value>isthevaluethatyouwanttoassigntothebeanproperty.
ThenotabledifferencesbetweenPropertyOverrideConfigurerandPropertySourcesPlaceholderConfigurer
classesare:
·YoucanusePropertyOverrideConfigureronlyforexternalizingvaluesofbeanproperties,thatis,
youcantusePropertyOverrideConfigurertoexternalizevaluesofconstructorarguments.
·PropertySourcesPlaceholderConfigurerdoesn’tprovideyouwithanoptiontospecifydefault
values for properties. But, PropertyOverrideConfigurer allows you to specify default values for
beanproperties.
LetsnowlookatanexampleusageofPropertyOverrideConfigurer.
IMPORT chapter 5/ch05-propertyOverrideConfigurer-example(This project shows a Spring
application that uses Springs PropertyOverrideConfigurer. To run the application, execute the main
methodoftheSampleAppclassofthisproject.)
PropertyOverrideConfigurerexample
The following example listing shows bean definitions for DataSource and WebServiceConfiguration
classeswhosepropertieswe’llsetusingPropertyOverrideConfigurer:
Example listing 5-32 – applicationContext.xml - Bean definitions for DataSource and
WebServiceConfiguration
Project–ch05-propertyOverrideConfigurer-example
Sourcelocation-src/main/resources/META-INF/spring
<beanid="datasource"class="sample.spring.chapter05.domain.DataSource">
<propertyname="url"value="testurlvalue"/>
<propertyname="username"value="testusernamevalue"/>
<propertyname="password"value="testpasswordvalue"/>
<propertyname="driverClass"value="testdriverClassvalue"/>
</bean>
<beanid="webServiceConfiguration"
class="sample.spring.chapter05.domain.WebServiceConfiguration">
<propertyname="webServiceUrl"value="thiswebserviceurlneedstobereplaced"/>
</bean>
In the above example listing, the <bean> element’s value attribute specifies default value of a bean
property.
The following example listing shows the bean definition for the PropertyOverrideConfigurer class that
replaces the default values of bean properties (shown in example listing 5-32) with values read from
database.propertiesandwebservice.propertiesfiles:
Examplelisting5-33–applicationContext.xml-PropertyOverrideConfigurerconfiguration
Project–ch05-propertyOverrideConfigurer-example
Sourcelocation-src/main/resources/META-INF/spring
<bean
class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
<propertyname="locations">
<list>
<value>classpath:database.properties</value>
<value>classpath:webservice.properties</value>
</list>
</property>
</bean>
In the above example listing,PropertyOverrideConfigurer’s locations property specifies the properties
filesthatcontainvaluesforbeanproperties.
NOTE Instead of directly configuring PropertyOverrideConfigurer, you can use <property-override>
elementofSpringscontextschematoconfigureaPropertyOverrideConfigurerinstance.
The following example listing shows database.properties and webservice.properties files that contain
valuesofbeanproperties:
Examplelisting5-34–Propertiesdefinedindatabase.propertiesandwebservice.properties
Project–ch05-propertyOverrideConfigurer-example
Sourcelocation-src/main/resources/META-INF
----------------database.propertiesfile------------------
datasource.url=some_url
datasource.username=some_username
datasource.password=some_password
----------------webservice.propertiesfile------------------
webServiceConfiguration.webServiceUrl=some_url
The entries in the database.properties and webservice.properties files show that the property name
followsthepattern:<bean-name>.<property-name>. When bean definitionsare loaded bytheSpring
container,PropertyOverrideConfigurerreplacesthedefaultvalueofabeanpropertywiththevalueread
forthatbeanpropertyfromthedatabase.propertiesandwebservice.propertiesfiles.Forinstance,theurl
property of datasource bean is set to the value of datasource.url property defined in the
database.properties file.Similarly,webServiceUrl property of webServiceConfiguration bean is set to
thevalueofwebServiceConfiguration.webServiceUrlpropertydefinedinthewebservice.propertiesfile.
If no value is found for a bean property in the external properties files, the bean property retains its
defaultvalue.Examplelisting5-32showsthatthedriverClasspropertyofdatasourcebeanhasthedefault
value ‘test driverClass value’. Example listing 5-34 shows that there is no property named
datasource.driverClass defined in the database.properties or webservice.properties file; therefore, the
driverClassbeanpropertyretainsitsdefaultvalue.
The main method of SampleApp class of ch05-propertyOverrideConfigurer-example project retrieves
WebServiceConfigurationandDataSourcebeansfromtheApplicationContextandprintstheirproperties
ontheconsole.IfyouexecuteSampleApp’smainmethod,youllseethefollowingoutputontheconsole:
DataSource[url=some_url,username=some_username,password=some_password,driverClass=testdriverClassvalue]
WebServiceConfiguration[webServiceUrl=some_url]
The above output shows that the default values of all bean properties, except that of driverClass, are
replacedbythepropertyvaluesspecifiedintheexternalpropertiesfiles.
As PropertyOverrideConfigurer and PropertySourcesPlaceholderConfigurer inherit from Springs
PropertyResourceConfigurer class, youll notice that both of these classes share many common
configurationoptions.Forinstance,youcansetPropertyOverrideConfigurerslocalOverridepropertyto
controlwhetherthelocalpropertiesgetprecedenceoverpropertiesreadfromexternalpropertiesfiles,
youcansetPropertyOverrideConfigurerspropertiespropertytodefinelocalproperties,andsoon.
5-5Summary
Inthischapter,wesawhowtoaddcustominitializationanddestructionlogictoabeaninstance.Wealso
lookedathowyoucanmodifynewlycreatedbeaninstancesusingBeanPostProcessorimplementations,
and modify beandefinitions using BeanFactoryPostProcessor implementations. Spring internally makes
useofBeanPostProcessorsandBeanFactoryPostProcessorstoprovidemanyframeworkfeatures.Inthe
nextchapter,we’lllookatSpringssupportforannotation-drivendevelopment.
Chapter6-Annotation-drivendevelopmentwithSpring
6-1Introduction
Inpreviouschapters,wesawthatthebeandefinitionscontainedintheapplicationcontextXMLfileare
used as a blueprint by the Spring container to create bean instances. A bean definition specifies
information about bean dependencies, initialization and destruction methods of a bean, lazy or eager
initialization strategy for the bean instance, bean scope, and so on. In this section, we’ll look at
annotationsthatyoucanusetospecifythesame informationin thebeanclassitself,therebysavingthe
effort toexplicitlyconfigureabeanintheapplication context XML file. We’ll alsotouch upon Spring
ExpressionLanguage(SpEL)andhowtovalidateobjectsusingSpringsValidatorinterfaceandthrough
JSR303annotations.We’llendthischapterwithaquicklookathowtoprogrammaticallydefineSpring
beansusingSprings@Configurationand@Beanannotations.
Lets firstbegin with looking at Spring’s @Component annotation that indicates that a particular class
representsaSpringcomponent.
6-2IdentifyingSpringcomponentswith@Component
Springs @Component annotation is a type-level annotation, which indicates that a class represents a
Springcomponent.Itisrecommendedthatyouusemorespecializedformsof@Componentannotationto
annotatecontrollers,servicesanddataaccessobjects(DAOs)ofyourapplication.Forinstance,annotate
controllerswith@Controller,serviceswith@Service,andDAOswith@Repositoryannotation.
IMPORTchapter6/ch06-bankapp-annotations(ThisprojectshowstheMyBankapplicationthatuses
annotationsforregisteringbeanswiththeSpringcontainerandforautowiringdependencies.Torunthe
application,executethemainmethodoftheBankAppclassofthisproject.)
The following example listing shows the MyBank’s FixedDepositServiceImpl class that makes use of
@Serviceannotation:
Examplelisting6-1–FixedDepositServiceImplclass-@Serviceannotationusage
Project–ch06-bankapp-annotations
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
importorg.springframework.stereotype.Service;
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{.....}
As FixedDepositSerivceImpl class is annotated with @Service annotation, FixedDepositServiceImpl
class represents a Spring component. @Service annotation accepts a value attribute that specifies the
name with which the component is registered as a bean with the Spring container. For instance,
FixedDepositServiceImpl class is registered with Spring container as a bean with the name
FixedDepositService.Thevalueattributeservesthesamepurposeasthe<bean>element’sidattribute.
Like@Serviceannotation,@Component,@Repositoryand@Controllerannotationsspecifythenameof
the component via value attribute. You can specify the name of a Spring component without explicitly
specifying the value attribute. This means that @Service(value="FixedDepositService") is same as
@Service("FixedDepositService").Ifyoudontspecifyanameforthecomponent,Springassumesname
of the component is same as the name of the component class. Only difference is that the name of the
componentbeginswithalowercaseletter.Youshouldspecifyacustomnameforacomponentbecauseit’s
particularlyhelpfulwhenautowiringdependencies‘byname’.
If you enable classpath-scanning feature of Spring, bean classes annotated with @Component,
@Controller, @Service or @Repository annotations are automatically registered with the Spring
container. You enable classpath scanning feature of Spring by using the <component-scan> element of
Springscontextschema.
Thefollowingexamplelistingshowsusageof<component-scan>element:
Examplelisting6-2–applicationContext.xml
Project–ch06-bankapp-annotations
Sourcelocation-src/main/resources/META-INF/spring
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=".....http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scanbase-package="sample.spring"/>
</beans>
In the above example listing, reference to Springs context schema is included so that its elements are
accessible. The <component-scan> elements base-package attribute specifies comma-separated list of
packages that should be searched for Spring components. As the base-package attribute’s value is
sample.spring,Springcomponentsare searchedinsidesample.spring package and itssub-packages. As
theFixedDepositServiceImplclassshowninexamplelisting6-1isannotatedwith@Serviceannotation
andislocatedinpackagesample.spring.chapter06.bankapp.service,the<component-scan>elementinthe
aboveexamplelistingautomaticallyregistersFixedDepositServiceImplclassasabeanwiththeSpring
container.ThisisequivalenttothefollowingbeandefinitionfortheFixedDepositServiceImplclassinthe
applicationcontextXMLfile:
Examplelisting6-3–BeandefinitionfortheFixedDepositServiceImplclass
<beanid="FixedDepositService"
class="sample.spring.chapter06.bankapp.service.FixedDepositServiceImpl"/>
Ifyouwanttofilterthecomponentclassesthatshouldbeconsideredforautomaticregistrationwiththe
Spring container, use the resource-pattern attribute of <component-scan> element. The default value of
resource-pattern attribute is **/*.class, which means all the component classes under the package(s)
specifiedbythebase-packageattributewillbeconsideredforautomaticregistration.The<include-filter>
and<exclude-filter>sub-elementsof<component-scan>elementprovideamoreconcisewaytospecify
component classes that should be considered for automatic registration, and the classes that should be
ignored. For instance, the following example listing shows an example usage of <include-filter> and
<exclude-filter>elements:
Examplelisting6-4–<include-filter>and<exclude-filter>elements
<beans.....>
<context:component-scanbase-package="sample.example">
<context:include-filtertype="annotation"expression="example.annotation.MyAnnotation"/>
<context:exclude-filtertype="regex"expression=".*Details"/>
</context:component-scan>
</beans>
The<exclude-filter>and<include-filter>elementsdefineatypeattributethatspecifiesthestrategyused
forfilteringcomponentclasses,andtheexpressionattributespecifiesthecorrespondingfilterexpression.
In the above example listing, the <include-filter> element specifies that the component classes that are
annotatedwithMyAnnotationtype-levelannotationareautomaticallyregisteredwiththeSpringcontainer,
andthe<exclude-filter>elementspecifiesthatthecomponentclasseswhosenamesendwithDetailsare
ignoredbythe<component-scan>element.
The following table describes the possible values that the type attributes of <include-filter> and
<exclude-filter>elementscanaccept:
Valueoftypeattribute Description
annotation
If the type attribute’s value is annotation, the expression attribute specifies the fully-
qualifiedclassnameoftheannotationthatacomponentclassmustbeannotatedwith.For
instance, if the expression attribute’s value is example.annotation.MyAnnotation,
componentclassesthat areannotatedwith MyAnnotationannotationare consideredfor
inclusion (in case of <include-filter> element) or exclusion (in case of <exclude-filter>
element).
assignable If the type attribute’s value is assignable, the expression attribute specifies the fully-
qualifiednameofaclassorinterfacetowhichacomponentclassmustbeassignable.
aspectj If the type attribute’s value is aspectj, the expression attribute specifies an AspectJ
expressionthatisusedforfilteringthecomponentclasses.
regex Ifthetypeattribute’svalueisregex,theexpressionattributespecifiesaregularexpression
thatisusedforfilteringcomponentclassesbytheirnames.
custom
If the type attribute’s value is custom, an implementation of
org.springframework.core.type.TypeFilter interface is specified by the expression
attributeforfilteringthecomponentclasses.
NOTE In this section, we looked at an example usage of @Service annotation. @Component,
@Controller and @Repository annotations are specified the same way as @Service annotation. Refer
CustomerRegistrationDetailsandCustomerRequestDetailsclassesofch06-bankapp-annotationsproject
to see usage of @Component annotation. Refer DAO classes contained in ch06-bankapp-annotations
projecttoseeusageof@Repositoryannotation.
AsSpringcomponentsarenotdefinedintheapplicationcontextXMLfile,youdonthavetheoptionto
use <property> or <constructor-arg> element to specify their dependencies. For this reason, Spring
componentsmakeuseofannotationslike@Autowired,@Inject,andsoon,tospecifytheirdependencies.
LetsnowlookatSprings@Autowiredannotation.
6-3@Autowired-autowiringdependenciesbytype
@Autowired annotation is used to autowire dependencies ‘by type’. Springs @Autowired annotation
provides the same functionality as the Spring’s autowiring feature that we discussed in chapter 4, but
@Autowired annotation offers a more cleaner and flexible approachto autowiring beandependencies.
@Autowiredannotationcanbeusedatconstructor-level,method-levelandfield-level.
ThefollowingexamplelistingshowstheAccountStatementServiceImplclassthatusesthe@Autowired
annotationatthefield-level:
Examplelisting6-5–AccountStatementServiceImplclass-@Autowiredannotationusageatthefield-
level
Project–ch06-bankapp-annotations
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Service;
@Service(value="accountStatementService")
publicclassAccountStatementServiceImplimplementsAccountStatementService{
@Autowired
privateAccountStatementDaoaccountStatementDao;

@Override
publicAccountStatementgetAccountStatement(Datefrom,Dateto){
returnaccountStatementDao.getAccountStatement(from,to);
}
}
Intheaboveexamplelisting,theaccountStatementDaofield(oftypeAccountStatementDao)isannotated
with @Autowired annotation.  When an instance of AccountStatementServiceImpl is created, Springs
AutowiredAnnotationBeanPostProcessor (a BeanPostProcessor implementation) is responsible for
autowiringaccountStatementDaofield.TheAutowiredAnnotationBeanPostProcessorretrievesreference
toanAccountStatementDaotypebeanfromtheSpringcontainerandassignsittotheaccountStatementDao
field.Itisimportanttonotethatthefieldannotatedwith@Autowiredannotationneednotbepublicor
haveacorrespondingpublicsettermethod.
NOTESpringsAutowiredAnnotationBeanPostProcessorperformsautowiringoffields,methodsand
constructorsthatareannotatedwithSprings@AutowiredorJSR330’s@Inject(explainedinsection6-
5)annotation.
The following example listing shows the CustomerRegistrationServiceImpl class that uses the
@Autowiredannotationatthemethod-level:
Example listing 6-6 – CustomerRegistrationServiceImpl class - @Autowired annotation usage at the
method-level
Project–ch06-bankapp-annotations
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
@Service("customerRegistrationService")
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
publicclassCustomerRegistrationServiceImplimplementsCustomerRegistrationService{
privateCustomerRegistrationDetailscustomerRegistrationDetails;
.....
@Autowired
publicvoidobtainCustomerRegistrationDetails(
CustomerRegistrationDetailscustomerRegistrationDetails){
this.customerRegistrationDetails=customerRegistrationDetails;
}
.....
@Override
publicvoidsetAccountNumber(StringaccountNumber){
customerRegistrationDetails.setAccountNumber(accountNumber);
}
.....
}
Intheaboveexamplelisting,obtainCustomerRegistrationDetailsmethodisannotatedwith@Autowired
annotation. If a method is annotated with @Autowired annotation, the arguments of the method are
autowired.AsobtainCustomerRegistrationDetailsmethodisannotatedwith@Autowiredannotation,its
CustomerRegistrationDetailsargumentisautowiredbytype.Itisimportanttonotethatan@Autowired
annotatedmethodneednotbepublic.
NOTE A method annotated with @Autowired annotation is invoked after the component instance is
created,andthefieldsannotatedwith@Autowiredannotationareinjectedwithmatchingbeaninstances.
The following example listing shows the CustomerRequestServiceImpl class that defines a constructor
annotatedwith@Autowiredannotation:
Examplelisting6-7–CustomerRequestServiceImplclass-@Autowiredannotationusageatconstructor-
level
Project–ch06-bankapp-annotations
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
@Service(value="customerRequestService")
publicclassCustomerRequestServiceImplimplementsCustomerRequestService{
privateCustomerRequestDetailscustomerRequestDetails;
privateCustomerRequestDaocustomerRequestDao;
@Autowired
publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,
CustomerRequestDaocustomerRequestDao){
this.customerRequestDetails=customerRequestDetails;
this.customerRequestDao=customerRequestDao;
}
.....
}
In the above example listing, the CustomerRequestServiceImpl’s constructor is annotated with
@Autowiredannotation.Ifaconstructorisannotatedwith@Autowiredannotation,theargumentsofthe
constructorareautowired.AsCustomerRequestServiceImplsconstructorisannotatedwith@Autowired
annotation,itsCustomerRequestDetailsandCustomerRequestDaoargumentsareautowiredbytype.Itis
importanttonotethatan@Autowiredannotatedconstructorneednotbepublic.
Whenusingthe@Autowiredannotation,exceptionisthrownifabeanmatchingtherequiredtypeisnot
found. For instance, in example listing 6-7, if a bean of type CustomerRequestDetails or
CustomerRequestDaoisnotfoundtoberegisteredwiththeSpringcontainer,anexceptionisthrownwhile
creatingtheCustomerRequestServiceImplinstance.@Autowired’srequiredattributespecifieswhetherit
ismandatoryoroptionaltoautowiredependencies.Ifyouset@Autowired’srequiredattributevalueto
false,autowiringofdependenciesisconsideredoptional.Thismeansthatiftherequiredattribute’svalue
is set to false, exception is not thrown if no bean matching the required type is found in the Spring
container. By default, value of required attribute is true; dependencies must be satisfied by the Spring
container.
Ifacomponentclassdefinesan@Autowiredannotatedconstructorwithrequiredattribute’svaluesetto
true, itcan’t have another @Autowired annotated constructor. For instance, consider the following
examplelistingthatdefines2constructorsannotatedwiththe@Autowiredannotation:
Examplelisting6-8–Acomponentclassthatdefines2@Autowiredannotatedconstructors
@Service(value="customerRequestService")
publicclassCustomerRequestServiceImplimplementsCustomerRequestService{
.....
@Autowired(required=false)
publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails){.....}
@Autowired
publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,
CustomerRequestDaocustomerRequestDao){.....}
}
Asautowiringofdependenciesisrequired(@Autowired’srequiredattributeissettotrue)foroneofthe
constructors and optional (@Autowired’s required attribute is set to false) for the other in the above
examplelisting,itresultsinanexceptionthrownbySpring.
A component class can define multiple @Autowired annotated constructors with required attribute’s
valuesettofalse.Insuchacase,oneoftheconstructorswillbeinvokedbySpringtocreateaninstance
of the component class. The following example listing shows a component class that defines 2
constructorsannotatedwith@Autowired(required=false),andadefaultconstructor:
Examplelisting6-9–Acomponentclassthatdefinesmultiple@Autowiredannotatedconstructorswith
requiredattributevaluesettofalse
@Service(value="customerRequestService")
publicclassCustomerRequestServiceImplimplementsCustomerRequestService{
publicCustomerRequestServiceImpl(){
.....
}
@Autowired(required=false)
publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails){
.....
}
@Autowired(required=false)
publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,
CustomerRequestDaocustomerRequestDao){
.....
}
}
Intheaboveexamplelisting,boththe@Autowiredannotatedconstructorsarecandidatesforautowiring
bySpringtocreateaninstanceoftheCustomerRequestServiceImplclass.Theconstructorwiththelargest
number of satisfied dependencies is chosen. In case of CustomerRequestServiceImpl class, if beans of
typesCustomerRequestDetailsandCustomerRequestDaoareregisteredwiththeSpringcontainer,Spring
invokes CustomerRequestServiceImpl(CustomerRequestDetails, CustomerRequestDao) constructor. If a
bean of type CustomerRequestDetails is registered with container but no bean of type
CustomerRequestDao is registered, CustomerRequestServiceImpl(CustomerRequestDetails) constructor
is invoked. In case none of the dependencies are found, the default constructor of
CustomerRequestServiceImplclassisinvoked.
LetsnowlookathowyoucanuseSprings@Qualifierannotationalongwith@Autowiredannotationto
autowiredependenciesbyname.
6-4@Qualifier–autowiringdependenciesbyname
YoucanuseSprings@Qualifierannotationalongwith@Autowiredannotationtoautowiredependencies
byname.The@Qualifierannotationcanbeusedatfield-level,method-parameter-levelandconstructor-
argument-level.
ThefollowingexamplelistingshowstheFixedDepositServiceImplclassthatuses@Qualifierannotation:
Examplelisting6-10–FixedDepositServiceImplclass-@Qualifierannotationusage
Project–ch06-bankapp-annotations
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.beans.factory.annotation.Qualifier;
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{

@Autowired
@Qualifier(value="myFixedDepositDao")
privateFixedDepositDaomyFixedDepositDao;
.....
}
In theabove examplelisting, myFixedDepositDaofieldis annotated with@Autowired and @Qualifier
annotations.@Qualifierannotationsvalueattributespecifiesthenameofthebeantobeassignedtothe
myFixedDepositDaofield.
Spring first finds autowiring candidates ‘by type’ for the fields, constructors and methods that are
annotated with @Autowired annotation. Then, Spring uses the bean name specified by @Qualifier
annotationtolocateauniquebeanfromthelistofautowiringcandidates.Forexample,inexamplelisting
6-10,SpringfirstfindsbeansoftypeFixedDepositDaoformyFixedDepositDaofield,andthenlocatesthe
bean named myFixedDepositDao from the list of autowiring candidates. If a bean named
myFixedDepositDaoisfound,SpringassignsittothemyFixedDepositDaofield.
NOTE @Qualifier(value="myFixedDepositDao") is same as @Qualifier("myFixedDepositDao"); you
dontneedtousethevalueattributetospecifythenameofthebeantobeautowired.
The following example listing shows usage of @Qualifier annotation at method-parameter-level and
constructor-argument-level:
Examplelisting6-11–@Qualifierusageatmethod-parameter-levelandconstructor-argument-level
publicclassSample{

@Autowired
publicSample(@Qualifier("aBean")ABeanbean){....}
@Autowired
publicvoiddoSomething(@Qualifier("bBean")BBeanbean,CBeancBean){.....}
}
Intheaboveexamplelisting,@Qualifierannotationisspecifiedforaconstructorargumentandamethod
argument.WhencreatinganinstanceofSampleclass,SpringfindsabeanoftypeABeanwithnameaBean
and passes it as an argument to the Sample classs constructor. When calling Samples doSomething
method,SpringfindsabeanoftypeBBean(whosenameisbBean)andanotherbeanoftypeCBean,and
passesboththesebeansasargumentstothedoSomethingmethod.ItisimportanttonotethattheBBean
dependencyisautowiredbyname,andCBeandependencyisautowiredbytype.
Lets now look at JSR 330’s @Inject and @Named annotations that you can use instead of Springs
@Autowiredand@Qualifierannotations.
6-5JSR330’s@Injectand@Namedannotations
JSR 330 (Dependency Injection for Java) standardizes dependency injection annotations for the Java
platform.JSR330defines@Injectand@NamedannotationsthataresimilartoSprings@Autowiredand
@Qualifierannotations,respectively.Springprovidessupportfor@Injectand@Namedannotations.
IMPORTchapter6/ch06-bankapp-jsr330(This project shows theMyBankapplication that uses JSR
330’s@Injectand@Namedannotationsforautowiringdependencies.Toruntheapplication,executethe
mainmethodoftheBankAppclassofthisproject.)
The following example listing shows the FixedDepositServiceImpl class that makes use of JSR 330’s
@Injectand@Namedannotations:
Examplelisting6-12–FixedDepositServiceImplclass
Project–ch06-bankapp-jsr330
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
importjavax.inject.Inject;
importjavax.inject.Named;
@Named(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{

@Inject
@Named(value="myFixedDepositDao")
privateFixedDepositDaomyFixedDepositDao;
.....
}
If you compare the FixedDepositServiceImpl class shown in the above example listing with the
FixedDepositServiceImplclassinexamplelisting6-10,youllnoticethatJSR330’s@Namedannotation
hasbeenusedinplaceof@Serviceand@Qualifierannotations,andJSR330’s@Injectannotationhas
beenusedinplaceof@Autowiredannotation.
@Autowired and @Inject annotations have the same semantics; they are used for autowiring
dependenciesbytype.Like@Autowiredannotation,@Inject can beused atmethod-level, constructor-
level and field-level. Dependency injection of constructors is performed first, followed by fields, and
then methods. We saw earlier that @Autowired annotations required attribute specifies whether it is
mandatory or optional to autowire dependencies. @Inject doesn’t have any equivalent of @Autowired
annotationsrequiredattribute.
If@Named annotation is used at the type-level, it acts like Springs @Component annotation. And, if
@Named annotation is used at the method-parameter-level or constructor-argument-level, it acts like
Springs @Qualifier annotation. If a class is annotated with @Named annotation, <component-scan>
element of Springs context schema treats it like a component class annotated with @Component
annotation.
To use @Named and @Inject annotations, you need to include JSR 330 JAR file in your project. The
ch06-bankapp-jsr330projectincludesJSR330JARfilethroughthefollowing<dependency>elementin
thepom.xmlfile:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
In chapter 5, we looked at JSR 250’s @PostConstruct and @PreDestroy annotations that are used to
identify initialization and destruction methods of a bean. Lets now look at JSR 250’s @Resource
annotationthatyoucanuseforautowiringdependenciesbyname.
6-6JSR250’s@Resourceannotation
Spring supports autowiring ‘by name’ of fields and methods via JSR 250’s @Resource annotation.
@Resourceannotationsnameattributespecifiesthenameofthebeantobeautowired.Itisimportantto
notethatyoucan’tuse@Resourceannotationforautowiringconstructorarguments.
ThefollowingexamplelistingshowshowFixedDepositServiceImplclassfromexamplelisting6-12can
berewrittenusing@Resourceannotation:
Examplelisting6-13–@Resourceannotationusageatfield-level
importjavax.annotation.Resource;
@Named(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{

@Resource(name="myFixedDepositDao")
privateFixedDepositDaomyFixedDepositDao;
.....
}
In the aboveexample listing,@Resource annotation has been used for autowiring myFixedDepositDao
field. As the value of name attribute is myFixedDepositDao, Spring locates a bean named
myFixedDepositDaointheSpringcontainerandassignsittomyFixedDepositDaofield.
Instead of using @Autowired and @Qualifier annotations, you should use @Resource annotation for
autowiring dependencies ‘by name’. As mentioned earlier, if you are using @Autowired-@Qualifier
combinationtoperformautowiringbyname’,Springfirstfindsbeansbasedonthetypeofthefield(or
thetypeofthemethodargumentorconstructorargument)tobeautowired,followedbynarrowingdownto
a unique bean based on the bean name specified by @Qualifier annotation. But, if you are using
@Resource annotation, Spring uses bean name specified by @Resource annotation to locate a unique
bean.Thismeansthatwhenyouuse@Resourceannotation,typeofthefield(orsettermethodargument)
tobeautowiredisnottakenintoconsiderationbySpring.
NOTEAs@Autowired,@Injectand@ResourceannotationsareprocessedbyBeanPostProcessors,you
should not use these annotations in component classes that implement BeanFactoryPostProcessor or
BeanPostProcessorinterface.
Letsnowlookat@Scope,@Lazy,@DependsOnand@Primaryannotations.
6-7@Scope,@Lazy,@DependsOnand@Primaryannotations
Youspecifythescope(prototypeorsingleton)ofaSpringcomponentusingSprings@Scopeannotation.
By default, Spring components are singleton-scoped. If you want a Spring component to be prototype-
scoped, you have to specify so via @Scopeannotation. @Scope annotation plays the same role as the
<bean>element’sscopeattribute(refersection2-5ofchapter2toknowmoreaboutthescopeattribute).
ThefollowingexamplelistingshowstheCustomerRequestDetailsclassthatuses@Scopeannotation:
Examplelisting6-14–@Scopeannotationusage
Project–ch06-bankapp-jsr330
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/domain
packagesample.spring.chapter06.bankapp.domain;
importjavax.inject.Named;
importorg.springframework.beans.factory.config.ConfigurableBeanFactory;
importorg.springframework.context.annotation.Scope;
@Named(value="customerRequestDetails")
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
publicclassCustomerRequestDetails{.....}
The@Scopeannotationacceptsavalueattributethatspecifiesthescopeofthecomponent.Youcanset
valueattribute’svaluetoprototypeorsingletontoindicatewhetherthecomponentissingleton-scopedor
prototype-scoped, or you can set value attribute’s value to ConfigurableBeanFactorys
SCOPE_SINGLETON(valueissingleton)orSCOPE_PROTOTYPE(valueisprototype)constants.
Bydefault,singleton-scopedSpringcomponentsareeagerlyinitialized,thatis,theyareinstantiatedwhen
theSpringcontaineriscreated.Ifyouwantasingleton-scopedcomponenttobelazilycreated,annotate
thecomponentclassofasingleton-scopedcomponentwith@Lazyannotation.
NOTE @Lazy annotation serves the same purpose as the <bean> elements lazy-init
attribute.Refersection2-5ofchapter2toknowmoreaboutlazy-initattribute.
Thefollowingexamplelistingshowsusageof@Lazyannotation:
Examplelisting6-15–@Lazyannotationusage
@Lazy(value=true)
@Component
publicclassSample{.....}
@Lazyannotationsvalueattributespecifieswhetherthecomponentislazilyoreagerlyinitialized.Ifthe
valueattribute’svalueistrue,itmeansthatthecomponentislazilyinitialized.
You specify implicit bean dependencies using @DependsOn annotation. The following example listing
showsusageof@DependsOnannotation:
Examplelisting6-16–@DependsOnannotationusage
@DependsOn(value={"beanA","beanB"})
@Component
publicclassSample{.....}
Intheaboveexamplelisting,@DependsOnannotationontheSampleclassinstructstheSpringcontainer
tocreatebeanAandbeanBbeansbeforecreatinganinstanceofSampleclass.
NOTE@DependsOnannotationservesthesamepurposeasthe<bean>element’sdepends-onattribute.
Refersection4-3ofchapter4toknowmoreaboutdepends-onattribute.
Ifmultipleautowiringcandidatesareavailableforadependency,@Primaryannotationdesignatesabean
as a primary candidate for autowiring. The following example listing shows usage of @Primary
annotation:
Examplelisting6-17–@Primaryannotationusage
@Primary
@Component
publicclassSample{.....}
NOTE@Primaryannotationservesthesamepurposeasthe<bean>element’sprimaryattribute.Refer
section4-6ofchapter4toknowmoreaboutprimaryattribute.
LetsnowlookatSprings@Valueannotationthatsimplifiesconfiguringcomponentclasses.
6-8Simplifyingcomponentconfigurationusing@Valueannotation
In previous chapters, we saw examples in which configuration information required by beans was
specifiedviavalueattributeof<property>and<constructor-arg>elements.AsSpringcomponentsarenot
defined in the application context XML file, Springs @Value annotation is used to serve the same
purpose as the value attribute of <property>and <constructor-arg> elements. You should note that the
@Value annotation can be used at field-level, method-level, method-parameter-level and constructor-
argument-level.
IMPORT chapter 6/ch06-value-annotation (This project shows an application that uses Springs
@ValueannotationtoconfigureSpringcomponents.Toruntheapplication,executethemainmethodofthe
SampleAppclassofthisproject.)
Thefollowingexamplelistingshowsanexampleusageof@Valueannotationatfield-level:
Examplelisting6-18–Sampleclass-@Valueannotationusage
Project–ch06-value-annotation
Sourcelocation-src/main/java/sample/spring/chapter06/beans
packagesample.spring.chapter06.beans;
importorg.springframework.beans.factory.annotation.Value;
@Component(value="sample")
publicclassSample{
@Value("Somecurrency")
privateStringcurrency;
.....
}
In the above example listing, currency field is annotated with @Value annotation. The @Value
annotationsvalue attribute specifies the default value for the field. It is optional to specify the value
attribute;therefore,@Value(value="Somecurrency")issameas@Value("Somecurrency").
YoucanalsouseaSpringExpressionLanguage(SpEL)expressionasthevalueof@Valueannotation.
SpEL is anexpression language that you can use to query and manipulate objects at runtime. The
followingexamplelistingshows@ValueannotationsthatmakeuseofSpELexpressions:
Examplelisting6-19–Sampleclass-@ValueannotationthatusesSpELexpressions
Project–ch06-value-annotation
Sourcelocation-src/main/java/sample/spring/chapter06/beans
packagesample.spring.chapter06.beans;
importorg.springframework.beans.factory.annotation.Value;
@Component(value="sample")
publicclassSample{
@Value("#{configuration.environment}")
privateStringenvironment;
.....
@Value("#{configuration.getCountry()}")
privateStringcountry;
@Value("#{configuration.state}")
privateStringstate;
.....
}
The above example listing shows that the @Value annotation specifies a value that has the syntax #
{<spel-expression>}. The SpEL expression specified by @Value annotation is processed by a
BeanPostProcessor.TheSpELexpressionscanmakeuseof<beanName>.<fieldorpropertyormethod>
formattoobtainitsvalue.Forinstance,#{configuration.environment}meansobtainvalueofenvironment
property of bean named configuration, and #{configuration.getCountry()} means invoke getCountry
methodofbeannamedconfiguration.
The following example listing shows the Java class of the configuration bean referenced by SpEL
expressionsshowninexamplelisting6-19:
Examplelisting6-20–Configurationcomponentclass
Project–ch06-value-annotation
Sourcelocation-src/main/java/sample/spring/chapter06/beans
packagesample.spring.chapter06.beans;
importorg.springframework.stereotype.Component;
@Component("configuration")
publicclassConfiguration{
publicstaticStringenvironment="DEV";
publicStringgetCountry(){
return"Somecountry";
}
publicStringgetState(){
return"Somestate";
}
publicString[]splitName(Stringname){
returnname.split("");
}
publicStringgetCity(){
return"Somecity";
}
}
TheaboveexamplelistingshowsthattheConfigurationclassrepresentsaSpringcomponentthatdefines
fields and methods. If you compare example listing 6-19 with 6-20, youll notice that #
{configuration.environment} expression refers to the static environment variable defined in the
Configuration class, #{configuration.getCountry()} expression refers to Configurations getCountry
method,and#{configuration.state}expressionreferstoConfigurationsgetStatemethod.
ThemainmethodofSampleAppclassinch06-value-annotationprojectretrievesaninstanceofSample
beanfromtheApplicationContextandprintsthevalueofvariousattributesofSamplebeaninstance.If
youexecuteSampleApp’smainmethod,youllseethefollowingoutput:
Sample[environment=DEV,currency=Somecurrency,country=Somecountry,state=Somestate,splitName=[FirstName,LastName],
city=Somecity]
Theaboveoutputshows:
·        #{configuration.environment} expression results in Sample’senvironment field value set to
DEV,whichisthevaluespecifiedbypublicstaticfieldenvironmentofConfigurationclass.
·#{configuration.getCountry()}expressionresultsinSample’scountryfieldvaluesettoSome
country,whichisthevaluereturnedbyinvokingConfigurationsgetCountrymethod.
·#{configuration.state}expressionresultsinSample’sstatefieldvaluesettoSomestate,whichis
thevaluereturnedbyinvokingConfigurationsgetStatemethod.
TheaboveexampleshowsthatyoucanuseSpELtoretrieveconfigurationinformationfromotherbeans.
NOTESpELisaverypowerfulexpressionlanguage,anditoffersmanymorecapabilitiesthandescribed
inthisbook.ItisrecommendedthatyourefertoSpringreferencedocumentationtoknowaboutSpEL.
Thefollowingexamplelistingshowsusageof@Valueannotationatmethod-levelandmethod-parameter-
level:
Examplelisting6-21–Sampleclass-@Valueannotationusageatmethod-levelandmethod-parameter-
level
Project–ch06-value-annotation
Sourcelocation-src/main/java/sample/spring/chapter06/beans
packagesample.spring.chapter06.beans;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.beans.factory.annotation.Value;
@Component(value="sample")
publicclassSample{
.....
privateString[]splitName;
privateStringcity;
@Autowired
publicvoidsplitName(@Value("#{configuration.splitName(FirstNameLastName')}")
String[]splitName){
this.splitName=splitName;
}
@Autowired
@Value("#{configuration.getCity()}")
publicvoidcity(Stringcity){
this.city=city;
}
.....
}
Theaboveexamplelistingshowsthatthemethodsthatareannotatedwith@Autowiredannotationmake
useof@Valueannotationatmethod-levelandmethod-parameter-level.Youshouldnotethatthe@Value
annotationcanbeusedatmethod-levelandmethod-parameter-levelonlyifthemethodisannotatedwith
@Autowired or @Resource or @Inject annotation. SpEL expression #
{configuration.splitName('FirstName LastName')} results in invocation of Configurations splitName
methodwith‘FirstNameLastNameasargument.ThisshowsthatSpELexpressionscanbeusedtoinvoke
methodsthatacceptarguments.
NOTE@ValueannotationisprocessedbyaBeanPostProcessor;therefore,youshouldnotuse@Value
annotation in component classes that implement BeanFactoryPostProcessor or BeanPostProcessor
interface.
UsageofSpELisnotlimitedto@Valueannotations,youcanalsouseSpELinbeandefinitionscontained
intheapplicationcontextXMLfile.
IMPORTchapter6/ch06-spel-example(ThisprojectshowsanapplicationthatusesSpELexpressions
in bean definitions. To run the application, execute the main method of the SampleApp class of this
project.)
ThefollowingexamplelistingshowshowSpELisusedinbeandefinitions:
Examplelisting6-22–applicationContext.xml–SpELexpressionsinbeandefinitions
Project–ch06-spel-example
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
<beanid="sample"class="sample.spring.chapter06.beans.Sample">
<propertyname="environment"value="#{configuration.environment}"/>
<propertyname="currency"value="Somecurrency"/>
<propertyname="country"value="#{configuration.getCountry()}"/>
<propertyname="state"value="#{configuration.state}"/>
</bean>
<beanid="configuration"class="sample.spring.chapter06.beans.Configuration"/>
</beans>
The above example listing shows that the bean definition for the Sample class makes use of SpEL
expressions(thatrefertoConfigurationbean)tosetdefaultvaluesforenvironment,currency,countryand
stateproperties.
Lets now look at how you can perform validation of objects in Spring applications using Springs
Validatorinterface.
6-9ValidatingobjectsusingSpring’sValidatorinterface
SpringsValidator interface is part of Spring Validation API that allows you to perform validation of
objects.YoucanusetheValidatorinterfaceforperformingvalidationofobjectsinanyoftheapplication
layers.Forinstance,youcanusetheValidatorinterfacetovalidateobjectsintheweblayeraswellasin
thepersistencelayer.
NOTEAnalternativetousingtheValidatorinterfaceistouseJSR303annotationstospecifyconstraints
thatapplyonanobject.JSR303annotationsareexplainedinthenextsection.
IMPORT chapter 6/ch06-validator-interface (This project shows the MyBank application that uses
SpringsValidatorinterfacetovalidateFixedDepositDetailsobject. Torun theapplication, execute the
mainmethodoftheBankAppclassofthisproject.)
The FixedDepositDetails object of MyBank application represents details of a fixed deposit. The
followingexamplelistingshowstheFixedDepositDetailsclass:
Examplelisting6-23–FixedDepositDetailsclass
Project–ch06-validator-interface
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/domain
packagesample.spring.chapter06.bankapp.domain;
publicclassFixedDepositDetails{
privatelongid;
privatefloatdepositAmount;
privateinttenure;
privateStringemail;
publicFixedDepositDetails(longid,floatdepositAmount,inttenure,
Stringemail){
this.id=id;
this.depositAmount=depositAmount;
this.tenure=tenure;
this.email=email;
}
.....
//--gettersandsettersforinstancevariables
publicfloatgetDepositAmount(){
returndepositAmount;
}
…..
}
The above example listing shows thattheFixedDepositDetails class defines id,depositAmount, tenure
andemailinstancevariables.Letssaythatbeforethefixeddepositdetailsaresavedinthesystem,we
needtomakesurethatthefixeddepositamount(representedbythedepositAmountinstancevariable)is
not0.
To validate the FixedDepositDetails object’s depositAmount property, we need to create an
implementation of Springs Validator interface. The following example listing shows a validator for
objectsoftypeFixedDepositDetails:
Examplelisting6-24–FixedDepositValidatorclass–SpringsValidatorinterfaceimplementation
Project–ch06-validator-interface
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/validator
packagesample.spring.chapter06.bankapp.validator;
importorg.springframework.validation.Errors;
importorg.springframework.validation.Validator;
publicclassFixedDepositValidatorimplementsValidator{
@Override
publicbooleansupports(Class<?>clazz){
returnFixedDepositDetails.class.isAssignableFrom(clazz);
}
@Override
publicvoidvalidate(Objecttarget,Errorserrors){
FixedDepositDetailsfixedDepositDetails=(FixedDepositDetails)target;
if(fixedDepositDetails.getDepositAmount()==0){
errors.reject("zeroDepositAmount");
}
}
}
The Validator interface defines supports and validate methods. The supports method checks if the
supplied object instance (represented by the clazz attribute) can be validated. If the supports method
returns true, the validate method is used to validate the object. In the above example listing, the
FixedDepositValidator’s supports method checks if the supplied object instance is of type
FixedDepositDetails. If the supports method returns true, the FixedDepositValidator’s validate method
validates the object. The validate method accepts the object instance to be validated, and an Errors
instance.TheErrorsinstance’srejectmethodisusedtostoreerrorsthatoccurduringvalidation.Youcan
laterinspecttheErrorsinstancetoknowmoreaboutvalidationerrors.
The following example listing shows that the FixedDepositServiceImpls createFixedDeposit method
usestheFixedDepositValidator(referexamplelisting6-24)tovalidateFixedDepositDetailsobjects:
Examplelisting6-25–FixedDepositServiceImplclass–ValidatingFixedDepositDetailsobject
Project–ch06-validator-interface
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
importorg.springframework.validation.BeanPropertyBindingResult;
importsample.spring.chapter06.bankapp.validator.FixedDepositValidator;
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{
@Autowired
@Qualifier(value="myFixedDepositDao")
privateFixedDepositDaomyFixedDepositDao;

@Override
publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{
BeanPropertyBindingResultbindingResult=
newBeanPropertyBindingResult(fixedDepositDetails,"Errors");
FixedDepositValidatorvalidator=newFixedDepositValidator();
validator.validate(fixedDepositDetails,bindingResult);
if(bindingResult.getErrorCount()>0){
logger.error("ErrorswerefoundwhilevalidatingFixedDepositDetailsinstance");
}else{
myFixedDepositDao.createFixedDeposit(fixedDepositDetails);
logger.info("Createdfixeddeposit");
}
}
}
FixedDepositServiceImpls createFixedDeposit method validates the FixedDepositDetails object
(representedbyfixedDepositDetailsargument)beforeitissavedintothedatastorebyFixedDepositDao.
ThecreateFixedDepositmethodshownintheaboveexamplelistingperformsthefollowingtasks:
·        creates an instance of FixedDepositValidator and Springs BeanPropertyBindingResult - a
defaultimplementationofErrorsinterfaceprovidedout-of-the-boxbySpring
·invokesFixedDepositValidator’svalidatemethod,passingFixedDepositDetailsobjectandthe
BeanPropertyBindingResultinstance
·invokesBeanPropertyBindingResultsgetErrorCountmethodtocheckifanyvalidationerrors
werereported.Ifnovalidationerrorsarereported,FixedDepositDao’screateFixedDepositmethod
iscalledtosavefixeddepositdetailsinthedatastore.
The following example listing shows BankApp’smain method that invokes FixedDepositServiceImpls
createFixedDepositmethod(referexamplelisting6-25)tocheckifthevalidationisperformedcorrectly
byFixedDepositValidator’svalidatemethod:
Examplelisting6-26–BankAppclass
Project–ch06-validator-interface
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp
packagesample.spring.chapter06.bankapp;
publicclassBankApp{
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,0,
12,"someemail@somedomain.com"));
FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,
12,"someemail@somedomain.com"));
}
}
First, FixedDepositServices createFixedDeposit method is passed a FixedDepositDetails object with
depositAmountvalueas0,followedbyaFixedDepositDetailsobjectwithdepositAmountvalueas1000.
IfyouexecuteBankApp’smainmethod,youllseethefollowingoutputontheconsole:
ErrorswerefoundwhilevalidatingFixedDepositDetailsinstance
Createdfixeddeposit
The output ‘Errors were found while validating FixedDepositDetails instance shows that
FixedDepositValidator reported errors when the FixedDepositDetails instance with 0 as the
depositAmountvaluewasvalidated.Theoutput‘Createdfixeddepositshowsthatthenoerrorswere
reportedwhentheFixedDepositDetailsinstancewith1000asthedepositAmountvaluewasvalidated.
NOTE Springs Validator interface is typically used in Spring MVC based web applications while
bindinginformationenteredbyauserintheHTMLformtothecorrespondingform-backingobject.
LetsnowlookathowyoucanspecifyconstraintsonbeanpropertiesusingJSR303annotations,andlet
Springperformthevalidation.
6-10SpecifyingconstraintsusingJSR303annotations
JSR 303 (Bean Validation API) allows you to use annotations to specify constraints on JavaBeans
components.WhenusingJSR303withSpring,youannotatebeanpropertieswithJSR303annotations,
andSpringtakescareofvalidatingthebeanandprovidingthevalidationresult.
IMPORTchapter6/ch06-jsr303-validation(ThisprojectshowstheMyBankapplicationthatusesJSR
303annotations.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject.)
The following example listing shows the FixedDepositDetails class that makes use of JSR 303
annotations:
Examplelisting6-27–FixedDepositDetailsclass–JSR303annotations
Project–ch06-jsr303-validation
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/domain
packagesample.spring.chapter06.bankapp.domain;
importjavax.validation.constraints.*;
importorg.hibernate.validator.constraints.NotBlank;
publicclassFixedDepositDetails{
@NotNull
privatelongid;

@Min(1000)
@Max(500000)
privatefloatdepositAmount;

@Min(6)
privateinttenure;

@NotBlank
@Size(min=5,max=100)
privateStringemail;
publicFixedDepositDetails(longid,floatdepositAmount,inttenure,Stringemail){
this.id=id;
this.depositAmount=depositAmount;
this.tenure=tenure;
this.email=email;
}
.....
}
@NotNull,@Min,@Max,@NotBlankand@SizearesomeoftheannotationsdefinedbyJSR303Bean
ValidationAPI.TheaboveexamplelistingshowsthatbyusingJSR303annotationsFixedDepositDetails
classclearlyspecifiestheconstraintsthatapplyonitsfields.Ontheotherhand,ifyouareusingSpring
ValidationAPItovalidateanobject,constraintinformationiscontainedintheValidatorimplementation
(referexamplelisting6-24).
The following table describes the constraints enforced by JSR 303 annotations on the
FixedDepositDetailsobjectshowninexamplelisting6-27:
JSR303annotation Constraintdescription
@NotNull
Theannotatedfieldmustnotbenull.
Forinstance,FixedDepositDetails’idfieldmustnotbenull.
@Min
Theannotatedfield’svaluemustbegreaterthanorequaltothespecifiedminimumvalue.
Forinstance,@M in(1000)annotationondepositAmountfieldofFixedDepositDetailsobject
meansthatdepositAmountsvaluemustbegreaterthanorequalto1000.
@Max
Theannotatedfield’svaluemustbelessthanorequaltothespecifiedvalue.
For instance, @Max(500000) annotation on depositAmount field of FixedDepositDetails
objectmeansthatthedepositAmountsvaluemustbelessthanorequalto500000.
@NotBlank Theannotatedfield’svaluemustnotbenullorempty.
Forinstance,FixedDepositDetails’emailfieldmustnotbeemptyornull.
@Size
Theannotatedfield’ssizemustbebetweenthespecifiedminandmaxattributes.
Forinstance,@Size(min=5,max=100)annotationonemailfieldofFixedDepositDetailsobject
meansthatthesizeoftheemailfieldmustbegreaterthanorequalto5andlessthanorequal
to100.
NOTETouseJSR303annotations,ch06-jsr303-validationprojectspecifiesdependencyonJSR303
APIJARfile(validation-api-1.0.0.GA)andHibernateValidatorframework(hibernate-validation-
4.3.0.Final).TheHibernateValidatorframeworkprovidesthereferenceimplementationforJSR303.
Ifyoulookattheimportstatementsinexamplelisting6-27,youllnoticethatthe@NotBlankannotationis
definedbyHibernateValidatorframework,andnotbyJSR303.HibernateValidatorframeworkprovides
additionalannotationsthatyoucanusealongwithJSR303annotations.
Now, that we have specified JSR 303 constraints on FixedDepositDetails class, lets look at how to
validateFixedDepositDetailsobjectusingSpring.
JSR303supportinSpring
Spring supports validating objects that make use of JSR 303 constraints. Springs
LocalValidatorFactoryBeanclass isresponsiblefordetectingthepresenceofaJSR303provider(like
Hibernate Validator) in the applications classpath and initializing it. It is important to note that the
LocalValidatorFactoryBean implements JSR 303’s Validator and ValidatorFactory interfaces, and also
SpringsValidatorinterface.
The following example listing shows the configuration of LocalValidatorFactoryBean class in the
applicationcontextXMLfile:
Examplelisting6-28–applicationContext.xml–SpringsLocalValidatorFactoryBeanconfiguration
Project–ch06-jsr303-validation
Sourcelocation-src/main/resources/META-INF/spring
<beanid="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
Asyoucansee,LocalValidatorFactoryBeanisconfiguredlikeanyotherSpringbean.Nowthatwehave
configuredLocalValidatorFactoryBean,letsseehowitisusedtoperformvalidation.
The following example listing shows the FixedDepositServiceImpl class which requires that the
FixedDepositDetailsobjectisvalidatedbeforefixeddepositdetailsaresavedinthedatastore:
Examplelisting6-29–FixedDepositServiceImplclass–validatingFixedDepositDetailsobject
Project–ch06-jsr303-validation
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
importorg.springframework.validation.BeanPropertyBindingResult;
importorg.springframework.validation.Validator;
.....
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{

@Autowired
privateValidatorvalidator;
@Autowired
@Qualifier(value="myFixedDepositDao")
privateFixedDepositDaomyFixedDepositDao;
@Override
publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{
BeanPropertyBindingResultbindingResult=
newBeanPropertyBindingResult(fixedDepositDetails,"Errors");
validator.validate(fixedDepositDetails,bindingResult);

if(bindingResult.getErrorCount()>0){
logger.error("ErrorswerefoundwhilevalidatingFixedDepositDetailsinstance");
}else{
myFixedDepositDao.createFixedDeposit(fixedDepositDetails);
logger.info("Createdfixeddeposit");
}
}
}
Theaboveexamplelistingshows thatSprings Validatorimplementationisreferencedbythevalidator
field. As LocalValidatorFactoryBean implements Springs Validator interface,
LocalValidatorFactoryBean instance is assigned to the validator field. FixedDepositServiceImpls
createFixedDeposit method invokes Validator’s validate method to perform validation of
FixedDepositDetailsobject.
Oneoftheinterestingthingstonoticeinexamplelisting6-29isthatwearenotdealingwithJSR303API
to perform validation of FixedDepositDetails object. Instead, we have used Spring Validation API to
performvalidation.ThisispossiblebecauseLocalValidatorFactoryBeanimplementsvalidatemethodof
SpringsValidatorinterfacetouseJSR303APItoperformvalidationofobjects,shieldingdevelopers
fromJSR303-specificAPIdetails.
As LocalValidatorFactoryBean implements JSR 303’s Validator and ValidatorFactory interfaces, you
havetheoptiontouseJSR303APItoperformvalidationofFixedDepositDetailsobject.Thefollowing
examplelistingshowsanalternativeimplementationofFixedDepositServiceImplclassthatmakesuseof
JSR303’sValidatortoperformvalidation:
Examplelisting6-30–FixedDepositServiceImplJsr303class-validatingFixedDepositDetailsobject
Project–ch06-jsr303-validation
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service
packagesample.spring.chapter06.bankapp.service;
importjavax.validation.ConstraintViolation;
importjavax.validation.Validator;
@Service(value="FixedDepositServiceJsr303")
publicclassFixedDepositServiceJsr303ImplimplementsFixedDepositService{
.....
@Autowired
privateValidatorvalidator;
@Autowired
@Qualifier(value="myFixedDepositDao")
privateFixedDepositDaomyFixedDepositDao;
@Override
publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{
Set<ConstraintViolation<FixedDepositDetails>>violations=
validator.validate(fixedDepositDetails);
Iterator<ConstraintViolation<FixedDepositDetails>>itr=violations.iterator();
if(itr.hasNext()){
logger.error("ErrorswerefoundwhilevalidatingFixedDepositDetailsinstance");
}else{
myFixedDepositDao.createFixedDeposit(fixedDepositDetails);
logger.info("Createdfixeddeposit");
}
}
}
TheaboveexamplelistingshowsthatJSR303’sValidatorimplementationisreferencedbythevalidator
field. As LocalValidatorFactoryBean implements JSR 303’s Validator interface,
LocalValidatorFactoryBean instance is assigned to the validator field. The createFixedDeposit method
validatesFixedDepositDetailsobjectbycallingValidatorsvalidatemethod.Thevalidatemethodreturns
ajava.util.SetobjectthatcontainstheconstraintviolationsreportedbyJSR303provider.Youcancheck
thejava.util.Setobjectreturnedbythevalidatemethodtoknowifanyconstraintviolationswerereported.
For instance, in the above example listing, the createFixedDeposit method calls FixedDepositDao’s
createFixedDepositmethodonlyifjava.util.Setdoesn’tcontainanyconstraintviolations.
Inthissection,wesawhowtouseSpringssupportforJSR303toperformvalidationofobjects.Weonly
lookedatconstraints,like@NotNull,@Size,andsoon,thatareprovidedout-of-the-boxbyJSR303.Itis
importanttonotethatJSR303allowsyoutocreatecustomconstraintsandusetheminyourapplication.
Forinstance,youcancreatea@MyConstraintcustomconstraintandacorrespondingvalidatortoenforce
thatconstraintonobjects.
LetsnowlookatannotationsthatyoucanusetoprogrammaticallyconfigureSpringbeans.
6-11 Programmatically configuring Spring beans using
@Configurationand@Beanannotations
Youcanuse@Configurationand@BeanannotationstoprogrammaticallyconfigureSpringbeans.Ifyou
annotate a class with @Configuration annotation, it indicates that the class contains @Bean annotated
methodsthatreturnbeaninstancesmeanttoberegisteredwiththeSpringcontainer.
NOTETouse@Configurationannotatedclassesfordefiningbeans,CGLIBlibraryisrequiredbecause
Springextends@Configurationannotatedclassestoaddbehaviortothe@Beanannotatedmethods.
StartingwithSpring3.2,theCGLIBclassesarepackagedwithinthespring-coreJARfileitself;therefore,
youdontneedtoexplicitlyspecifythatyourprojectisdependentonCGLIBJARfile.
IMPORTchapter6/ch06-bankapp-configuration(ThisprojectshowstheMyBankapplicationthatuses
@Configuration and @Bean annotations to programmatically configure beans. To run the application,
executethemainmethodoftheBankAppclassofthisproject.)
The following example listing shows the BankAppConfiguration class that is annotated with
@Configurationannotation:
Examplelisting6-31–BankAppConfigurationclass-@Configurationand@Beanannotations
Project–ch06-bankapp-configuration
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp
packagesample.spring.chapter06.bankapp;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.context.annotation.Scope;
.....
@Configuration
publicclassBankAppConfiguration{
.....
@Bean(name="customerRegistrationService")
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
publicCustomerRegistrationServicecustomerRegistrationService(){
returnnewCustomerRegistrationServiceImpl();
}
.....
}
BankAppConfigurationclassdefines@Beanannotatedmethodsthatreturnbeaninstances.@Beansname
attributespecifiesthenamewithwhichthereturnedbeaninstanceisregisteredwiththeSpringcontainer.
@Scopeannotationspecifiesthescope(singletonorprototype)ofthereturnedbeaninstance.
NOTE@Scope annotation is also used at the type-level to specify the scope of a Spring component.
Referexamplelisting6-14thatshowsusageof@Scopeannotationattype-level.
In example listing 6-31, the customerRegistrationService method returns an instance of
CustomerRegistrationServicebeanthatisregisteredwiththeSpringcontainerasaprototype-scopedbean
namedcustomerRegistrationService.ThecustomerRegistrationServicemethodhasthesameeffectasthe
followingbeandefinitionintheapplicationcontextXMLfile:
<beanid="customerRegistrationService"scope="prototype”
class="sample.spring.chapter06.bankapp.service.CustomerRegistrationServiceImpl"/>
Thefollowingtabledescribestheattributesof@Beanannotationthatyoucanusetoconfigurethebean
instance:
Valueoftypeattribute Description
Autowire
Sameas<bean>elementsautowireattribute(refersection4-6ofchapter4toknowmore
about autowire attribute). If the bean returned by the @Bean annotated method is
dependent on other beans, you can use autowire attribute to instruct Sp ring to p erform
autowiringofdependenciesbynameortype.
initM ethod Sameas<bean>elementsinit-method attribute (refer section 5-2 of chap ter 5 to know
moreaboutinit-methodattribute)
destroyMethod Same as <bean> elements destroy-method attribute (refer section 5-2 of chapter 5 to
knowmoreaboutdestroy-methodattribute)
Itisimportanttonotethat@Beanannotatedmethodsmayalsobeannotatedwith@Lazy,@DependsOn,
@Primaryand@Scopeannotations.Theseannotationsapplytotheobjectinstancereturnedbythe@Bean
annotatedmethod.Forinstance,@DependsOnannotationspecifiestheimplicitdependenciesoftheobject
instance returned by the @Bean annotated method. Also, if the bean instance returned by @Bean
annotated method implements lifecycle interfaces (like InitializingBean and DisposableBean), and
Springs*Aware interfaces (like ApplicationContextAware,BeanNameAware, and so on), itll receive
callbacksfromtheSpringcontainer.
In the examples that we have seen so far, we created an instance of ClassPathXmlApplicationContext
class (an implementation of ApplicationContext interface) to represent the Spring container. If you are
using an @Configuration annotated class as the source of beans, you need to create an instance of
AnnotationConfigApplicationContext class (another implementation of ApplicationContext interface) to
representtheSpringcontainer.
The following example listing shows the BankApp class that creates an instance of
AnnotationConfigApplicationContext class and retrieves beans from the newly created
AnnotationConfigApplicationContextinstance:
Examplelisting6-32–BankAppclass-AnnotationConfigApplicationContextusage
Project–ch06-bankapp-configuration
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp
packagesample.spring.chapter06.bankapp;
importorg.springframework.context.annotation.AnnotationConfigApplicationContext;
publicclassBankApp{
publicstaticvoidmain(Stringargs[])throwsException{
AnnotationConfigApplicationContextcontext=
newAnnotationConfigApplicationContext(BankAppConfiguration.class);
.....
FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,
12,"someemail@somedomain.com"));
.....
}
}
In the above example listing, the BankAppConfiguration class is passed as an argument to the
AnnotationConfigApplicationContexts constructor. As AnnotationConfigApplicationContext class
implementsApplicationContextinterface,youcanaccessregisteredbeansinthesamewayasincaseof
ClassPathXmlApplicationContext.
You should note that @Bean annotated methods can also be defined in @Component and JSR 330’s
@Named annotated classes.Incase you have definedbeans inmultiple@Configuration, @Component
and @Named annotated classes, pass all these classes to the AnnotationConfigApplicationContexts
constructor.
The following example listing shows @Bean annotated methods of BankAppConfiguration class that
returnaBeanFactoryPostProcessorandaBeanPostProcessorimplementation:
Example listing 6-33 – BankAppConfiguration class – defining BeanFactoryPostProcessor and
BeanPostProcessorbeans
Project–ch06-bankapp-configuration
Sourcelocation-src/main/java/sample/spring/chapter06/bankapp
packagesample.spring.chapter06.bankapp;
importorg.springframework.context.annotation.Bean;
@Configuration
publicclassBankAppConfiguration{
.....
@Bean
publicExampleBeanPostProcessorexampleBeanPostProcessor(){
returnnewExampleBeanPostProcessor();
}

@Bean
publicstaticBeanNamePrinterBeanFactoryPostProcessorapplicationConfigurer(){
returnnewBeanNamePrinterBeanFactoryPostProcessor();
}
}
In the aboveexample listing,ExampleBeanPostProcessor instance representsa BeanPostProcessor that
prints a message on the console before and after a newly created bean instance is initialized, and
BeanNamePrinterBeanFactoryPostProcessor instance represents a BeanFactoryPostProcessor
implementationthatprintsnamesofallthebeansregisteredwiththeSpringcontainer.
Ifyougotoch06-bankapp-configurationprojectandexecuteBankApp’smainmethod,youllnoticethat
theBeanNamePrinterBeanFactoryPostProcessor is invoked before any bean defined in @Configuration
annotatedclassiscreatedbytheSpringcontainer,andtheExampleBeanPostProcessor is invoked each
timeanewbeaninstanceiscreatedbytheSpringcontainer.Thisshowsthatwhetheryouconfigurebeans
declaratively (via application context XML file) or programmatically (via @Configuration annotated
class), beans that implement callback interfaces (like ApplicationContextAware, BeanNameAware,
InitializingBean, DisposableBean, BeanFactoryPostProcessor, and so on) receive callback from the
Springcontainer.
6-12Summary
ThischapterlookedatannotationsthatyoucanusetosimplifydevelopingSpringapplications.Welooked
at how to designate a bean class as a Spring component using Springs @Component, @Service,
@Repositoryand@Controllerannotations, perform classpathscanning toautomaticallyregister Spring
components with container, validate objects using Spring Validation API and JSR 303’s annotations,
performdependencyinjectionusingSprings@Autowired,JSR330’s@InjectandJSR250’s@Resource
annotations, anduse@Configurationand@Bean annotations to configure beans programmatically. The
nextchaptershowshowSpringsimplifiesinteractingwithdatabases.
Chapter7-DatabaseinteractionusingSpring
7-1Introduction
SpringsimplifiesinteractionwithdatabasesbyprovidingalayerofabstractionontopofJDBC.Spring
also simplifies using ORM (Object Relational Mapping) frameworks, like Hibernate
(http://www.hibernate.org/) and MyBatis (http://www.mybatis.org), for database interaction. In this
chapter, well look at examples that demonstrate how Spring simplifies developing applications that
interactwithdatabases.
NOTETheexamplesdescribedinthischaptermakeuseofHibernate4.Ifyouareusing
Hibernate 3, the changes that you’ll need to make to the configuration are specified at
relevantplaces.
We’llbeginthischapterbylookingatasampleapplicationthatusesSpringsJDBCabstractiontointeract
with MySQL database. After that, we well develop the same application using Springs support for
Hibernate framework. We’ll wrap this chapter by looking at Springs support for programmatic and
declarativetransactionmanagement.
LetsfirstlookattheMyBankapplicationsrequirementsthatwellbedevelopinginthischapter.
7-2MyBankapplicationsrequirements
MyBankapplicationisaninternetbankingapplicationthatallowsbankcustomerstocheckbankaccount
details, generate bank statement, create fixed deposits, request cheque book, and so on. The following
figure shows the BANK_ACCOUNT_DETAILSand FIXED_DEPOSIT_DETAILS tables in which
MyBankapplicationsdataisstored:
Figure7-1DatabasetablesusedbytheMyBankapplication
BANK_ACCOUNT_DETAILS table contains information about bank accounts, and
FIXED_DEPOSIT_DETAILS table contains information about fixed deposits. The above figure shows
that there is many-to-one relationship between FIXED_DEPOSIT_DETAILS and
BANK_ACCOUNT_DETAILS tables. When a bank customer opens a new fixed deposit, the fixed
deposit amount is deducted from the BANK_ACCOUNT_DETAILS tables BALANCE_AMOUNT
column,andthefixeddepositdetailsaresavedintheFIXED_DEPOSIT_DETAILStable.
ThecolumnsofBANK_ACCOUNT_DETAILStableare:
·ACCOUNT_ID–accountidentifierthatuniquelyidentifiesacustomersbankaccount.
·        BALANCE_AMOUNT – holds the current balance in the bank account. When a customer
requestsforopeningafixeddeposit,thefixeddepositamountisdeductedfromthiscolumn.
·LAST_TRANSACTION_TS–specifiesthedate/timewhenthelasttransactionwasperformed
onthisaccount.
ThecolumnsofFIXED_DEPOSIT_DETAILStableare:
·FIXED_DEPOSIT_ID–fixeddepositidentifierthatuniquelyidentifiesafixeddeposit.Whena
customeropensafixeddeposit,auniquefixeddepositidentifier isgeneratedby theMyBankfor
futurereferencebythecustomer.ThevalueofFIXED_DEPOSIT_IDcolumnisauto-generatedby
MySQLdatabase.
·ACCOUNT_ID–foreignkeythatidentifiesthebankaccountwithwhichthefixeddepositis
associated.Everyquarter,interestgeneratedbythefixeddepositiscreditedintothebankaccount
identifiedbythiscolumn.
·FD_CREATION_DATE–thedateonwhichthefixeddepositwascreated
·AMOUNT–fixeddepositamount
·TENURE–fixeddeposittenure(inmonths).Fixeddeposittenuremustbegreaterthanorequal
to12monthsandlessthanorequalto60months.
·ACTIVE–indicateswhetherthefixeddepositiscurrentlyactiveornot.Anactivefixeddeposit
generatesinterestonthefixeddepositamount.
LetsnowlookathowwecancreatetheMyBankapplicationusingSpringsJDBCmodule.
7-3DevelopingtheMyBankapplicationusingSpring’sJDBCmodule
SpringsJDBCmodulesimplifiesinteractionwithdatasourcesbytakingcareoflowerleveldetailsof
openingandclosingconnections,managingtransactions,processingexceptions,andsoon.Inthissection,
we’ll develop the MyBank application (as described in the previous section) using Springs JDBC
module. For the sake of simplicity, well develop only the services and DAOs that form part of the
MyBankapplication.
IMPORTchapter7/ch07-bankapp-jdbc(ThisprojectshowstheMyBankapplicationthatusesSprings
JDBC module to interact with the database. To run the application, execute the main method of the
BankAppclass of this project. Before executing BankApp’s main method, install MySQL database and
executethespring_bank_app_db.sqlSQLscriptcontainedinthesqlfolderofch07-bankapp-jdbcproject.
Executing spring_bank_app_db.sql script creates SPRING_BANK_APP_DB database and adds
BANK_ACCOUNT_DETAILS and FIXED_DEPOSIT_DETAILS tables to the
SPRING_BANK_APP_DB database. Also, modify the src/main/resources/META-
INF/spring/database.propertiesfiletopointtoyourMySQLinstallation.)
InMyBankapplication,youfirstneedtoconfigureajavax.sql.DataSourceobjectthatidentifiesthedata
sourcewithwhichtheMyBankapplicationinteracts,followedbyimplementingDAOsthatuseSprings
JDBCmoduleclassestointeractwiththedatasource.Let’slookateachofthesestepsindetail.
Configuringadatasource
If you are using Spring to develop a standalone application, you can configure the data source in the
application context XML file. If you are developing an enterprise application, you can define a data
source that is bound to the application servers JNDI, and retrieve the JNDI-bound data source in the
applicationcontextXMLfileforusebytheapplication.Incaseofch07-bankapp-jdbcproject,thedata
sourceisconfiguredintheapplicationcontextXMLfile.
The following example listing shows how MyBank applications data source is configured in the
applicationcontextXMLfile:
Examplelisting7-1–applicationContext.xml–datasourceconfiguration
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/resources/META-INF/spring
<context:property-placeholderlocation="classpath*:META-INF/spring/database.properties"/>
<beanid="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
<propertyname="driverClassName"value="${database.driverClassName}"/>
<propertyname="url"value="${database.url}"/>
<propertyname="username"value="${database.username}"/>
<propertyname="password"value="${database.password}"/>
</bean>
Intheaboveexamplelisting,the<property-placeholder>element(refersection5-4ofchapter5formore
details)ofSpringscontextschemaloadspropertiesfromtheMETA-INF/spring/database.propertiesfile
andmakesthemavailabletobeandefinitionsintheapplicationcontextXMLfile.ThedataSourcebean
representsajavax.sql.DataSourceobjectthatactsasafactoryforcreatingconnectionstothedatasource.
BasicDataSourceclassisan implementation of javax.sql.DataSource interfacethat supportsconnection
pooling feature. BasicDataSource class is part of Apache Commons DBCP project
(http://commons.apache.org/dbcp/) and supports database connection pooling feature. The values for
driverClassName, url, username and password properties of BasicDataSource class comes from the
propertiesdefinedinthedatabase.propertiesfile.TheclosemethodofBasicDataSourceclassclosesall
idle connections in the pool. As the bean definition for the BasicDataSource class specifies value of
destroy-methodattributeasclose,allidleconnectionsinthepoolareclosedwhenthedataSourcebean
instanceisdestroyedbytheSpringcontainer.
ConfiguringadatasourceinJavaEEenvironments
If you are developing an enterprise application that is deployed in an application server, you can use
Springsjeeschema’s<jndi-lookup>elementtomaketheJNDI-bounddatasourceavailableasaSpring
beanintheApplicationContext:
<jee:jndi-lookupjndi-name="java:comp/env/jdbc/bankAppDb"id="dataSource"/>
here,jndi-nameattributespecifiestheJNDInamewithwhichthejavax.sql.DataSourceobjectisboundto
theJNDI,andidattributespecifiesthenamewithwhichthejavax.sql.DataSourceobjectisregisteredas
abeanintheApplicationContext.
LetsnowlookatsomeoftheSpringsJDBCmoduleclassesthatyoucanuseinyourDAOstointeract
withthedatabase.
CreatingDAOsthatuseSpringsJDBCmoduleclasses
SpringsJDBCmoduledefinesmultipleclassesthatsimplifydatabaseinteraction.We’llfirstlookatthe
JdbcTemplateclassthatisattheheartofSpringsJDBCmodule.Theotherclassesthatwe’lldiscussin
this section are NamedParameterJdbcTemplate and SimpleJdbcInsert. To learn about other Springs
JDBCmoduleclasses,refertoSpringsreferencedocumentation.
JdbcTemplate
JdbcTemplateclasstakescareofmanagingConnection,StatementandResultSetobjects,catchingJDBC
exceptions and translating them into easily understandable exceptions (like
IncorrectResultSetColumnCountException and CannotGetJdbcConnectionException), performing batch
operations,andsoon.AnapplicationdeveloperonlyneedstoprovideSQLtotheJdbcTemplateclass,
andextractresultsaftertheSQLisexecuted.
AsJdbcTemplateactsasawrapperaroundjavax.sql.DataSourceobject,youdon’tneedtodirectlydeal
withajavax.sql.DataSourceobject.AJdbcTemplateinstanceistypicallyinitializedwithreferencetothe
javax.sql.DataSource object from which it needs to obtain connections, as shown in the following
examplelisting:
Examplelisting7-2–applicationContext.xml–JdbcTemplateconfiguration
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/resources/META-INF/spring
<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">
<propertyname="dataSource"ref="dataSource"/>
</bean>
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource".....>
.....
</bean>
TheaboveexamplelistingshowsthattheJdbcTemplateclassdefinesadataSourcepropertythatrefersto
ajavax.sql.DataSourceobject.
If your application uses a JNDI-bound data source, use the <jndi-lookup> element of jee schema to
registertheJNDI-bounddatasourceasabeanwiththeSpringcontainer.Now,thetheJdbcTemplateclass
can refer to the javax.sql.DataSource bean registered by the <jndi-lookup> element, as shown in the
followingexamplelisting:
Examplelisting7-3–JdbcTemplateconfigurationforJNDI-bounddatasource
<beans.....
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation=".....
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-4.0.xsd">

<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate">
<propertyname="dataSource"ref="dataSource"/>
</bean>

<jee:jndi-lookupjndi-name="java:comp/env/jdbc/bankAppDb"id="dataSource"/>
.....
</beans>
Intheaboveexamplelisting,referencetoSpringsjeeschemaisincludedintheapplicationcontextXML
file. The <jndi-lookup> element retrieves javax.sql.DataSource object from JNDI and exposes it as a
beannameddataSource,whichisreferencedbytheJdbcTemplateclass.
JdbcTemplateinstanceisthread-safe,whichmeansmultipleDAOsofyourapplicationcansharethesame
instance of JdbcTemplate class to interact with the database. The following example listing shows
FixedDepositDaoImplscreateFixedDepositmethodthatmakesuseofJdbcTemplatetosavefixeddeposit
detailsinthedatabase:
Examplelisting7-4–FixedDepositDaoImplclass–savingdatausingJdbcTemplate
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp/dao
packagesample.spring.chapter07.bankapp.dao;
importjava.sql.*;
importorg.springframework.jdbc.core.JdbcTemplate;
importorg.springframework.jdbc.core.PreparedStatementCreator;
importorg.springframework.jdbc.support.GeneratedKeyHolder;
importorg.springframework.jdbc.support.KeyHolder;
importorg.springframework.stereotype.Repository;
@Repository(value="FixedDepositDao")
publicclassFixedDepositDaoImplimplementsFixedDepositDao{
@Autowired
privateJdbcTemplatejdbcTemplate;
.....
publicintcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails){
finalStringsql=
"insertintofixed_deposit_details(account_id,fixedDeposit_creation_date,amount,
tenure,active)values(?,?,?,?,?)";
KeyHolderkeyHolder=newGeneratedKeyHolder();
jdbcTemplate.update(newPreparedStatementCreator(){
@Override
publicPreparedStatementcreatePreparedStatement(Connectioncon)
throwsSQLException{
PreparedStatementps=con.prepareStatement(sql,newString[]{
"fixed_deposit_id"});
ps.setInt(1,fixedDepositDetails.getBankAccountId());
ps.setDate(2,
newjava.sql.Date(fixedDepositDetails.getFixedDepositCreationDate().getTime()));
.....
returnps;
}
},keyHolder);
returnkeyHolder.getKey().intValue();
}
.....
}
In the above example listing, the FixedDepositDaoImpl class is annotated with Springs @Repository
annotationbecausetheFixedDepositDaoImplclassrepresentsaDAOclass.JdbcTemplateinstancethat
we configured in the application context XML file (refer example listing 7-2) is autowired into the
FixedDepositDaoImpl class. JdbcTemplate’s update method accepts an instance of
PreparedStatementCreator and an instance of KeyHolder. PreparedStatementCreator is used to perform
insert,updateordeleteoperationonthedatabase.SpringsKeyHolderinterfacerepresentsaholderfor
thekeysthatareauto-generatedwheninsertSQLstatementsareexecuted.GeneratedKeyHolderclassis
thedefaultimplementationofKeyHolderinterface.
Once the INSERT SQL statement is successfully executed, the auto-generated keys are added to the
GeneratedKeyHolderinstance.Youcanextracttheauto-generatedkeysfromtheGeneratedKeyHolderby
callingthe getKey method.In example listing 7-4, the createFixedDeposit method inserts fixed deposit
detailsintotheFIXED_DEPOSIT_DETAILStableandreturnstheauto-generatedkey.Examplelisting7-
4showsthatyoudon’tneedtoworryaboutcatchingSQLExceptionthatmaybethrownbytheexecution
of PreparedStatement. This is because JdbcTemplate is responsible for catching SQLExceptions and
handlingthem.
LetsnowlookatNamedParameterJdbcTemplateclass.
NamedParameterJdbcTemplate
Asshowninexamplelisting7-4,ifyouareusingJdbcTemplateclassfordatabaseinteraction,parameters
to be passed to the SQL statement are specified using? placeholders. Springs
NamedParameterJdbcTemplateisawrapperaroundJdbcTemplateinstancethatallowsyoutousenamed
parametersintheSQLstatementratherthanusing?.
ThefollowingexamplelistingshowshowtheNamedParameterJdbcTemplateclassisconfiguredinthe
applicationcontextXMLfile:
Examplelisting7-5–applicationContext.xml–NamedParameterJdbcTemplateconfiguration
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/resources/META-INF/spring
<beanid="namedJdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-argindex="0"ref="dataSource"/>
</bean>
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource".....>
.....
</bean>
The above example listing shows that the NamedParameterJdbcTemplate class accepts
javax.sql.DataSourceobjectasconstructorargument.
The following example listing shows the FixedDepositDaoImpl class that uses
NamedParameterJdbcTemplatetofetchfixeddepositdetailsfromtheFIXED_DEPOSIT_DETAILStable:
Examplelisting7-6–FixedDepositDaoImplclass–NamedParameterJdbcTemplateusage
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp/dao
packagesample.spring.chapter07.bankapp.dao;
importjava.sql.ResultSet;
importorg.springframework.jdbc.core.RowMapper;
importorg.springframework.jdbc.core.namedparam.MapSqlParameterSource;
importorg.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
importorg.springframework.jdbc.core.namedparam.SqlParameterSource;
.....
@Repository(value="FixedDepositDao")
publicclassFixedDepositDaoImplimplementsFixedDepositDao{
.....
@Autowired
privateNamedParameterJdbcTemplatenamedParameterJdbcTemplate;
.....
publicFixedDepositDetailsgetFixedDeposit(finalintFixedDepositId){
finalStringsql="select*fromfixed_deposit_detailswherefixed_deposit_id
=:FixedDepositId";
SqlParameterSourcenamedParameters=newMapSqlParameterSource(
"FixedDepositId",FixedDepositId);
returnnamedParameterJdbcTemplate.queryForObject(sql,namedParameters,
newRowMapper<FixedDepositDetails>(){
publicFixedDepositDetailsmapRow(ResultSetrs,introwNum)throwsSQLException{
FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();
fixedDepositDetails.setActive(rs.getString("active"));
.....
returnfixedDepositDetails;
}
});
}
}
NamedParameterJdbcTemplateinstance that we configured in the application context XML file (refer
examplelisting7-5)isautowiredintoFixedDepositDaoImplclass.Intheaboveexamplelisting,theSQL
query passed to NamedParameterJdbcTemplate’s queryForObject method contains a named parameter
FixedDepositId. The named parameter values are supplied via an implementation of Springs
SqlParameterSource interface. MapSqlParameterSource class is an implementation of
SqlParameterSourceinterfacethatstoresnamedparameters(andtheirvalues)inajava.util.Map.Inthe
above example listing, MapSqlParameterSource instance holds value of FixedDepositId named
parameter.NamedParameterJdbcTemplate’squeryForObjectmethodexecutesthesuppliedSQLqueryand
returnsasingleobject.SpringsRowMapperobjectisusedformappingeachreturnedrowtoanobject.
In the above example listing, RowMapper maps the returned row in the ResultSet to a
FixedDepositDetailsobject.
LetsnowlookatSpringsSimpleJdbcInsertclass.
SimpleJdbcInsert
SimpleJdbcInsertclassmakesuseofdatabasemetadatatosimplifycreatingabasicSQLinsertstatement
foratable.
ThefollowingexamplelistingshowstheBankAccountDaoImplclassthatmakesuseofSimpleJdbcInsert
toinsertbankaccountdetailsintoBANK_ACCOUNT_DETAILStable:
Examplelisting7-7–BankAccountDaoImplclass–SimpleJdbcInsertusage
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp/dao
packagesample.spring.chapter07.bankapp.dao;
importjavax.sql.DataSource;
importorg.springframework.jdbc.core.simple.SimpleJdbcInsert;
.....
@Repository(value="bankAccountDao")
publicclassBankAccountDaoImplimplementsBankAccountDao{
privateSimpleJdbcInsertinsertBankAccountDetail;
@Autowired
privatevoidsetDataSource(DataSourcedataSource){
this.insertBankAccountDetail=newSimpleJdbcInsert(dataSource)
.withTableName("bank_account_details")
.usingGeneratedKeyColumns("account_id");
}
@Override
publicintcreateBankAccount(finalBankAccountDetailsbankAccountDetails){
Map<String,Object>parameters=newHashMap<String,Object>(2);
parameters.put("balance_amount",bankAccountDetails.getBalanceAmount());
parameters.put("last_transaction_ts",newjava.sql.Date(
bankAccountDetails.getLastTransactionTimestamp().getTime()));
Numberkey=insertBankAccountDetail.executeAndReturnKey(parameters);
returnkey.intValue();
}
.....
}
AsthesetDataSourcemethodisannotatedwith@Autowiredannotation,javax.sql.DataSourceobjectis
passed as an argument to the setDataSource method. In the setDataSource method, an instance of
SimpleJdbcInsertiscreatedbypassingreferencetojavax.sql.DataSourceobjecttotheSimpleJdbcInsert
constructor.
SimpleJdbcInserts withTableName method sets the name of the table into which you want to insert
record(s). As we want to insert bank account details into BANK_ACCOUNT_DETAILS table,
‘bank_account_details’ string value is passed as argument to the withTableName method.
SimpleJdbcInserts usingGeneratedKeyColumns method sets names of table columns that contain auto-
generatedkeys.IncaseofBANK_ACCOUNT_DETAILStable,ACCOUNT_IDcolumncontainstheauto-
generatedkey;therefore,‘account_id’stringvalueispassedtotheusingGeneratedKeyColumnsmethod.
The actual insert operation is performed by calling SimpleJdbcInsert’s executeAndReturnKey method.
The executeAndReturnKey method accepts a java.util.Map type argument that contains table column
names and their corresponding values, and returns the generated key value. You should note that the
SimpleJdbcInsertclassinternallyusesJdbcTemplatetoexecutetheactualSQLinsertoperation.
IfyoulookatBankAccountDaoImplclassofch07-bankapp-jdbcproject,youllnoticethatitmakesuseof
both SimpleJdbcInsert and JdbcTemplate classes to interact with the database. Similarly,
FixedDepositDaoImpl class of ch07-bankapp-jdbc project uses both JdbcTemplate and
NamedParameterJdbcTemplate classes for database interaction. This shows that you can use a
combinationofSpringsJDBCmoduleclassestointeractwithadatabase.
NOTEAsch07-bankapp-jdbcprojectmakesuseofSpringsJDBCmoduleandusesSpringsTransaction
Managementfeature(explainedinsection7-5),thepom.xmlfileofch07-bankapp-jdbcprojectdepends
onspring-jdbcandspring-txJARfiles.
LetsnowlookatBankAppclassofch07-bankapp-jdbcprojectthatcreatesabankaccountandopensa
fixeddepositcorrespondingtoit.
BankAppclass
BankApp class of ch07-bankapp-jdbc project runs the MyBank application as a standalone Java
application.BankApp’smainmethodcreatesabankaccountintheBANK_ACCOUNT_DETAILStable
and creates a fixed deposit (corresponding to the newly created bank account) in the
FIXED_DEPOSIT_DETAILStable.
ThefollowingexamplelistingshowstheBankAppclass:
Examplelisting7-8–BankAppclass
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp
packagesample.spring.chapter07.bankapp;
.....
publicclassBankApp{
privatestaticLoggerlogger=Logger.getLogger(BankApp.class);
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
BankAccountServicebankAccountService=context.getBean(BankAccountService.class);
BankAccountDetailsbankAccountDetails=newBankAccountDetails();
.....
intbankAccountId=bankAccountService.createBankAccount(bankAccountDetails);
.....
FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();
.....
intFixedDepositId=FixedDepositService.createFixedDeposit(fixedDepositDetails);
.....
}
}
Intheaboveexamplelisting,theBankAccountServiceobjectinteractswithBankAccountDaoImpl(refer
example listing 7-7) to create a bank account, and FixedDepositService object interacts with
FixedDepositDaoImpl(referexamplelisting7-4and7-6)objecttoopenafixeddepositcorrespondingto
thenewlycreatedbankaccount.IfyouexecuteBankApp’smainmethod,youllfindthatanewrecordis
insertedintobothBANK_ACCOUNT_DETAILSandFIXED_DEPOSIT_DETAILStables.
In this section, we looked at how Springs JDBC module simplifies updating or fetching data from
databases.SpringsJDBCmodulecanalsobeusedforthefollowingpurposes:
·executingstoredproceduresandfunctions.Forinstance,youcanuseSpringsSimpleJdbcCall
classforexecutingstoredproceduresandfunctions
·executingpreparedstatementsinbatches
·        accessing relational databases in an object-oriented manner. For instance, you can extend
Springs MappingSqlQuery class to create an SQL query and map the returned ResultSet to a
domainobject.
·configuringanembeddeddatabaseinstance.Forinstance,youcanSpringsjdbcschematocreate
an instance ofHSQL, H2 or Derbydatabases,and register thedatabaseinstance withtheSpring
containerasabeanoftypejavax.sql.DataSource.
Lets now look at how we can use Springs support for Hibernate ORM framework to interact with
databases.
7-4DevelopingtheMyBankapplicationusingHibernate
Springs ORM module provides integration with Hibernate, Java Persistence API (JPA), MyBatis, and
JavaDataObjects(JDO).Inthissection,we’llseehowSpringsimplifiesusingHibernateframeworkfor
database interaction. As Hibernate itself is a JPA provider, well use JPA annotations to map our
persistententityclassestodatabasetables.
IMPORT chapter 7/ch07-bankapp-hibernate(This project shows the MyBank application that uses
Hibernatetointeractwiththedatabase.Toruntheapplication,executethemainmethodoftheBankApp
classofthisproject.)
LetsfirstlookathowtoconfigureHibernatesSessionFactoryinstance.
ConfiguringSessionFactoryinstance
SessionFactoryisafactoryforcreatingHibernate’sSessionobject.ItistheSessionobjectthatisusedby
DAOs to perform create, read, delete and update operations on persistent entities. Springs
org.springframework.orm.hibernate4.LocalSessionFactoryBean(aFactoryBeanimplementation)createsa
SessionFactoryinstancethatcanbeusedbyDAOclassesforobtainingaSessioninstance.
NOTE If you want to use JPAs EntityManager in your applications DAOs for database interaction,
configure Springs LocalContainerEntityManagerFactoryBean instead of
org.springframework.orm.hibernate4.LocalSessionFactoryBean.
The following example listing shows how the LocalSessionFactoryBean class is configured in the
applicationcontextXMLfile:
Examplelisting7-9–applicationContext.xml-LocalSessionFactoryBeanconfiguration
Project–ch07-bankapp-hibernate
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp
<beanid="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<propertyname="dataSource"ref="dataSource"/>
<propertyname="packagesToScan"value="sample.spring"/>
</bean>
ThedataSourcepropertyspecifiesreferencetoabeanoftypejavax.sql.DataSource.ThepackagesToScan
propertyspecifiesthepackage(s)underwhichSpringlooksforpersistentclasses.Forinstance,theabove
example listing specifies that if a persistent class is annotated with JPAs @Entity annotation, and is
located inside sample.spring package (or its sub-packages), it is automatically detected by
org.springframework.orm.hibernate4.LocalSessionFactoryBean.AnalternativetousingpackagesToScan
propertyistoexplicitlyspecifyallthepersistentclassesusingannotatedClassesproperty,asshowninthe
followingexamplelisting:
Examplelisting7-10LocalSessionFactoryBean’sannotatedClassesproperty
<beanid="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<propertyname="dataSource"ref="dataSource"/>
<propertyname="annotatedClasses">
<list>
<value>sample.spring.chapter07.bankapp.domain.BankAccountDetails</value>
<value>sample.spring.chapter07.bankapp.domain.FixedDepositDetails</value>
</list>
</property>
</bean>
In the above example listing, annotatedClasses property (of type java.util.List) lists down all the
persistentclassesintheapplication.
NOTEIfyouareusingHibernate3,useSprings
org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBeaninsteadof
org.springframework.orm.hibernate4.LocalSessionFactoryBeantocreateaSessionFactoryinstance.
As we have configured LocalSessionFactoryBean, lets now look at DAOs that make use of
SessionFactoryinstancecreatedbyLocalSessionFactoryBeantoperformdatabaseoperations.
CreatingDAOsthatuseHibernateAPIfordatabaseinteraction
Tointeractwiththedatabase,DAOsneedaccesstoHibernate’sSessionobject.ToaccessHibernate’s
Session object, inject the SessionFactory instance created by LocalSessionFactoryBean bean (refer
example listing 7-9) into DAOs, and use the injected SessionFactory instance to obtain a Session
instance.
ThefollowingexamplelistingshowstheFixedDepositDaoImplclassthatusesHibernateAPIforsaving
andretrievingtheFixedDepositDetailspersistententity:
Examplelisting7-11–FixedDepositDaoImplclass-HibernateAPIusage
Project–ch07-bankapp-hibernate
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp/dao
packagesample.spring.chapter07.bankapp.dao;
importorg.hibernate.SessionFactory;
.....
@Repository(value="FixedDepositDao")
publicclassFixedDepositDaoImplimplementsFixedDepositDao{
@Autowired
privateSessionFactorysessionFactory;
publicintcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails){
sessionFactory.getCurrentSession().save(fixedDepositDetails);
returnfixedDepositDetails.getFixedDepositId();
}
publicFixedDepositDetailsgetFixedDeposit(finalintFixedDepositId){
Stringhql="fromFixedDepositDetailsasFixedDepositDetailswhere"
+"FixedDepositDetails.FixedDepositId="
+FixedDepositId;
return(FixedDepositDetails)sessionFactory.getCurrentSession()
.createQuery(hql).uniqueResult();
}
}
The above example listing shows that an instance of SessionFactory is autowired into
FixedDepositDaoImplinstance,whichislaterusedbycreateFixedDepositandgetFixedDepositmethods
tosaveandretrieveFixedDepositDetailspersistententity.AutowiringofSessionFactoryinstanceshows
thatyoucanautowireanobjectcreatedbySpringsFactoryBeanimplementationbysimplydefiningthe
type created by the FactoryBean and annotating it with @Autowired annotation (refer section 3-9 of
chapter 3 to know more about Springs FactoryBean interface). The createFixedDeposit and
getFixedDeposit methods call SessionFactorys getCurrentSession method to obtain an instance of
Session. It is important to note that the call to getCurrentSession method returns the Session object
associatedwiththecurrenttransactionorthread.UsinggetCurrentSessionmethodisusefulifyouwant
Springtomanagetransactions,whichisthecaseinMyBankapplication.
LetsnowlookatSpringsprogrammaticanddeclarativetransactionmanagementfeature.
7-5TransactionmanagementusingSpring
SpringFrameworksupportsbothprogrammaticanddeclarativetransactionmanagement.Inprogrammatic
transactionmanagement,Springstransactionmanagementabstractionisusedtoexplicitlystart,endand
committransactions.Indeclarativetransactionmanagement,youannotatemethodsthatexecutewithina
transactionwithSprings@Transactionalannotation.
LetsfirstlookatthetransactionmanagementrequirementofMyBankapplicationdescribedinsection7-
2.
MyBankstransactionmanagementrequirements
Insection7-2,itwasmentionedthatwhenabankcustomeropensanewfixeddeposit,thefixeddeposit
amountisdeductedfromtheBANK_ACCOUNT_DETAILStablesBALANCE_AMOUNTcolumn,and
thefixeddepositdetailsaresavedintheFIXED_DEPOSIT_DETAILStable.
ThefollowingsequencediagramshowsthatthecreateFixedDepositmethodofFixedDepositServiceImpl
classsavesthefixeddepositdetailsinFIXED_DEPOSIT_DETAILStableanddeductsthefixeddeposit
amountfromthecorrespondingbankaccountinBANK_ACCOUNT_DETAILStable:
Figure7-2 The sequence of actions performed by MyBank application when a customer opens a new
fixeddeposit
The above sequence diagram shows that FixedDepositServiceImpls createFixedDeposit method calls
FixedDepositDaoImpls createFixedDeposit method and BankAccountDaoImpls subtractFromAccount
method. FixedDepositDaoImpls createFixedDeposit method saves the fixed deposit details in the
FIXED_DEPOSIT_DETAILS table. BankAccountDaoImpls subtractFromAccount method first checks
thatthecustomersbankaccountcontainssufficientbalanceto createthefixeddepositof the specified
amount. If sufficient balance is available in customers bank account, the subtractFromAccount method
deductsthefixeddepositamountfromthecustomersbankaccount.Ifsufficientbalanceisntavailable,
an exception is thrown by BankAccountDaoImpls subtractFromAccount method. If
FixedDepositDaoImpls createFixedDeposit or BankAccountDaoImpls subtractFromAccount method
failsforsomereason,thesystemwillbeleftinaninconsistentstate;therefore,boththemethodsmustbe
executedwithinatransaction.
Lets now look at how you can use Spring to programmatically manage transactions in the MyBank
application.
Programmatictransactionmanagement
YoucanprogrammaticallymanagetransactionsbyusingSpringsTransactionTemplateclassorbyusing
an implementation of Springs PlatformTransactionManager interface. TransactionTemplate class
simplifies transaction management by taking care ofinitiating and committing transactions. You only
needtoprovideanimplementationofSpringsTransactionCallbackinterfacethatcontainsthecodetobe
executedwithinatransaction.
IMPORT chapter 7/ch07-bankapp-tx-jdbc (This project shows the MyBank application that uses
SpringsTransactionTemplateclassforprogrammaticallymanagingtransactions.Toruntheapplication,
execute the main method of the BankApp class of this project. Create SPRING_BANK_APP_DB
database, and BANK_ACCOUNT_DETAILS and FIXED_DEPOSIT_DETAILS tables as described for
ch07-bankapp-jdbcproject)
ThefollowingexamplelistingshowshowtheTransactionTemplateclassisconfiguredintheapplication
contextXMLfile:
Examplelisting7-12–applicationContext.xml-TransactionTemplateconfiguration
Project–ch07-bankapp-tx-jdbc
Sourcelocation-src/main/resources/META-INF/spring
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource".....>
.....
</bean>
<beanid="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"/>
</bean>
<beanid="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<propertyname="transactionManager"ref="txManager"/>
<propertyname="isolationLevelName"value="ISOLATION_READ_UNCOMMITTED"/>
<propertyname="propagationBehaviorName"value="PROPAGATION_REQUIRED"/>
</bean>
TransactionTemplate’s transactionManager property refers to Springs PlatformTransactionManager
implementationthatisresponsibleformanagingtransactions.
TransactionTemplate’sisolationLevelNamepropertyspecifiesthetransactionisolationleveltobesetfor
thetransactionsmanagedbythetransactionmanager.ThevalueofisolationLevelNamepropertyrefersto
a constant defined by Springs TransactionDefinition interface. For instance,
ISOLATION_READ_UNCOMMITTED is a constant defined by TransactionDefinition interface that
indicatesthattheuncommittedchangesbyatransactioncanbereadbyothertransactions.
TransactionTemplate’s propagationBehaviorName property specifies the transaction propagation
behavior. The value of propagationBehaviorName property refers to a constant defined by Springs
TransactionDefinition interface. For instance, PROPAGATION_REQUIRED is a constant defined by
TransactionDefinitioninterfacethatindicates:
·ifamethodisnotinvokedwithinatransaction,thetransactionmanagerstartsanewtransaction
andexecutesthemethodinthenewlycreatedtransaction
·ifamethodisinvokedwithinatransaction,thetransactionmanagerexecutesthemethodinthe
sametransaction
Spring provides a couple ofbuilt-in PlatformTransactionManager implementations that you can choose
from, depending upon the data access technology used by your application. For instance,
DataSourceTransactionManageris appropriate for managing transactionsinapplications thatuseJDBC
forinteractingwithadatabase,HibernateTransactionManagerisappropriatewhenHibernateisusedfor
database interaction and JpaTransactionManager when JPA’s EntityManager is used for data access. In
example listing 7-12, TransactionTemplate’s transactionManager property refers to a
DataSourceTransactionManager instance because the MyBank application of ch07-bankapp-tx-jdbc
projectuses JDBC for data access. The example listing 7-12 shows that
DataSourceTransactionManagers dataSource property refers to a javax.sql.DataSource object that
representsthedatabasewhosetransactionsaremanagedbytheDataSourceTransactionManagerinstance.
ThefollowingexamplelistingshowstheFixedDepositServiceImplclassthatusesTransactionTemplate
instancefortransactionmanagement:
Examplelisting7-13–FixedDepositServiceImplclassthatusesTransactionTemplate
Project–ch07-bankapp-tx-jdbc
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp/service
packagesample.spring.chapter07.bankapp.service;
importorg.springframework.transaction.TransactionStatus;
importorg.springframework.transaction.support.TransactionCallback;
importorg.springframework.transaction.support.TransactionTemplate;
.....
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{
@Autowired
privateTransactionTemplatetransactionTemplate;
.....
@Override
publicintcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails)throwsException{
transactionTemplate.execute(newTransactionCallback<FixedDepositDetails>(){
publicFixedDepositDetailsdoInTransaction(TransactionStatusstatus){
try{
myFixedDepositDao.createFixedDeposit(fixedDepositDetails);
bankAccountDao.subtractFromAccount(
fixedDepositDetails.getBankAccountId(),
fixedDepositDetails.getFixedDepositAmount()
);
}catch(Exceptione){status.setRollbackOnly();}
returnfixedDepositDetails;
}
});
returnfixedDepositDetails.getFixedDepositId();
}
.....
}
TheaboveexamplelistingshowsFixedDepositServiceImplscreateFixedDepositmethod(referfigure7-
2formoredetails)thatsavesfixeddepositdetailsintheFIXED_DEPOSIT_DETAILStable,anddeducts
thefixeddepositamountfromthecorrespondingbankaccountintheBANK_ACCOUNT_DETAILStable.
You create an implementation of TransactionCallback interface to define the actions that you want to
executewithinatransaction.And,TransactionTemplate’sexecutemethodexecutestheactionscontained
in the TransactionCallback instance within a transaction. TransactionCallback interface defines a
doInTransaction method that you implement to provide the actions that should be executed within a
transaction. TransactionCallbacks doInTransaction method is invoked within a transaction by
TransactionTemplate’s executemethod.ThedoInTransaction method accepts a TransactionStatus object
thatyoucanusetocontroltheoutcomeofthetransaction.Inexamplelisting7-13,TransactionCallbacks
doInTransaction method contains calls to FixedDepositDaoImpls createFixedDeposit method and
BankAccountDaoImpl’ssubtractFromAccountmethodbecausewewantboththemethodstobeexecuted
withinasingletransaction.Aswe’dwanttorollbackthetransactionifeitherofthemethodsfails,the
setRollbackOnly method of TransactionStatus is invoked in case of an exception. If you call
TransactionStatusssetRollbackOnlymethod,theTransactionTemplateinstancerollbacksthetransaction.
A transaction will be automatically rolled back if the actions contained in the doInTransaction method
resultinajava.lang.RuntimeException.
TransactionCallbackinstanceacceptsagenerictypeargumentwhichreferstotheobjecttypereturnedby
the doInTransaction method. In example listing 7-13, a FixedDepositDetails object is returned by the
doInTransaction method. If you dont want the doInTransaction method to return any object, use the
TransactionCallbackWithoutResultabstractclassthatimplementstheTransactionCallbackinterface.The
TransactionCallbackWithoutResult class allows you to create TransactionCallback implementations in
whichdoInTransactionmethoddoesn’treturnavalue.
The following example listing shows the main method of BankApp class that calls
BankAccountServiceImpls createBankAccount method to create a bank account, and
FixedDepositServiceImpls createFixedDeposit method to create a fixed deposit corresponding to the
newlycreatedbankaccount:
Examplelisting7-14–BankAppclass
Project–ch07-bankapp-tx-jdbc
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp
packagesample.spring.chapter07.bankapp;
publicclassBankApp{
.....
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
BankAccountServicebankAccountService=context.getBean(BankAccountService.class);
FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
BankAccountDetailsbankAccountDetails=newBankAccountDetails();
bankAccountDetails.setBalanceAmount(1000);
.....
intbankAccountId=bankAccountService.createBankAccount(bankAccountDetails);
FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();
fixedDepositDetails.setFixedDepositAmount(1500);
fixedDepositDetails.setBankAccountId(bankAccountId);
.....
intFixedDepositId=FixedDepositService.createFixedDeposit(fixedDepositDetails);
.....
}
}
The above example listing shows that a bank account is first created with a balance amount of 1000,
followedbycreatingafixeddepositofamount1500.Asfixeddepositamountisgreaterthanthebalance
in the bank account, BankAccountDaoImpl’s subtractFromAccount method throws an exception (refer
BankAccountDaoImpl’ssubtractFromAccountmethodorfigure7-2).
If you execute BankApp’s main method, youll notice that the fixed deposit is not created in the
FIXED_DEPOSIT_DETAILS table, and 1500 amount isnot deducted from the
BANK_ACCOUNT_DETAILS table. This shows that both FixedDepositDaoImpls createFixedDeposit
andBankAccountDaoImplssubtractFromAccountareexecutedinthesametransaction.
Instead of using TransactionTemplate class, you can directly use a PlatformTransactionManager
implementation to programmatically manage transactions. When using PlatformTransactionManager
implementation, you are required to explicitly initiate and commit (or roll back) transactions. For this
reason, it is recommended to use TransactionTemplate instead of directly using a
PlatformTransactionManagerimplementation.
LetsnowlookatdeclarativetransactionmanagementfeatureofSpring.
Declarativetransactionmanagement
ProgrammatictransactionmanagementcouplesyourapplicationcodewithSpring-specificclasses.Onthe
other hand, declarative transaction management requires you to only annotate methods or classes with
Springs @Transactional annotation. If you want to execute a method within a transaction, annotate the
method with @Transactional annotation. If you want to execute all the methods of a class within a
transaction,annotatetheclasswith@Transactionalannotation.
NOTEInsteadofusing@Transactionalannotationfordeclarativetransactionmanagement,youcanuse
Springstxschemaelementstoidentifytransactionalmethods.AsusingSpringstxschemaresultsin
verboseapplicationcontextXMLfile,we’llbeonlylookingatusing@Transactionalannotationfor
declarativetransactionmanagement.
IMPORTchapter7/ch07-bankapp-jdbcandchapter7/ch07-bankapp-hibernate (The ch07-bankapp-
jdbc project shows the MyBank application that uses Springs JDBC module for database interaction
(refersection7-3tolearnmoreaboutch07-bankapp-jdbcproject).Thech07-bankapp-hibernateproject
showstheMyBankapplicationthatusesHibernatetointeractwiththedatabase(refersection7-4tolearn
moreaboutch07-bankapp-hibernateproject).
Youenabledeclarativetransactionmanagementusing<annotation-driven>elementofSpringstxschema.
The following example listing shows the <annotation-driven> element’s usage in ch07-bankapp-jdbc
project:
Examplelisting7-15–applicationContext.xml-<annotation-driven>element
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/resources/META-INF/spring
<beans.....xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=".....http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
.....
<tx:annotation-driventransaction-manager="txManager"/>
<beanid="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"/>
</bean>
.....
</beans>
In the above example listing, Springs txschema is included so that its elements are accessible in the
application context XML file. The <annotation-driven> element enables declarative transaction
management.The<annotation-driven>element’stransaction-managerattributespecifiesreferencetothe
PlatformTransactionManager implementation to use for transaction management. The above example
listing shows that the DataSourceTransactionManager is used as the transaction manager in ch07-
bankapp-jdbcproject.
The following example listing shows how you can use declarative transaction management in ch07-
bankapp-hibernateprojectthatusesHibernateORMfordataaccess:
Examplelisting7-16–applicationContext.xml-<annotation-driven>element
Project–ch07-bankapp-hibernate
Sourcelocation-src/main/resources/META-INF/spring
<beans.....xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=".....http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
.....
<tx:annotation-driventransaction-manager="txManager"/>
<beanid="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<propertyname="sessionFactory"ref="sessionFactory"/>
</bean>
.....
</beans>
If you compare the above example listing with 7-15, youll notice that the only difference is in the
PlatformTransactionManager implementation referenced by the transaction-manager attribute of
<annotation-driven> element. The above example listing shows that if Hibernate ORM is used for
database interaction, the org.springframework.orm.hibernate4.HibernateTransactionManager
implementationofPlatformTransactionManagerisusedformanagingtransactions.
NOTE If you are using Hibernate 3, set transaction-manager attribute to
org.springframework.orm.hibernate3.HibernateTransactionManager instead of
org.springframework.orm.hibernate4.HibernateTransactionManager.
The following example listing shows the FixedDepositServiceImpl class that makes use of declarative
transactionmanagement:
Examplelisting7-17–FixedDepositServiceImplclass-@Transactionalannotationusage
Project–ch07-bankapp-jdbc
Sourcelocation-src/main/java/sample/spring/chapter07/bankapp/service
packagesample.spring.chapter07.bankapp.service;
importorg.springframework.transaction.annotation.Transactional;
.....
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
@Transactional
publicintcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{
bankAccountDao.subtractFromAccount(fixedDepositDetails.getBankAccountId(),
fixedDepositDetails.getFixedDepositAmount());
returnmyFixedDepositDao.createFixedDeposit(fixedDepositDetails);
}
.....
}
Intheaboveexamplelisting,thecreateFixedDepositmethodisannotatedwith@Transactionalannotation.
ThismeansthatthecreateFixedDepositmethodisexecutedwithinatransaction.Thetransactionmanager
specifiedviathetransaction-managerattributeof<annotation-driven>element(referexamplelisting7-15
and 7-16) is used for managing the transaction. If a java.lang.RuntimeException is thrown during
executionofcreateFixedDepositmethod,thetransactionisautomaticallyrolledback.
@Transactionalannotationdefinesattributesthatyoucanusetoconfigurethebehaviorofthetransaction
manager. For instance, you can use the rollbackFor attribute to specify exception classes that result in
transaction roll back. The exception classes specified by rollbackFor attribute must be subclasses of
java.lang.Throwableclass.Similarly,youcanuseisolationattributetospecifythetransactionisolation
level.
Incaseyourapplicationdefinesmultipletransactionmanagers,youcanuse@Transactionalannotations
valueattributetospecifythebeannameofthePlatformTransactionManagerimplementationthatyouwant
touse for managing transactions.The followingexamplelistingshows that2transactionmanagers, tx1
and tx2, are defined in the application context XML file. The tx1 transaction manager is used by
SomeServiceImplsmethodAandtx2transactionmanagerisusedbySomeServiceImplsmethodB:
Examplelisting7-18–@Transactionalsvalueattributeusage
-----------------------SomeServiceImplclass------------------------
@Service
publicclassSomeServiceImplimplementsSomeService{
.....
@Transactional(value="tx1")
publicintmethodA(){.....}
@Transactional(value="tx2")
publicintmethodB(){.....}
}
-----------------------applicationcontextXMLfile------------------------
<tx:annotation-driven/>
<beanid="tx1"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<propertyname="sessionFactory1"ref="sessionFactory1"/>
</bean>
<beanid="tx2"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"/>
</bean>
Intheaboveexamplelisting,the<annotation-driven>elementofSpringstxschemadoesn’tspecifythe
transaction-manager attribute because the transaction manager to use for managing transactions is
specified by the @Transactional annotation itself. In the above example listing, @Transactional
annotationsvalueattributespecifiesthetransactionmanagertouseformanagingtransactions.Thismeans
that SomeServiceImpl’s methodA executes under tx1 transaction manager and SomeServiceImpls
methodBexecutesundertx2transactionmanager.
LetsnowlookatSpringssupportforJTA(JavaTransactionAPI)transactions.
SpringssupportforJTA
Inchapter1,wediscussedthatwhenmultipletransactionalresourcesareinvolvedinatransaction,JTAis
used for transaction management. Spring provides a generic JtaTransactionManager class (a
PlatformTransactionManager implementation) that you can use in applications to manage JTA
transactions.
Figure 7-3 JTA transaction managers and resource-specific transaction managers implement
PlatformTransactionManagerinterface
In most application server environments, the JtaTransactionManager will meet your requirements. But,
Spring also provides vendor-specific PlatformTransactionManager implementations that leverage
application server-specific features to manage JTA transactions. The vendor-specific JTA transaction
managers provided by Spring are: OC4JJtaTransactionManager (for Oracle OC4J),
WebLogicJtaTransactionManager (for WebLogic application server),
WebSphereUowTransactionManager (for WebSphere application server). Figure 7-3 summarizes how
JTA transaction managers and resource-specific transaction managers are related to the
PlatformTransactionManager interface. The figure shows that the PlatformTransactionManager is
implementedbybothJTAtransactionmanagerclassesandresource-specifictransactionmanagerclasses.
Lets now look at how Spring simplifies configuring a JTA transaction manager in application context
XMLfile.
ConfiguringaJTAtransactionmanagerusing<jta-transaction-manager>element
Springs tx schema provides a <jta-transaction-manager> element that automatically detects the
application server in which the application is deployed and configures an appropriate JTA transaction
manager. This saves the effort for explicitly configuring an application server-specific JTA transaction
manager in the application context XML file. For instance, if you deploy an application in WebSphere
application server, the <jta-transaction-manager> element configures an instance of
WebSphereUowTransactionManager instance. If the same application is deployed in WebLogic
application server, the <jta-transaction-manager> element configures an instance of
WebLogicJtaTransactionManagerinstance.Iftheapplicationisdeployedinanyapplicationserverother
than OC4J, WebSphere or WebLogic, the <jta-transaction-manager> element configures an instance of
JtaTransactionManagerinstance.
7-6Summary
In this chapter, we saw that Spring supports database interaction using JDBC and Hibernate ORM
framework. We also saw how we can use Spring to manage transactions programmatically and
declaratively. In the next chapter, we’ll look athow Spring simplifies sending emails, interaction with
messagingmiddlewares,andperformtransparentcachingofdata.
Chapter8-Messaging,emailing,asynchronousmethod
execution,andcachingusingSpring
8-1Introduction
In the previous chapter, we saw that Spring simplifies database interaction. In the context of MyBank
application,thischaptergoesastepfurtherandshowshowSpringsimplifies:
·sendingandreceivingJMSmessagesfromaJMSprovider,likeActiveMQ
·sendingemailmessages
·asynchronouslyexecutingmethods
·storingandretrievingdatafromcache
LetsfirstlookattheMyBankapplicationsrequirementsthatwellimplementinthischapter.
8-2MyBankapplicationsrequirements
MyBank application allows its customers to open fixed deposits and retrieve details of their existing
fixeddeposits.Figure8-1showsthesequenceofeventsthatoccurwhenacustomerrequestsforopening
anewfixeddeposit.
First, FixedDepositServices createFixedDeposit method is invoked that sends 2 JMS messages – a
message containing customers email id, and a message that contains fixed deposit details.
EmailMessageListenerretrievestheJMSmessagecontainingtheemailidofthecustomerandsendsan
email to the customer informing that the request for opening a fixed deposit has been received.
FixedDepositMessageListenerretrievestheJMSmessagecontainingfixeddepositdetailsandsavesthe
fixeddepositdetailsinthedatabase.
A scheduled job runs every 5 seconds to check if any new fixed deposits have been created in the
database. If the job finds any new fixed deposits, it subtracts the fixed deposit amount from the bank
accountofthecustomerandsendsanemailtothecustomerinformingthatthefixeddepositrequesthas
beensuccessfullyprocessed.
Figure8-1MyBankapplicationbehaviorwhenacustomerrequestsforopeninganewfixeddeposit
The following diagram shows the behavior of MyBank application when FixedDepositServices
findFixedDepositsByBankAccount method is invoked to retrieve all fixed deposits corresponding to a
bankaccount:
Figure 8-2 MyBank application behavior when a customer requests for the details of all his fixed
deposits
The above figure shows thatwhen FixedDepositService’sfindFixedDepositsByBankAccountmethod is
invoked,thefixeddepositinformationisfetchedfromthedatabaseandcachedintomemory.Ifyoucan
FixedDepositService’sfindFixedDepositsByBankAccountagain,thefixeddepositinformationisfetched
fromthecacheandnotfromthedatabase.
Lets now look at how Spring is used in the MyBank application to send JMS messages to JMS
destinationsconfiguredinActiveMQ.
IMPORTchapter8/ch08-bankapp(Togetthemostofoutofthischapter,installMySQLdatabaseand
execute the spring_bank_app_db.sql SQL script contained in the sql folder of ch08-bankapp project.
Executing spring_bank_app_db.sql script creates SPRING_BANK_APP_DB database and adds
BANK_ACCOUNT_DETAILS and FIXED_DEPOSIT_DETAILS tables to the
SPRING_BANK_APP_DB database. Modify the src/main/resources/META-
INF/spring/database.properties to point to your MySQL installation. To get the email feature working,
modifysrc/main/resources/META-INF/spring/email.propertiestospecifytheemailserverandtheemail
accounttouseforsendingemails.ModifytheBankAppclasstospecifytheemailidofthecustomerto
whomtheemailsaresent)
8-3SendingJMSmessages
SpringsimplifiesinteractionwithJMSprovidersbyprovidingalayerofabstractionontopofJMSAPI.
InthecontextofMyBankapplication,thissectionshowshowtosynchronouslyandasynchronouslysend
andreceivemessagesfromanActiveMQbrokerusingSpring.Forthesakeofsimplicity,theActiveMQ
brokerisconfiguredtoruninembeddedmodeinch08-bankappproject.
NOTEInSpring,JMSsupportclassesaredefinedinspring-jmsJARfile;therefore,youmustdefinethat
yourapplicationdependsonspring-jmsJARfiletouseSpringssupportforJMS.
ConfiguringActiveMQbrokertoruninembeddedmode
AnembeddedActiveMQbrokerrunsinthesameJVMastheapplication.YoucanuseActiveMQ’sXML
schema to configure an embedded ActiveMQ broker in a Spring application. The following example
listing shows how ActiveMQ’s XML schema is used to configure an embedded ActiveMQ broker in
MyBankapplication:
Examplelisting8-1–applicationContext.xml–embeddedActiveMQbrokerconfiguration
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
<beans.....
xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation=".....http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd.....">
<amq:broker>
<amq:transportConnectors>
<amq:transportConnectoruri="tcp://localhost:61616"/>
</amq:transportConnectors>
</amq:broker>
.....
</beans>
In the above example listing, the amq namespace refers to ActiveMQs XML schema (activemq-core-
5.7.0.xsd)thatallowsyoutoconfigureanembeddedActiveMQbroker.The<broker>elementconfigures
an embedded ActiveMQ broker with name localhost. The <transportConnectors> element specifies the
transport connectors onwhich the embedded ActiveMQ broker allows clients toconnect. In the above
examplelisting,the<transportConnector>sub-elementof<transportConnectors>specifiesthatclientscan
connecttotheembeddedActiveMQbrokeronportnumber61616usingaTCPsocket.
LetsnowlookathowtoconfigureaJMSConnectionFactoryforcreatingconnectionstotheembedded
ActiveMQinstance.
ConfiguringaJMSConnectionFactory
The following example listing shows how a JMS ConnectionFactory is configured in the application
contextXMLfile:
Examplelisting8-2–applicationContext.xml–JMSConnectionFactoryconfiguration
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
<beans.....
xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation=".....http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd.....">
.....
<amq:connectionFactorybrokerURL="vm://localhost"id="jmsFactory"/>
<beanclass="org.springframework.jms.connection.CachingConnectionFactory"
id="cachingConnectionFactory">
<propertyname="targetConnectionFactory"ref="jmsFactory"/>
</bean>
.....
</beans>
In the above example listing, the <connectionFactory> element of amq schema creates a JMS
ConnectionFactory instance that is used for creating connections to the embedded ActiveMQ instance
(refer example listing 8-1). The brokerUrl attribute specifies the URL for connecting to the ActiveMQ
broker.AsweareusingembeddedActiveMQbroker,thebrokerUrlspecifiesthatVMprotocol(specified
byvm://)isusedtoconnecttotheActiveMQbrokerinstance.
Springs CachingConnectionFactory is an adapter for the JMS ConnectionFactory (specified by the
targetConnectionFactory property), that provides the additional feature of caching instances of JMS
Session,MessageProducerandMessageConsumer.
LetsnowlookathowtouseSpringsJmsTemplateclasstosendJMSmessages.
SendingJMSmessagesusingJmsTemplate
Springs JmsTemplate class simplifies synchronously sending and receiving JMS messages. For the
purpose of this chapter, we’ll only look at how to send JMS messages using JmsTemplate. Like
TransactionTemplate(refersection7-5ofchapter7)andJdbcTemplate(refersection7-3ofchapter7)
classes,theJmsTemplateclassprovidesalayerofabstractionsothatyoudon’thavetodealwithlower-
levelJMSAPI.
ThefollowingexamplelistingshowshowtheJmsTemplateclassisconfiguredintheapplicationcontext
XMLfileofMyBankapplicationtosendmessagestotheembeddedActiveMQinstance:
Examplelisting8-3–applicationContext.xml–JmsTemplateconfiguration
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
<beans.....
xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation=".....http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd.....">
.....
<beanclass="org.springframework.jms.core.JmsTemplate"id="jmsTemplate">
<propertyname="connectionFactory"ref="cachingConnectionFactory"/>
<propertyname="defaultDestination"ref="FixedDepositDestination"/>
</bean>
<amq:queueid="FixedDepositDestination"physicalName="aQueueDestination"/>
<amq:queueid="emailQueueDestination"physicalName="emailQueueDestination"/>
.....
</beans>
JmsTemplate’sconnectionFactorypropertyspecifiestheJMSConnectionFactorythatisusedforcreating
aconnectionwiththeJMSprovider.JmsTemplate’sdefaultDestinationpropertyreferstothedefaultJMS
destination to which the JmsTemplate sends JMS messages. In the above example listing,
connectionFactorypropertyreferstotheCachingConnectionFactoryinstance(referexamplelisting8-2),
and defaultDestination property refers to the JMSqueue destination created by amq schema’s <queue>
element.
Theamqschema’s<queue>elementcreatesaJMSqueuedestinationinActiveMQ.Inexamplelisting8-
3,thefirst<queue>elementcreatesaJMSqueuedestinationnamedaQueueDestinationinActiveMQ,and
the second <queue> element creates a JMS queue destination named emailQueueDestination in
ActiveMQ. The physicalName attribute refers to the name with which the JMS queue destination is
created in ActiveMQ, and id attribute refers to the name with which the JMS queue destination is
accessedbyotherbeansintheSpringcontainer.Inexamplelisting8-3,JmsTemplate’sdefaultDestination
property refers to the id attribute of the <queue> element that creates the aQueueDestination JMS
destination; therefore, the aQueueDestination is the default JMS destination to which the JmsTemplate
instancesendsJMSmessages.
JMSSessionusedbyJmsTemplatehastheacknowledgementmodesettoauto-acknowledgeandisnot
transactedinnature.IfyouwantJmsTemplatetousetransactedSessions,setJmsTemplate’stransacted
propertytotrue.IncaseoftransactedSessions,anewtransactionbeginswhentheSessioniscreatedby
theapplication,orwhenthetransactioniscommittedorrolledback.ThismeansthatatransactedJMS
Session isalways associated with a transaction. You can use a transacted JMS Session to send and
receive JMS messages within a transaction. If you use JmsTemplate with Springs
JmsTransactionManager,theJmsTemplateinstancewillalwaysgetatransactedJMSSession.
LetsnowlookathowJmsTransactionManagerisconfigured,andJMSmessagesaresentbyJmsTemplate
withinatransaction.
SendingJMSmessageswithinatransaction
Inchapter7,wesawthatSpringprovidesacoupleofPlatformTransactionManagerimplementationsthat
provide resource-specific transaction management. In your JMS applications, you can use Springs
JmsTransactionManager (an implementation of PlatformTransactionManager) class for managing
transactions for a single JMS ConnectionFactory. As JmsTransactionManager implements
PlatformTransactionManager, you can use TransactionTemplate for programmatically managing JMS
transactionsoryoucanuse@TransactionalannotationfordeclarativelymanagingJMStransactions.
ThefollowingexamplelistingshowstheconfigurationofSpring’sJmsTransactionManagerinapplication
contextXMLfile:
Examplelisting8-4–applicationContext.xml–JmsTransactionManagerconfiguration
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
<beanid="jmsTxManager"class="org.springframework.jms.connection.JmsTransactionManager">
<propertyname="connectionFactory"ref="cachingConnectionFactory"/>
</bean>
JmsTransactionManagersconnectionFactorypropertyspecifiesreferencetotheJMSConnectionFactory
for which the JmsTransactionManager manages transactions. In the above example listing, reference to
Springs CachingConnectionFactory bean (refer example listing 8-2) is specified as the value for
connectionFactory property. As the CachingConnectionFactory caches JMS Sessions, using
CachingConnectionFactorywithJmsTransactionManagerresultsinreducedutilizationofresources.
IfyouwanttoprogrammaticallymanageJMStransactionsusingTransactionTemplateclass,configurethe
TransactionTemplateclassintheapplicationcontextXMLfile.Ifyouwanttousedeclarativetransaction
management,use<annotation-driven>elementofSpringstxschema.
ThefollowingexamplelistingshowstheFixedDepositServiceImplclassthatmakesuseofJmsTemplate
tosendmessagestotheembeddedActiveMQbroker:
Examplelisting8-5–FixedDepositServiceImplclass–sendJMSmessagesusingJmsTemplate
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/service
packagesample.spring.chapter08.bankapp.service;
importjavax.jms.*;
importorg.springframework.jms.core.JmsTemplate;
importorg.springframework.jms.core.MessageCreator;
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{
@Autowired
privateJmsTemplatejmsTemplate;
.....
@Override
@Transactional("jmsTxManager")
publicvoidcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails)throwsException{
jmsTemplate.send("emailQueueDestination",newMessageCreator(){
publicMessagecreateMessage(Sessionsession)throwsJMSException{
TextMessagetextMessage=session.createTextMessage();
textMessage.setText(fixedDepositDetails.getEmail());
returntextMessage;
}
});
//--thisJMSmessagegoestothedefaultdestinationconfiguredfortheJmsTemplate
jmsTemplate.send(newMessageCreator(){
publicMessagecreateMessage(Sessionsession)throwsJMSException{
ObjectMessageobjectMessage=session.createObjectMessage();
objectMessage.setObject(fixedDepositDetails);
returnobjectMessage;
}
});
}
.....
}
The above example listing shows that JmsTemplate’s send method is used to send messages to
emailQueueDestinationandaQueueDestinationJMSdestinations.Refer examplelisting 8-3 tosee how
these JMS destinations are configured in the application context XML file. The name of the JMS
destination passed to JmsTemplatessend method is resolved to the actual JMS Destination object by
Springs DynamicDestinationResolver instance (an implementation of Springs DestinationResolver
interface). If you have configured JMS destinations in the application context XML file using amq
schema’s <queue> (or <topic>) element, the JMS destination name passed to the JmsTemplate’s send
message is the value of id attribute of the <queue> (or <topic>) element corresponding to the JMS
destinationtowhichyouwanttosendmessages.
In example listing 8-5, the FixedDepositServiceImpls createFixedDeposit method is annotated with
@Transactional("jmsTxManager"), which means that the createFixedDeposit method executes within a
transaction,andthetransactionismanagedbyjmsTxManagertransactionmanager(referexamplelisting
8-4toseehowjmsTxManagerisconfigured).JmsTemplate’ssendmethodacceptsthenameoftheJMS
destination(towhichtheJMSmessageistobesent)andaMessageCreatorinstance.Ifyoudontspecify
theJMSdestination,thesendmethodsendstheJMSmessagetothedefaultdestinationthatyouconfigured
fortheJmsTemplateusingdefaultDestinationproperty(referexamplelisting8-3).
InMessageCreator’screateMessagemethodyoucreatetheJMSmessagethatyouwanttosend.Youdon’t
need to explicitly handle checked exceptions thrown by JMS API, as they are taken care by the
JmsTemplate itself. Example listing 8-5 shows that if you are using JmsTemplate, you dont need to
explicitly obtain Connection from ConnectionFactory, create Session from Connection, and so on, for
sending JMS messages. So, using JmsTemplate hides the lower-level JMS API details from the
developers.
In example listing 8-5, the TextMessage and ObjectMessage instances represent JMS messages. Both,
TextMessage and ObjectMessage classes implement javax.jms.Message interface. In the MyBank
application,theTextMessageinstancehasbeenusedtosendtheemailid(asimplestringvalue)ofthe
customer requesting to open a fixed deposit, and the ObjectMessage instance has been used to send
FixedDepositDetails object (a Serializable object) that contains fixed deposit information. As the
FixedDepositServiceImplscreateFixedDepositmethodexecuteswithinaJMStransaction,eitherboththe
messagesaresenttotheActiveMQinstanceornone.
Insteadofusing@Transactionalannotation,youcanprogrammaticallymanageJMStransactionsbyusing
theTransactionTemplateclass(refersection7-5ofchapter7).Thefollowingexamplelistingshowshow
you can configure the TransactionTemplate class to use JmsTransactionManager for transaction
management:
Examplelisting8-6–TransactionTemplateconfiguration
<beanid="jmsTxManager"
class="org.springframework.jms.connection.JmsTransactionManager">
<propertyname="connectionFactory"ref="cachingConnectionFactory"/>
</bean>
<beanid="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<propertyname="transactionManager"ref="jmsTxManager"/>
</bean>
In the above example listing, TransactionTemplate’s transactionManager property refers to the
JmsTransactionManagerbean.
OnceyouhaveconfiguredtheTransactionTemplateclass,youcanuseittomanageJMStransactions.The
followingexamplelistingshowsavariantofFixedDepositServiceImplscreateFixedDepositmethodthat
usesTransactionTemplateformanagingJMStransactions:
Examplelisting8-7–ProgrammaticallymanagingJMStransactionsusingTransactionTemplate
packagesample.spring.chapter08.bankapp.service;
importjavax.jms.*;
importorg.springframework.jms.core.JmsTemplate;
importorg.springframework.jms.core.MessageCreator;
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{
@Autowired
privateJmsTemplatejmsTemplate;
@Autowired
privateTransactionTemplatetransactionTemplate;
.....
publicvoidcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails)throwsException{
transactionTemplate.execute(newTransactionCallbackWithoutResult(){
protectedvoiddoInTransactionWithoutResult(TransactionStatusstatus){
jmsTemplate.send("emailQueueDestination",newMessageCreator(){.....});
jmsTemplate.send(newMessageCreator(){.....});
}
});
}
.....
}
TheaboveexamplelistingshowsthatJMSmessagesaresentfromwithinthedoInTransactionmethodof
TransactionCallbackWithoutResultclasssothattheyareinthesameJMStransaction.Thisissimilarto
how we programmatically managed JDBC transactions (refer section 7-5 of chapter 7) using
TransactionTemplate.
SofarwehaveseenexamplesinwhichJmsTemplateisusedtosendmessagestoapre-configuredJMS
destination.Let’snowlookathowtoconfigureJmsTemplateclassifanapplicationusesdynamicJMS
destinations.
DynamicJMSdestinationsandJmsTemplateconfiguration
If your application uses dynamic JMS destinations (that is, JMS destinations are created by the
applicationatruntime),youmustspecifytheJMSdestinationtype(queueortopic)usingpubSubDomain
propertyofJmsTemplate.ThepubSubDomainpropertyisusedtodeterminetheJMSdestinationtypeto
whichtheJmsTemplatesendsJMSmessages.Ifyoudon’tspecifythepubSubDomainproperty,bydefault
JMSqueueisassumedtobethedestinationtype.
ThefollowingexamplelistingshowstheJmsTemplatethatsendsmessagestoadynamicallycreatedJMS
topic:
Examplelisting8-8–UsingJmsTemplateforsendingmessagestodynamicJMStopicdestinations
--------------------------applicationContext.xml---------------------
<beanclass="org.springframework.jms.core.JmsTemplate"id="jmsTemplate">
<propertyname="connectionFactory"ref="cachingConnectionFactory"/>
<propertyname="defaultDestination"ref="FixedDepositDestination"/>
<propertyname="pubSubDomain"value="true"/>
</bean>
------------------Dynamictopiccreation------------------
jmsTemplate.send("dynamicTopic",newMessageCreator(){
publicMessagecreateMessage(Sessionsession)throwsJMSException{
session.createTopic("dynamicTopic");
ObjectMessageobjectMessage=session.createObjectMessage();
objectMessage.setObject(someObject);
returnobjectMessage;
}
});
In the above example listing, JmsTemplate’s pubSubDomain property is set to true, which means that
when dynamic destinations are used, Spring resolves a dynamic destinations name to a JMS topic.
NoticethatthenameoftheJMSdestinationpassedtoJmsTemplatessendmethodisdynamicTopic,anda
JMS topic with the same name is created by MessageCreator’s createMessage method. As no
dynamicTopic JMSdestinationis configured in the applicationcontextXML file, Spring doesn’tknow
whether the dynamicTopic JMS destination is a queue or a topic. As JmsTemplate’s pubSubDomain
property is set to true, Spring’s DynamicDestinationResolver resolves dynamicTopic JMS destination
nametothedynamicTopicJMStopiccreatedatruntimebyMessageCreator’screateMessagemethod.If
you had not set JmsTemplates pubSubDomain property, Springs DynamicDestinationResolver would
havetriedresolvingdynamicTopicJMSdestinationnametoadynamicTopicJMSqueue.
LetsnowlookathowJmsTemplatesimplifiessendingJavaobjectsasJMSmessages.
JmsTemplateandmessageconversion
JmsTemplate defines multiple convertAndSendmethods that convert and send a Java object as a JMS
message. By default, JmsTemplate is configured with a SimpleMessageConverter instance (an
implementationofSpringsMessageConverterinterface)thatconvertsJavaobjectstoJMSmessages,and
viceversa.
MessageConverterinterfacedefinesthefollowingmethods:
·ObjecttoMessage(Objectobject,Sessionsession)convertstheJavaobject(represented
byobjectargument)toaJMSMessageusingthesuppliedJMSSession(representedby
sessionargument)
·ObjectfromMessage(Messagemessage)-convertsMessageargumenttoJavaobject
Springs SimpleMessageConverter class provides conversion between String and JMS TextMessage,
byte[] and JMS BytesMessage, Map and JMS MapMessage, and Serializable object and JMS
ObjectMessage. If you want to modify the JMS Message created by JmsTemplate’s convertAndSend
method,youcanuseaMessagePostProcessorimplementationtomakemodifications.
The following example listing shows a scenario in which a MessagePostProcessor implementation is
usedtomodifytheJMSmessagecreatedbyJmsTemplate’sconvertAndSendmethod:
Examplelisting8-9–JmsTemplate’sconvertAndSendmethodusage
jmsTemplate.convertAndSend("aDestination","Hello,World!!",
newMessagePostProcessor(){
publicMessagepostProcessMessage(Messagemessage)throwsJMSException{
message.setBooleanProperty("printOnConsole",true);
returnmessage;
}
});
In the above example listing, ‘Hello, World !! string is passed to the convertAndSend method. The
convertAndSend method creates a JMS TextMessage instance and makes it available to the
MessagePostProcessorimplementationtoperformanypostprocessingofthemessagebeforeitissent.In
theaboveexamplelisting,MessagePostProcessorspostProcessMessagemethodsetsaprintOnConsole
propertyontheJMSmessagebeforeitissenttoaDestination.
SofarwehaveseenhowtosendJMSmessagestoJMSdestinationsusingJmsTemplate.Letsnowlook
at how to receive JMS messages from JMS destinations using JmsTemplate and Springs message
listenercontainers.
8-4ReceivingJMSmessages
You can receive JMS messages synchronously using JmsTemplate and asynchronously using Springs
messagelistenercontainers.
SynchronouslyreceivingJMSmessagesusingJmsTemplate
JmsTemplatedefinesmultiplereceivemethodsthatyoucanusetosynchronouslyreceiveJMSmessages.
ItisimportanttonotethatcalltoJmsTemplate’sreceivemethodcausesthecallingthreadtoblockuntila
JMS message is obtained from the JMS destination. To ensure that the calling thread is not blocked
indefinitely, you must specify an appropriate value for JmsTemplate’s receiveTimeout property. The
receiveTimeout property specifies the amount of time (in milliseconds) the calling thread should wait
beforegivingup.
JmsTemplate alsodefines multiplereceiveAndConvert methods thatautomaticallyconvert the received
JMS message toa Java object. By default, JmsTemplate uses SimpleMessageConverter for performing
conversions.
AsynchronouslyreceivingJMSmessagesusingmessagelistenercontainers
YoucanuseSpringsmessagelistenercontainerstoasynchronouslyreceiveJMSmessages.Amessage
listener container takes care of transaction and resource management aspects, so that you can focus on
writingthemessageprocessinglogic.
A message listener container receives messages from JMS destinations and dispatches them to JMS
MessageListenerimplementationsforprocessing.Thefollowingexamplelistingshowshowtoconfigure
amessagelistenercontainerusing<listener-container>elementofSpring’sjmsschema:
Examplelisting8-10–applicationContext.xml–messagelistenercontainerconfiguration
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
<beans.....xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation=".....
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms-4.0.xsd">
.....
<jms:listener-containerconnection-factory="cachingConnectionFactory"
destination-type="queue"transaction-manager="jmsTxManager">
<jms:listenerdestination="aQueueDestination"ref="FixedDepositMessageListener"/>
<jms:listenerdestination="emailQueueDestination"ref="emailMessageListener"/>
</jms:listener-container>
<beanclass="sample.spring.chapter08.bankapp.jms.EmailMessageListener"
id="emailMessageListener"/>
<beanclass="sample.spring.chapter08.bankapp.jms.FixedDepositMessageListener"
id="FixedDepositMessageListener"/>
.....
</beans>
In the above example listing, Springs jms schema is included so that its elements are available in the
applicationcontextXMLfile.The<listener-container>elementconfiguresamessagelistenercontainer
for each of the MessageListener implementations defined by <listener> sub-elements. The connection-
factory attribute specifies reference to the JMS ConnectionFactory bean that the message listener
container uses to obtain connections to the JMS provider. As we are using Springs
CachingConnectionFactory in the MyBank application, the connection-factory attribute refers to the
cachingConnectionFactorybeandefinedintheapplicationcontextXMLfileofMyBankapplication(refer
example listing 8-2). The destination-type attribute specifies the JMS destination type with which the
messagelistenercontainerisassociatedwith.Thepossiblevaluesthatthedestination-typeattributecan
acceptare:queue,topicanddurableTopic.
The transaction-manager attribute of <listener-container> element specifies a
PlatformTransactionManager implementation that ensures JMS message reception and message
processingbyMessageListenerhappenswithinatransaction.Intheaboveexamplelisting,thevalueof
transaction-managerattributereferstotheJmsTransactionManagerimplementation(referexamplelisting
8-4) configured for the MyBank application. If a MessageListener implementation interacts with other
transactional resources also, consider using Springs JtaTransactionManager instead of
JmsTransactionManager. In a standalone application, you can use embedded transaction managers, like
Atomikos(http://www.atomikos.com/),toperformJTAtransactionsinyourapplication.
NOTE By default, the <listener-container> element creates an instance of Springs
DefaultMessageListenerContainer class corresponding to each JMS MessageListener implementation
specifiedby<listener>sub-elements.
Each <listener> element specifies a JMS MessageListener implementation which is asynchronously
invoked by the message listener container. The <listener> elements destination attribute specifies the
JMSdestinationnamefromwhichMessageListenerimplementationreceivesitsmessagesviathemessage
listener container. The <listener> elements ref attribute specifies reference to the MessageListener
implementation responsible for processing the JMS messages received from the destination. Example
listing 8-10 shows that the FixedDepositMessageListener (a MessageListener implementation) is
responsible for processing messages received from aQueueDestination destination, and the
EmailMessageListener (a MessageListener implementation) is responsible for processing messages
receivedfromemailQueueDestinationdestination.
MessageListenerinterfacedefinesanonMessagemethodthatisasynchronouslyinvokedbythemessage
listener container. The message listener container passes the JMS Message received from the JMS
destinationtotheonMessagemethod.TheonMessagemethodisresponsibleforprocessingthereceived
JMS message. The following example listing shows implementation of MyBank application’s
FixedDepositMessageListenerthatisresponsibleforretrievingFixedDepositDetailsobjectfromtheJMS
Message,andthensavingthefixeddepositinformationcontainedintheFixedDepositDetailsobjectinto
thedatabase:
Examplelisting8-11–FixedDepositMessageListenerclass–processingJMSmessage
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/jms
packagesample.spring.chapter08.bankapp.jms;
importjavax.jms.MessageListener;
importjavax.jms.ObjectMessage;
importsample.spring.chapter08.bankapp.domain.FixedDepositDetails;
.....
publicclassFixedDepositMessageListenerimplementsMessageListener{
@Autowired
@Qualifier(value="FixedDepositDao")
privateFixedDepositDaomyFixedDepositDao;
@Autowired
privateBankAccountDaobankAccountDao;
@Transactional
publicintcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){
bankAccountDao.subtractFromAccount(fixedDepositDetails.getBankAccountId(),
fixedDepositDetails.getFixedDepositAmount());
returnmyFixedDepositDao.createFixedDeposit(fixedDepositDetails);
}
@Override
publicvoidonMessage(Messagemessage){
ObjectMessageobjectMessage=(ObjectMessage)message;
FixedDepositDetailsfixedDepositDetails=null;
try{
fixedDepositDetails=(FixedDepositDetails)objectMessage.getObject();
}catch(JMSExceptione){
e.printStackTrace();
}
if(fixedDepositDetails!=null){
createFixedDeposit(fixedDepositDetails);
}
}
}
In the above example listing, FixedDepositMessageListeners onMessage method obtains the
FixedDepositDetailsobjectfromtheJMSmessageandsavesthefixeddepositdetailsintothedatabase.
FixedDepositMessageListenerscreateFixedDeposit method is responsible for saving the fixed deposit
information into the database. As the createFixedDeposit method is annotated with @Transactional
annotation, it is executed under the transaction managed by DataSourceTransactionManager (refer the
applicationContext.xmlfileofch08-bankappproject).ThemessagelistenercontainerreceivestheJMS
messageandexecutesFixedDepositMessageListenersonMessagemethodunderthetransactionmanaged
byJmsTransactionManager(referexamplelisting8-10).
As onMessage and createFixedDeposit methods execute under different transaction managers, the
databaseupdateisnotrolledbackiftheJMStransactionfailsforsomereason,andtheJMSmessageis
not redelivered to the MessageListener if the database update fails for some reason. If you want JMS
messagereception(andprocessing)andthedatabaseupdatetobepartofthesametransaction,youshould
useJTAtransactions.
Inthissection,welookedathowtosendandreceiveJMSmessagesusingSpring.Let’snowlookathow
Springsimplifiessendingemails.
8-5Sendingemails
Spring simplifies sending emails from an application by providing a layer of abstraction on top of
JavaMailAPI.Springtakescareofresourcemanagementandexceptionhandlingaspects,sothatyoucan
focusonwritingthenecessarylogicrequiredtopreparetheemailmessage.
To send emails using Spring, you first need to configure Springs JavaMailSenderImpl class in your
application context XML file. The JavaMailSenderImpl class acts as a wrapper around JavaMail API.
The following example listing shows how JavaMailSenderImpl class is configured in MyBank
application:
Examplelisting8-12–applicationContext.xml–JavaMailSenderImplclassconfiguration
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
<beanid="mailSender"class="org.springframework.mail.javamail.JavaMailSenderImpl">
<propertyname="host"value="${email.host}"/>
<propertyname="protocol"value="${email.protocol}"/>
.....
<propertyname="javaMailProperties">
<props>
<propkey="mail.smtp.auth">true</prop>
<propkey="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
JavaMailSenderImpl class defines properties, like host, port, protocol, and so on, that provide
informationaboutthe mail server. The javaMailProperties property specifies configuration information
thatisusedbyJavaMailSenderImplinstanceforcreatingaJavaMailSessionobject.Themail.smtp.auth
property value is set to true, which means that SMTP (Simple Mail Transfer Protocol) is used for
authentication with the mail server. The mail.smtp.starttls.enable property value is set to true, which
meansTLS-protectedconnectionisusedforauthenticatingwiththemailserver.
Examplelisting8-12showsthatthevaluesofsomeofthepropertiesof JavaMailSenderImplclassare
specifiedusingpropertyplaceholders.Forinstance,hostpropertyvalueisspecifiedas${email.host}and
protocol property value as ${email.protocol}. The value of these property placeholders comes from
email.propertiesfilelocatedinsrc/main/resources/META-INF/springdirectory.Thefollowingexample
listingshowsthecontentsofemail.propertiesfile:
Examplelisting8-13–email.properties
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
email.host=smtp.gmail.com
email.port=587
email.protocol=smtp
email.username=<enter-email-id>
email.password=<enter-email-password>
The above example listing shows that email.properties file contains mail server information,
communicationprotocolinformation,andthemailaccounttouseforconnectingtothemailserver.The
propertiesspecifiedintheemail.propertiesfileareusedtoconfiguretheJavaMailSenderImpl instance
(referexamplelisting8-12).
NOTETheclassesthatprovideabstractionontopofJavaMailAPIaredefinedinspring-context-support
JARfile.So,touseSpringssupportforsendingemails,youmustdefinethatyourapplicationdependson
spring-context-supportJARfile.
Springs SimpleMailMessage class represents a simple email message. SimpleMailMessage defines
properties,liketo,cc,subject,text,andsoon,thatyoucansettoconstructtheemailmessagethatyou
wanttosendfromyourapplication.
The following example listing shows the MyBanks application context XML file that configures two
SimpleMailMessageinstancescorrespondingtothetwoemailmessagesthatwesendfromtheMyBank
application:
Examplelisting8-14–applicationContext.xml–SimpleMailMessageconfiguration
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
<beanclass="org.springframework.mail.SimpleMailMessage"id="requestReceivedTemplate">
<propertyname="subject"value="${email.subject.request.received}"/>
<propertyname="text"value="${email.text.request.received}"/>
</bean>
<beanclass="org.springframework.mail.SimpleMailMessage"id="requestProcessedTemplate">
<propertyname="subject"value="${email.subject.request.processed}"/>
<propertyname="text"value="${email.text.request.processed}"/>
</bean>
Intheaboveexamplelisting,therequestReceivedTemplatebeanrepresentstheemailmessagethatissent
to the customer informing that the request for opening a fixed deposit has been received, and
requestProcessedTemplatebeanrepresentstheemailmessagethatissenttothecustomerinformingthat
therequestforopeningthefixeddeposithasbeensuccessfullyprocessed.SimpleMailMessage’ssubject
property specifies the subject line of the email, and text property specifies the body of the email. The
values for these properties are defined in the emailtemplate.properties file, as shown in the following
examplelisting:
Examplelisting8-15–emailtemplate.properties
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring
email.subject.request.received=Fixeddepositrequestreceived
email.text.request.received=Yourrequestforcreatingthefixeddeposithasbeenreceived
email.subject.request.processed=Fixeddepositrequestprocessed
email.text.request.processed=Yourrequestforcreatingthefixeddeposithasbeenprocessed
We have so far seen how to configure JavaMailSenderImpl and SimpleMailMessage classes in the
applicationcontextXMLfile.Letsnowlookathowtosendemailmessages.
The following example listing shows the MyBank applications EmailMessageListener class (a JMS
MessageListener implementation) that retrieves customers email address from the JMS message and
sendsanemailtothecustomerinformingthattherequestforopeningafixeddeposithasbeenreceived:
Examplelisting8-16–EmailMessageListenerclass–sendingemailsusingMailSender
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/jms
packagesample.spring.chapter08.bankapp.jms;
importorg.springframework.mail.MailSender;
importorg.springframework.mail.SimpleMailMessage;
.....
publicclassEmailMessageListenerimplementsMessageListener{
@Autowired
privatetransientMailSendermailSender;
@Autowired
@Qualifier("requestReceivedTemplate")
privatetransientSimpleMailMessagesimpleMailMessage;
publicvoidsendEmail(){
mailSender.send(simpleMailMessage);
}
publicvoidonMessage(Messagemessage){
TextMessagetextMessage=(TextMessage)message;
try{
simpleMailMessage.setTo(textMessage.getText());
}catch(Exceptione){
e.printStackTrace();
}
sendEmail();
}
}
TheaboveexamplelistingshowsthattheMailSenderssendmethodsendstheemailmessagerepresented
by the SimpleMailMessage instance. As JavaMailSenderImpl class implements Springs MailSender
interface, the JavaMailSenderImpl instance (refer example listing 8-12) is autowired into the
EmailMessageListener instance. SimpleMailMessage instance named requestReceivedTemplate (refer
example listing 8-14) is also autowired into the EmailMessageListener instance. As
SimpleMailMessage’s to property identifies the email recipient, the onMessage method retrieves the
emailidofthecustomerfromtheJMSmessageandsetsitasthevalueoftoproperty.
SpringsMailSenderinterfacerepresentsagenericinterfacethatisindependentofJavaMailAPI,andis
suited for sending simple email messages. Springs JavaMailSender interface (a sub-interface of
MailSender)isdependentonJavaMailAPI,anddefinesthefunctionalityforsendingMIMEmessages.A
MIMEmessageisusedifyouwantto send emailscontaininginlineimages, attachments, andsoon.A
MIME message is represented by a MimeMessage class in JavaMail API. Spring provides a
MimeMessageHelperclassandaMimeMessagePreparatorcallbackinterfacethatyoucanusetocreate
andpopulateaMimeMessageinstance.
The following example listing shows the MyBank applications FixedDepositProcessorJob class that
subtractsthefixeddepositamountfromthecustomersbankaccountandsendsanemailtothecustomer
informingthattherequestforopeningthefixeddeposithasbeenprocessed:
Examplelisting8-17–FixedDepositProcessorJobclass–JavaMailSenderusage
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/job
packagesample.spring.chapter08.bankapp.job;
importjavax.mail.internet.MimeMessage;
importorg.springframework.mail.javamail.JavaMailSender;
publicclassFixedDepositProcessorJob{
.....
@Autowired
privatetransientJavaMailSendermailSender;
@Autowired
@Qualifier("requestProcessedTemplate")
privatetransientSimpleMailMessagesimpleMailMessage;
privateList<FixedDepositDetails>getInactiveFixedDeposits(){
returnmyFixedDepositDao.getInactiveFixedDeposits();
}
publicvoidsendEmail()throwsAddressException,MessagingException{
List<FixedDepositDetails>inactiveFixedDeposits=getInactiveFixedDeposits();
for(FixedDepositDetailsfixedDeposit:inactiveFixedDeposits){
MimeMessagemimeMessage=mailSender.createMimeMessage();
MimeMessageHelpermimeMessageHelper=newMimeMessageHelper(mimeMessage);
mimeMessageHelper.setTo(fixedDeposit.getEmail());
mimeMessageHelper.setSubject(simpleMailMessage.getSubject());
mimeMessageHelper.setText(simpleMailMessage.getText());
mailSender.send(mimeMessage);
}
myFixedDepositDao.setFixedDepositsAsActive(inactiveFixedDeposits);
}
}
TheaboveexamplelistingshowsthatJavaMailSenderssendmethodisusedtosendaMIMEmessage.
As JavaMailSenderImpl instance implements Springs JavaMailSender interface, JavaMailSenderImpl
instance (refer example listing 8-12) is autowired into the FixedDepositProcessorJob instance.
SimpleMailMessage instance named requestProcessedTemplate (refer example listing 8-14) is also
autowired intothe FixedDepositProcessorJob instance. The mailSender instance variable is defined of
type JavaMailSender (and not MailSender) because the FixedDepositProcessorJob creates and sends
MIMEmessages.FixedDepositProcessorJob’ssendEmailmethodcreatesaninstanceofaMimeMessage
using JavaMailSenders createMimeMessage method. Springs MimeMessageHelper is then used to
populatetheMimeMessageinstancewithto,subjectandtextproperties.
The following example listing shows how the FixedDepositProcessorJob’s sendEmail method can be
writtenusingSpringsMimeMessagePreparatorcallbackinterfaceinsteadofMimeMessageHelper:
Examplelisting8-18–MimeMessagePreparatorusage
importjavax.mail.Message;
importjavax.mail.internet.InternetAddress;
importorg.springframework.mail.javamail.MimeMessagePreparator;
publicclassFixedDepositProcessorJob{
.....
publicvoidsendEmail_()throwsAddressException,MessagingException{
List<FixedDepositDetails>inactiveFixedDeposits=getInactiveFixedDeposits();
for(finalFixedDepositDetailsfixedDeposit:inactiveFixedDeposits){
mailSender.send(newMimeMessagePreparator(){
@Override
publicvoidprepare(MimeMessagemimeMessage)throwsException{
mimeMessage.setRecipient(Message.RecipientType.TO,
newInternetAddress(fixedDeposit.getEmail()));
mimeMessage.setSubject(simpleMailMessage.getText());
mimeMessage.setText(simpleMailMessage.getText());
}
});
}
myFixedDepositDao.setFixedDepositsAsActive(inactiveFixedDeposits);
}
}
TheaboveexampleshowsthataMimeMessagePreparatorinstanceispassedtoJavaMailSenderssend
method to prepare a MimeMessage instance for sending. MimeMessagePreparator’s prepare method
providesanewinstanceofMimeMessagethatyouneedtopopulate.Intheaboveexamplelisting,notice
thatsettingtheMimeMessage’srecipientpropertyrequiresyoutodealwithlower-levelJavaMailAPI.In
example listing 8-17, MimeMessageHelpers setTo method accepted an email id of the recipient as a
stringargumenttosettheMimeMessagesrecipientproperty.Forthisreason,youshouldconsiderusing
MimeMessageHelper to populate the MimeMessage instance passed to the prepare method of
MimeMessagePreparator.
LetsnowlookathowyoucanuseSpringtoexecuteataskasynchronously,andtoscheduleexecutionofa
taskinthefuture.
8-6Taskschedulingandasynchronousexecution
You can asynchronously execute java.lang.Runnable tasks using Springs TaskExecutor, and you can
schedule execution ofjava.lang.Runnable tasks using Spring’s TaskScheduler. Instead of directly using
TaskExecutorandTaskScheduler,youcanuseSprings@Asyncand@Scheduledannotationstoexecutea
methodasynchronouslyandtoscheduleexecutionofamethod,respectively.
LetsfirstlookatTaskExecutorandTaskSchedulerinterfaces.
TaskExecutorinterface
Java 5 introduced the concept ofexecutors for executing java.lang.Runnable tasks. An executor
implements java.util.concurrent.Executor interface that defines a single method, execute(Runnable
runnable).SpringsTaskExecutorextendsjava.util.concurrent.Executorinterface.Springalsoprovidesa
couple of TaskExecutor implementations that you can choose from depending upon your applications
requirements. DependingupontheTaskExecutorimplementationyouchoose, the Runnable task may be
executed synchronously or asynchronously, using a thread pool or CommonJ, and so on. Some of the
TaskExecutor implementations provided by Spring are: ThreadPoolTaskExecutor (asynchronously
executestasksusingathreadfromathreadpool),SyncTaskExecutor(executestaskssynchronously)and
SimpleAsyncTaskExecutor(asynchronouslyexecuteseachtaskinanewthread).
ThreadPoolTaskExecutor is the most commonly used TaskExecutor implementation that uses Java 5’s
ThreadPoolExecutor to execute tasks. The following example listing shows how to configure a
ThreadPoolTaskExecutorinstanceintheapplicationcontextXMLfile:
Examplelisting8-19–ThreadPoolTaskExecutorconfiguration
<beanid="myTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<propertyname="corePoolSize"value="5"/>
<propertyname="maxPoolSize"value="10"/>
<propertyname="queueCapacity"value="15"/>
<propertyname="rejectedExecutionHandler"ref="abortPolicy"/>
</bean>

<beanid="abortPolicy"class="java.util.concurrent.ThreadPoolExecutor.AbortPolicy"/>
ThecorePoolSizepropertyspecifiestheminimumnumberofthreadsinthethreadpool.ThemaxPoolSize
property specifies the maximum number of threads that can be accommodated in the thread pool. The
queueCapacity property specifies the maximum number of tasks that can wait in the queue if all the
threadsinthethread pool arebusy executingtasks.TherejectedExecutionHandler propertyspecifiesa
handlerfortasksrejectedbytheThreadPoolTaskExecutor.AtaskisrejectedbyThreadPoolTaskExecutor
ifthequeueisfullandthereisnothreadavailableinthethreadpoolforexecutingthesubmittedtask.The
rejectedExecutionHandler property refers to an instance of
java.util.concurrent.RejectedExecutionHandlerobject.
In example listing 8-19, the rejectedExecutionHandler property refers to
java.util.concurrent.ThreadPoolExecutor.AbortPolicy instance that always throws
RejectedExecutionException. The other possible handlers for rejected tasks are:
java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy (the rejected task is executed in callers
thread), java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy (the handler discards the oldest
task from the queue and retries executing the rejected task), and
java.util.concurrent.ThreadPoolExecutor.DiscardPolicy(thehandlersimplydiscardstherejectedtask).
The <executor> element of Springs task schema simplifies configuring a ThreadPoolTaskExecutor
instance,asshowninthefollowingexamplelisting:
Examplelisting8-20–ThreadPoolTaskExecutorconfigurationusingSpringstaskschema
<beans.....xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation=".....http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd">
<task:executorid="myTaskExecutor"pool-size="5-10"
queue-capacity="15"rejection-policy="ABORT"/>
</beans>
Intheaboveexamplelisting,the<executor>elementconfiguresaThreadPoolTaskExecutorinstance.The
pool-sizeattributespecifiesthecorepoolsizeandthemaximumpoolsize.Intheaboveexamplelisting,5
is the core pool size and 10 is the maximum pool size. The queue-capacity attribute sets the
queueCapacity property, and rejection-policy attribute specifies the handler for rejected tasks. The
possible values of rejection-policy attribute are ABORT, CALLER_RUNS, DISCARD_OLDEST, and
DISCARD.
OnceyouhaveconfiguredaThreadPoolTaskExecutorinstancebyexplicitlydefiningitasaSpringbean
(referexamplelisting8-19)orbyusingSpringstaskschema(referexamplelisting8-20),youcaninject
theThreadPoolTaskExecutorinstanceintobeansthatwanttoasynchronouslyexecutejava.lang.Runnable
tasks,asshowninthefollowingexamplelisting:
Examplelisting8-21–ExecutingtasksusingThreadPoolTaskExecutor
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.core.task.TaskExecutor;
@Component
publicclassSample{
@Autowired
privateTaskExecutortaskExecutor;

publicvoidexecuteTask(Runnabletask){
taskExecutor.execute(task);
}
}
Intheaboveexamplelisting,aninstanceofThreadPoolTaskExecutorisautowiredintotheSampleclass,
andislaterusedbySample’sexecuteTaskmethodtoexecuteajava.lang.Runnabletask.
TaskExecutor executes a java.lang.Runnable task immediately after it is submitted, and the task is
executedonlyonce.Ifyouwanttoscheduleexecutionofajava.lang.Runnabletask,andyouwantthetask
tobeexecutedperiodically,youshoulduseaTaskSchedulerimplementation.
TaskSchedulerinterface
SpringsTaskScheduler interface provides the abstraction to schedule execution of java.lang.Runnable
tasks.  Springs Trigger interface abstracts the time when a java.lang.Runnable task is executed. You
associateaTaskSchedulerinstancewithaTriggerinstancetoscheduleexecutionofjava.lang.Runnable
tasks.PeriodicTrigger(animplementationofTriggerinterface)isusedifyouwantperiodicexecutionof
tasks.CronTrigger(anotherimplementationofTriggerinterface)acceptsacronexpressionthatindicates
thedate/timewhenthetaskisexecuted.
ThreadPoolTaskScheduler is one of the most commonly used implementations of TaskScheduler that
internally uses Java 5’s ScheduledThreadPoolExecutor (an implementation of Java 5’s
ScheduledExecutorService interface) to schedule task execution. You can configure a
ThreadPoolTaskSchedulerimplementationandassociateitwithaTriggerimplementationtoscheduletask
execution.ThefollowingexamplelistingshowshowThreadPoolTaskSchedulerisconfiguredandused:
Examplelisting8-22–ThreadPoolTaskExecutorconfigurationandusage
------------ThreadPoolTaskSchedulerconfiguration---------------------
<beanid="myScheduler"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<propertyname="poolSize"value="5"/>
</bean>
---------------ThreadPoolTaskSchedulerusage---------------------
importorg.springframework.scheduling.TaskScheduler;
importorg.springframework.scheduling.support.PeriodicTrigger;
@Component
publicclassSample{
@Autowired
@Qualifier("myScheduler")
privateTaskSchedulertaskScheduler;
publicvoidexecuteTask(Runnabletask){
taskScheduler.schedule(task,newPeriodicTrigger(5000));
}
}
In the above example listing, ThreadPoolTaskSchedulers poolSize property specifies the number of
threadsinthethreadpool.Toscheduleataskforexecution,ThreadPoolTaskSchedulersschedulemethod
is called, passing the java.lang.Runnable task and a Trigger instance. In the above example listing,
PeriodicTriggerinstanceispassedtoThreadPoolTaskSchedulersschedulemethod.Theargumenttothe
PeriodicTriggerconstructorspecifiesthetimeinterval(inmilliseconds)betweentaskexecutions.
The <scheduler> element of Springs task schema simplifies configuring a ThreadPoolTaskScheduler
instance.TheThreadPoolTaskSchedulerinstancecreatedbythe<scheduler>elementcanbeusedbythe
<scheduled-tasks>elementofSpring’staskschematoscheduleexecutionofbeanmethods.Thefollowing
examplelistingshowshow<scheduler>and<scheduled-tasks>elementsareusedbyMyBankapplication
toexecuteFixedDepositProcessorJob’ssendEmailmethodevery5seconds:
Examplelisting8-23–<scheduler>and<scheduled-tasks>elements
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/job
<task:schedulerid="emailScheduler"pool-size="10"/>
<task:scheduled-tasksscheduler="emailScheduler">
<task:scheduledref="FixedDepositProcessorJob"method="sendEmail"fixed-rate="5000"/>
</task:scheduled-tasks>

<beanid="FixedDepositProcessorJob"
class="sample.spring.chapter08.bankapp.job.FixedDepositProcessorJob"/>
In theaboveexamplelisting,the<scheduler>elementconfiguresaThreadPoolTaskScheduler instance.
Theidattributeofthe<scheduler>elementspecifiesthenamewithwhichtheThreadPoolTaskScheduler
instanceisaccessedbyotherbeansintheSpringcontainer.The<scheduled-tasks>element’sscheduler
attribute specifies reference to the ThreadPoolTaskScheduler instance that is used for scheduling
executionofbeanmethods.Intheaboveexamplelisting,theThreadPoolTaskSchedulerinstancecreated
bythe<scheduler>elementisreferencedbythe<scheduled-tasks>elementsscheduledattribute.
The<scheduled-tasks>element contains one or more <scheduled>elements. The <scheduled> element
containsinformationaboutthebeanmethodtobeexecutedandthetriggerforthebeanmethodexecution.
TherefattributespecifiesreferencetoaSpringbean,themethodattributespecifiesamethodofthebean
referencedbytherefattribute,andthefixed-rate attribute (an interval-based trigger)specifiesthetime
interval between successive method executions. In example listing 8-23, the <scheduled> element
specifiesthatFixedDepositProcessorJob’ssendEmailmethodisexecutedevery5seconds.
Instead of using fixed-rate attribute of the <scheduled> element, you can use fixed-delay (an interval-
basedtrigger)orcron(acron-basedtrigger)ortrigger(referencetoaTriggerimplementation)attribute,
tospecifyatriggerforthebeanmethodexecution.
LetsnowlookatSprings@Asyncand@Scheduledannotations.
@Asyncand@Scheduledannotations
IfyouannotateabeanmethodwithSprings@Asyncannotation,itisasynchronouslyexecutedbySpring.
If you annotate a bean method with Springs @Scheduled annotation, it is scheduled for execution by
Spring.
Useof@Asyncand@Scheduledannotationsisenabledby<annotation-driven>elementofSpringstask
schema,asshowninthefollowingexamplelisting:
Examplelisting8-24–Enabling@Asyncand@Scheduledannotations
<task:annotation-drivenexecutor="anExecutor"scheduler="aScheduler"/>
<task:executorid="anExecutor"/>

<task:scheduled-tasksscheduler="aScheduler">
<task:scheduledref="sampleJob"method="doSomething"fixed-rate="5000"/>
</task:scheduled-tasks>
The<annotation-driven>elementsexecutorattributespecifiesreferencetoaSpringsTaskExecutor(or
Java5’sExecutor)instancethatisusedforexecuting@Asyncannotatedmethods.Theschedulerattribute
specifiesreferencetoaSpringsTaskScheduler(orJava5’sScheduledExecutorService)instancethatis
usedforexecuting@Scheduledannotatedmethods.
Letsnowlookat@Asyncannotationindetail.
@Asyncannotation
Thefollowingexamplelistinghighlightssomeoftheimportantpointsthatyouneedtoknowwhenusing
@Asyncannotation:
Examplelisting8-25–@Asyncannotationusage
importjava.util.concurrent.Future;
importorg.springframework.scheduling.annotation.Async;
importorg.springframework.scheduling.annotation.AsyncResult;
importorg.springframework.stereotype.Component;
@Component
publicclassSample{
@Async
publicvoiddoA(){.....}

@Async(value="someExecutor")
publicvoiddoB(Stringstr){.....}

@Async
publicFuture<String>doC(){
returnnewAsyncResult<String>("Hello");
}
}
@AsyncannotationsvalueattributespecifiestheSpringsTaskExecutor(orJava5’sExecutor)instance
to use for asynchronously executing the method. Asthe@Async annotation on the doA method doesn’t
specifytheexecutortouse,SpringsSimpleAsyncTaskExectorisusedforasynchronouslyexecutingthe
doA method. @Async annotation on the doB method specifies the value attribute’s value as
someExecutor,whichmeansthebeannamedsomeExecutor(oftypeTaskExecutororJava5’sExecutor)is
usedforasynchronouslyexecutingthedoBmethod.@Asyncannotatedmethodscanacceptarguments,like
thedoBmethodintheaboveexamplelisting.@Asyncannotatedmethodscaneitherreturnvoid(likethe
doA and doB methods) or a Future instance (like the doC method). To return a Future instance, youll
need to wrap the value that you want to return into an AsyncResult object, and return the AsyncResult
object.
Letsnowlookat@Scheduledannotationindetail.
@Scheduledannotation
Thefollowingexamplelistinghighlightssomeoftheimportantpointsthatyouneedtoknowwhenusing
@Scheduledannotation:
Examplelisting8-26–@Scheduledannotationusage
importorg.springframework.scheduling.annotation.Scheduled;
@Component
publicclassSample{
@Scheduled(cron="009-17**MON-FRI")
publicvoiddoA(){.....}
@Scheduled(fixedRate=5000)
publicvoiddoB(){.....}
}
Amethodannotatedwith@Scheduledannotationmustreturnvoidandmustnotbedefinedtoacceptany
arguments.Youmustspecifycron,fixedRateorfixedDelayattributeof@Scheduledannotation.
Itisimportanttonotethatifthe@Async(or@Scheduled)annotationisspecifiedononeormoremethods
ofaclass,youarerequiredtoincludeCGLIBJARfileinyourapplicationsclasspath.Ifthe@Async(or
@Scheduled) annotation is specified only on the methods defined in an interface, you dont need to
includeCGLIBJARfile.StartingwithSpring3.2,theCGLIBclassesarepackagedwithinthespring-core
JARfileitself;therefore,youdontneedtoexplicitlyspecifythatyourprojectisdependentonCGLIB
JARfile.
NOTEIfyouwanttousetheQuartzScheduler(http://quartz-scheduler.org/)inyourSpringapplication,
youcanusetheintegrationclassesprovidedbySpringthatsimplifyusingtheQuartzScheduler.
Spring simplifies using caching in an application by providing an abstraction on top of
java.util.concurrent.ConcurrentMapandEhcache(http://ehcache.org/).
8-7Caching
Ifyouwanttousecachinginyourapplication,youcanconsiderusingSpringscacheabstraction.Springs
cacheabstractionshieldsdevelopersfromdirectlydealingwiththeunderlyingcachingimplementations
API. Starting with Spring 3.2, cache abstraction is available out-of-the-box for
java.util.concurrent.ConcurrentMap,Ehcache and for caching solutions that implement JSR 107 – Java
TemporaryCachingAPI(referredtoasJCACHE).
NOTEIfyouareusingacachingsolutionwhichisnotcurrentlysupportedbySpringscacheabstraction,
you have the option to either directly use the API of the caching solution or create adapters that map
Springscacheabstractiontothecachingsolution.
Spring provides a CacheManager interface that defines methods for managing a collection of Cache
instances. A CacheManager instance acts as a wrapper around the cache manager provided by the
underlying caching solution. For instance, EhCacheCacheManager is a wrapper around Ehcache’s
net.sf.ehcache.CacheManager, JCacheCacheManager is a wrapper around JSR 107 providers
javax.cache.CacheManager implementation, and so on. A Cache instance is a wrapper around the
underlying cache, and it provides methods for interacting with the underlying cache. For instance,
EhCacheCache (a Cache implementation) is a wrapper around net.sf.ehcache.Ehcache, and
JCacheCache (a Cache implementation) is a wrapper around JSR 107 providers javax.cache.Cache
instance.
Spring also provides a ConcurrentMapCacheManager that you can use if you want to use
java.util.concurrent.ConcurrentMap as the underlying cache. The Cache instance managed by
ConcurrentMapCacheManager is a ConcurrentMapCache. The following diagram summarizes
relationshipbetweenCacheManagerandCacheinterfacesprovidedbySpringscachingabstraction:
NOTE If you want to use Springs caching abstraction for a caching solution that is not currently
supported by Springs caching abstraction, all you need to do is to provide CacheManager and Cache
implementationsforthecachingsolution.
Figure8-3ACacheManagerimplementationactsaswrapperaroundthecachemanageroftheunderlying
cachingsolution,andaCacheimplementationprovidesoperationstointeractwiththeunderlyingcache.
TheabovefigureshowsthatCacheManagermanagesCacheinstances.EhCacheCacheManagermanages
EhCacheCache instances (underlying cache store is Ehcache), JCacheCacheManager manages
JCacheCache instances (underlying cache store is a caching solution that implements JSR 107),
ConcurrentMapCacheManager manages ConcurrentMapCache instances (underlying cache store is
java.util.concurrent.ConcurrentMap),andsoon.
Figure 8-3 shows a SimpleCacheManager class that implements CacheManager interface.
SimpleCacheManagerisusefulforsimplecachingscenariosandfortestingpurposes.Forinstance,ifyou
want to use java.util.concurrent.ConcurrentMap as the underlying cache store, you can use
SimpleCacheManager,insteadofConcurrentMapCacheManager,tomanagethecache.
LetsnowlookathowaCacheManagerisconfiguredintheapplicationcontextXMLfile.
ConfiguringaCacheManager
In MyBank application, a collection of java.util.concurrent.ConcurrentMap instances are used as the
underlyingcachestore;therefore,SimpleCacheManagerisusedtomanagethecache.
The following example listing shows how a SimpleCacheManager instance is configured in MyBank
application:
Examplelisting8-27–SimpleCacheManagerconfiguration
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring/
<beanid="myCacheManager"
class="org.springframework.cache.support.SimpleCacheManager">
<propertyname="caches">
<set>
<bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<propertyname="name"value="FixedDepositList"/>
</bean>
<bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<propertyname="name"value="FixedDeposit"/>
</bean>
</set>
</property>
</bean>
SimpleCacheManagers caches property specifies a collection of caches managed by the
SimpleCacheManagerinstance.ConcurrentMapCacheFactoryBeanisaFactoryBeanimplementationthat
simplifies configuring a ConcurrentMapCache instance - a Cache instance that uses a
java.util.concurrent.ConcurrentHashMap instance (an implementation of
java.util.concurrent.ConcurrentMap interface) as the underlying cache store.
ConcurrentMapCacheFactoryBean’snamepropertyspecifiesanameforthecache.Intheaboveexample
listing,theFixedDepositListandFixedDepositcachesaremanagedbytheSimpleCacheManagerinstance.
LetsnowlookathowtouseSpringscachingannotationsinapplications.
Cachingannotations-@Cacheable,@CacheEvictand@CachePut
AfteryouhaveconfiguredanappropriateCacheManagerforyourapplication,youneedtochoosehow
you want to use Springs cache abstraction. You can use Springs cache abstraction either by using
caching annotations (like @Cacheable, @CacheEvict and @CachePut) or by using Springs cache
schema.AsusingSpringscacheschemaforcachingresultsinaverboseapplicationcontextXMLfile,
we’llbeonlylookingatusingcachingannotationsfordeclarativecaching.
Tousecachingannotations,youneedtoconfigure<annotation-driven>elementofSpringscacheschema,
asshownherefortheMyBankapplication:
Examplelisting8-28–Enablecachingannotationsusing<annotation-driven>
Project–ch08-bankapp
Sourcelocation-src/main/resources/META-INF/spring/
<beans.....xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation=".....
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-drivencache-manager="myCacheManager"/>
.....
</beans>
Intheaboveexamplelisting,Springscacheschemaisincludedsothatitselementsareaccessibleinthe
application context XML file. The <annotation-driven>element’s cache-manager attribute refers to the
CacheManager bean that is used for managing the cache. You don’t need to specify the cache-manager
attributeiftheCacheManagerbeanisnamedcacheManager.
Now,thatwehaveenabledcachingannotations,letslookatdifferentcachingannotations.
@Cacheable
@Cacheableannotationonamethodindicatesthatthevaluereturnedbythemethodiscached.Springs
DefaultKeyGeneratorclassisusedbydefaulttogeneratethekeywithwhichthemethod’sreturnvalueis
stored in the cache. DefaultKeyGenerator uses method signature and method arguments to compute the
key. You can use a custom key generator by providing an implementation of Springs KeyGenerator
interface,andspecifyingitasthevalueofkey-generatorattributeof<annotation-driven>element.
Thefollowingexamplelistingshowstheusageof@Cacheableannotationtocachethevaluereturnedby
FixedDepositService’sfindFixedDepositsByBankAccountmethodintheMyBankapplication:
Examplelisting8-29–@Cacheableannotation
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/service
packagesample.spring.chapter08.bankapp.service;
importorg.springframework.cache.annotation.Cacheable;
.....
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
@Cacheable(value={"FixedDepositList"})
publicList<FixedDepositDetails>findFixedDepositsByBankAccount(intbankAccountId){
logger.info("findFixedDepositsByBankAccountmethodinvoked");
returnmyFixedDepositDao.findFixedDepositsByBankAccount(bankAccountId);
}
}
@Cacheable annotations value attribute specifies the cache region into which the returned value is
cached.Inlisting8-27,wecreatedacacheregionnamedFixedDepositListfortheMyBankapplication.In
the above example listing, the @Cacheable annotation specifies that the value returned by the
findFixedDepositsByBankAccountmethodisstoredintheFixedDepositListcache.Itisimportanttonote
that@Cacheableannotatedmethod is notinvokedif the samesetofargumentvaluesarepassed tothe
method.But,@Cacheableannotatedmethodwillbeinvokedifyoupassadifferentvalueforatleastone
ofthearguments.
@CacheEvict
If you want to evict data from the cache when a method is called, annotate the method with the
@CacheEvict annotation. In the MyBank application, when a new fixed deposit is created, the fixed
depositdetailscachedbyFixedDepositServiceImplsfindFixedDepositsByBankAccountmethodmustbe
evictedfromthecache.ThisensuresthatwhenthenexttimefindFixedDepositsByBankAccountmethodis
invoked,thenewlycreatedfixeddepositisalsofetchedfromthedatabase.Thefollowingexamplelisting
showsusageof@CacheEvictannotation:
Examplelisting8-30–@CacheEvictannotation
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/service
packagesample.spring.chapter08.bankapp.service;
importorg.springframework.cache.annotation.CacheEvict;
.....
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
@Transactional("jmsTxManager")
@CacheEvict(value={"FixedDepositList"},allEntries=true,beforeInvocation=true)
publicvoid createFixedDeposit(final FixedDepositDetails fixedDepositDetails) throws Exception{
.....}
.....
}
In the above example listing, the @CacheEvict annotation on the createFixedDeposit method instructs
Spring to remove all the cached entries from the cache region named FixedDepositList. The value
attributespecifiesthecacheregionfromwhichtoevictthecacheditem,andallEntriesattributespecifies
whetherornotallentriesfromthespecifiedcacheregionareevicted.Ifyouwanttoevictaparticular
cacheditem,usethekeyattributetospecifythekeywithwhichtheitemiscached.Youcanalsospecify
conditional eviction of items by using the condition attribute. The condition and key attributes support
specifying values using SpEL (refer section 6-8 of chapter 6 for more details), making it possible to
perform sophisticated cache evictions. The beforeInvocation attribute specifies whether the cache
evictionisperformedbeforeorafterthemethodexecution.AsthevalueofbeforeInvocationattributeis
settotrue,cacheisevictedbeforethecreateFixedDepositmethodisinvoked.
@CachePut
Spring also provides a @CachePut annotation that indicates that a method isalways invoked, and the
value returned by the method is put into the cache. @CachePut annotation is different from the
@Cacheable annotation in the sense that @Cacheable annotation instructs Spring to skip the method
invocationifthemethodiscalledwiththesamesetofargumentvalues.
Thefollowingexamplelistingshowsusageof@CachePutannotationbyFixedDepositServiceImplclass
ofMyBankapplication:
Examplelisting8-31–@CachePutannotation
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/service
packagesample.spring.chapter08.bankapp.service;
importorg.springframework.cache.annotation.CachePut;
importorg.springframework.cache.annotation.Cacheable;
.....
@Service(value="FixedDepositService")
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
@CachePut(value={"FixedDeposit"},key="#FixedDepositId")
publicFixedDepositDetailsgetFixedDeposit(intFixedDepositId){
logger.info("getFixedDepositmethodinvokedwithFixedDepositId"+FixedDepositId);
returnmyFixedDepositDao.getFixedDeposit(FixedDepositId);
}
@Cacheable(value={"FixedDeposit"},key="#FixedDepositId")
publicFixedDepositDetailsgetFixedDepositFromCache(intFixedDepositId){
logger.info("getFixedDepositFromCachemethodinvokedwithFixedDepositId"
+FixedDepositId);
thrownewRuntimeException("Thismethodthrowsexceptionbecause"
+"FixedDepositDetailsobjectmustcomefromthecache");
}
.....
}
Intheaboveexamplelisting,thegetFixedDepositmethodisannotatedwith@CachePutannotation,which
meansthatthegetFixedDepositmethodisalwaysinvoked,andthereturnedFixedDepositDetailsobjectis
storedintothecachenamedFixedDeposit.Thevalueattributespecifiesthenameofthecacheintowhich
theFixedDepositDetails objectis stored. The key attribute specifies the key to be used for storing the
returnedFixedDepositDetailsobjectintothecache.Asyoucansee,keyattributemakesuseofSpELto
specifythekey.The#FixedDepositIdvalueofkeyattributereferstotheFixedDepositIdargumentpassed
to the getFixedDeposit method. To summarize, the FixedDepositDetails object returned by the
getFixedDeposit method is stored in the cache named FixedDeposit, and the value of FixedDepositId
methodargumentisusedasthekey.
In example listing 8-31, FixedDepositServiceImpls getFixedDepositFromCache method retrieves the
FixedDepositDetailsobjectfromthecachebasedonthekeyattributevaluespecifiedbythe@Cacheable
annotation. Notice that the body of the getFixedDepositFromCache method does nothing but throw a
RuntimeException. The key attribute value refers to the FixedDepositId argument passed to the
getFixedDepositFromCache method. If the FixedDepositDetails object is not found in the cache, the
getFixedDepositFromCachemethodisinvoked,whichwillresultinRuntimeException.
LetsnowlookatwhathappenswhenyouruntheMyBankapplicationofch08-bankappproject.
8-8RunningtheMyBankapplication
BankApp class of MyBank application defines the main method of the application. The main method
accesses methods of FixedDepositService and BankAccountService instances to demonstrate different
featuresthatwediscussedinthischapter.
ThefollowingexamplelistingshowstheMyBankapplicationsBankAppclass:
Examplelisting8-32–BankAppclass
Project–ch08-bankapp
Sourcelocation-src/main/java/sample/spring/chapter08/bankapp
packagesample.spring.chapter08.bankapp;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassBankApp{
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
BankAccountServicebankAccountService=context.getBean(BankAccountService.class);
BankAccountDetailsbankAccountDetails=newBankAccountDetails();
.....
intbankAccountId=bankAccountService.createBankAccount(bankAccountDetails);
FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();
.....
fixedDepositDetails.setEmail("someUser@someDomain.com");
FixedDepositService.createFixedDeposit(fixedDepositDetails);
.....
FixedDepositService.findFixedDepositsByBankAccount(bankAccountId);
FixedDepositService.findFixedDepositsByBankAccount(bankAccountId);
FixedDepositService.createFixedDeposit(fixedDepositDetails);
.....
List<FixedDepositDetails>FixedDepositDetailsList=FixedDepositService
.findFixedDepositsByBankAccount(bankAccountId);
for(FixedDepositDetailsdetail:FixedDepositDetailsList){
FixedDepositService.getFixedDeposit(detail.getFixedDepositId());
}
for(FixedDepositDetailsdetail:FixedDepositDetailsList){
FixedDepositService.getFixedDepositFromCache(detail.getFixedDepositId());
}
.....
}
}
Intheaboveexamplelisting,followingsequenceofactionsareperformedbythemainmethod:
Step 1. First, a bank account is created in the BANK_ACCOUNT_DETAILS table by calling
BankAccountServicescreateBankAccountmethod.
Step 2. Corresponding to the newly created bank account, a fixed deposit is created in the
FIXED_DEPOSIT_DETAILS table by calling FixedDepositServices createFixedDeposit method. You
shouldmakesurethatemailpropertyofFixedDepositDetailsobjectissettotheemailidwhereyoucan
checktheemails.ThecreateFixedDepositmethodsends2JMSmessages(referexamplelisting8-5).One
JMSmessagecontainstheemailidspecifiedbytheFixedDepositDetailsobjectsemailproperty,andis
processedbyEmailMessageListener(referexamplelisting8-16)thatsendsanemailtothecustomer.The
otherJMSmessageisprocessedbyFixedDepositMessageListener(referexamplelisting8-11)thatsaves
the fixed deposit details in the FIXED_DEPOSIT_DETAILS table. You should also note that
FixedDepositServiceImplscreateFixedDepositmethodisannotatedwith@CacheEvictannotation(refer
examplelisting8-30)thatresultsinremovingalltheitemscachedinFixedDepositListcache.
Step3.FixedDepositService’sfindFixedDepositsByBankAccountmethodisinvokedthatretrievesfixed
deposits corresponding to the bank account that we created in Step 1. As the
findFixedDepositsByBankAccount method is annotated with @Cacheable annotation (refer example
listing8-29),fixeddepositsreturnedbythefindFixedDepositsByBankAccountmethodarestoredinthe
cache named FixedDepositList. Listing 8-29 showed that findFixedDepositsByBankAccount method
writesthefollowingmessagetotheconsolefindFixedDepositsByBankAccountmethodinvoked.Inthe
aboveexamplelisting,thefindFixedDepositsByBankAccountiscalledtwiceforthesamebankAccountId
argument,butyou’llnoticethatonlyoncefindFixedDepositsByBankAccountmethodinvokediswritten
to the console. This is because the second call to the findFixedDepositsByBankAccount results in
retrieving fixed deposit details from the cache named FixedDepositList, and the
findFixedDepositsByBankAccountmethodisnotexecuted.
Step 4. Corresponding to the bank account created in Step 1, another fixed deposit is created in the
FIXED_DEPOSIT_DETAILStablebycallingFixedDepositService’screateFixedDepositmethod.Now,
the FixedDepositServiceImpls createFixedDeposit method is annotated with @CacheEvict annotation
(referexamplelisting8-30)thatresultsinremovingalltheitemscachedinFixedDepositListcache.
Step 5. FixedDepositService’s findFixedDepositsByBankAccount method is invoked once again. This
time findFixedDepositsByBankAccount is executed because the previous call to createFixedDeposit
method (refer Step 4) resulted in evicting all the items from the FixedDepositList cache. At this time,
you’ll once again see ‘findFixedDepositsByBankAccount method invoked message written on the
console. The fixed deposits returned by the findFixedDepositsByBankAccount method are cached in
FixedDepositListcachebecausethemethodisannotatedwith@Cacheableannotation.
Step6.ForeachfixeddepositretrievedinStep5,FixedDepositService’sgetFixedDepositmethod(refer
example listing 8-31) is invoked. The getFixedDeposit method accepts the fixed deposit identifier and
returns the fixed depositinformation from the database. The getFixedDeposit method is annotated with
@CachePut,whichmeansitisalwaysinvoked.ThefixeddepositreturnedbythegetFixedDepositmethod
iscachedintheFixedDepositcache.
Step7.For eachfixed depositretrieved in Step 5,FixedDepositService’s getFixedDepositFromCache
method(referexamplelisting8-31)isinvoked.ThegetFixedDepositFromCachemethodacceptsthefixed
depositidentifierandthrowsaRuntimeExceptiononexecution.ThegetFixedDepositFromCachemethod
is annotated with @Cacheable, and is executed only when the fixed deposit is not found in the
FixedDepositcache.AsallthefixeddepositswerecachedbythegetFixedDepositmethodinStep6,the
getFixedDepositFromCachemethodisneverexecuted.
Step8.Every5seconds,theFixedDepositProcessorJob(referexamplelisting8-17)checksifanynew
fixed deposits have been created in the database. If new fixed deposits are found in the database, the
FixedDepositProcessorJobactivatesthefixeddepositandsendsanemailtothecustomer,confirmingthat
thefixeddepositrequesthasbeensuccessfullyprocessed.
8-9Summary
In this chapter, we touched upon some of the frequently used features of Spring. We saw that Spring
simplifiessendingandreceivingJMSmessages,sendingemails,asynchronouslyinvokingbeanmethods,
scheduling bean methods for execution, and caching data. In the next chapter, we’ll look at Springs
supportforAOP(Aspect-orientedprogramming).
Chapter9-Aspect-orientedprogramming
9-1Introduction
Aspect-oriented programming (AOP) is a programming approach in which responsibilities that are
distributedacrossmultipleclassesareencapsulatedintoaseparateclass,referredtoasanaspect.The
responsibilities that are distributed across multiple classes are referred to as ‘cross-cutting concerns’.
Logging,transactionmanagement,caching,security,andsoon,areexamplesofcross-cuttingconcerns.
Spring provides an AOP framework that is used internally by Spring for implementing declarative
services, like transaction management (refer chapter 7) and caching (refer chapter 8). Instead of using
Spring AOP framework, you can consider using AspectJ (http://www.eclipse.org/aspectj/) as the AOP
framework for your application. As Spring AOP framework is sufficient for most AOP scenarios, and
providesintegrationwiththeSpringcontainer,thischapterfocusesonSpringAOPframework.
LetsbeginthischapterbylookingatanexampleusageofAOP.
9-2AsimpleAOPexample
Letssaythatforauditingpurposeswewanttocapturetheargumentspassedtothemethodsofclasses
definedintheservicelayerofMyBankapplication.Asimpleapproachtologdetailsofmethodarguments
istowritethelogginglogicinsideeachmethod.But,thiswouldmeanthateachmethodisadditionally
responsible for logging details of method arguments. As the responsibility to log details of method
argumentsisdistributedacrossmultipleclassesandmethods,itrepresentsacross-cuttingconcern.
Toaddressacross-cuttingconcernusingAOP,youneedtofollowthesesteps:
·createaJavaclass(referredtoasanaspect)
·addimplementationofthecross-cuttingconcerntotheJavaclass,and
·usearegularexpressiontospecifythemethodstowhichthecross-cuttingconcernapplies
IntermsofAOPterminology,themethodsofanaspectthatimplementcross-cuttingconcernsarereferred
toasadvices. And, each advice is associated with a pointcut that identifies the methods to which the
adviceapplies.Themethodstowhichanadviceappliesarereferredtoasjoinpoints.
InSpringAOP,youhavetheoptiontodevelopanaspectusingAspectJannotation-styleorXMLschema-
style. InAspectJannotation-style,AspectJannotations,like@Aspect,@Pointcut,@Before, and so on,
are used to develop an aspect. In XML schema-style, elements of Springs aop schema are used to
configureaSpringbeanasanaspect.
IMPORTchapter9/ch09-simple-aop(Thech09-simple-aopprojectshowstheMyBankapplicationthat
usesSpringAOPtologdetailsofmethodargumentspassedtothemethodsdefinedbytheclassesinthe
service layerof MyBank application. To runthe application, execute the main method of the BankApp
classofthisproject)
The following example listing shows the logging aspect that logs details of the arguments passed to
servicemethodsinMyBankapplication:
Examplelisting9-1–LoggingAspectclass
Project–ch09-simple-aop
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspects
packagesample.spring.chapter09.bankapp.aspects;
importorg.aspectj.lang.JoinPoint;
importorg.aspectj.lang.annotation.Aspect;
importorg.aspectj.lang.annotation.Before;
importorg.springframework.stereotype.Component;
@Aspect
@Component
publicclassLoggingAspect{
privateLoggerlogger=Logger.getLogger(LoggingAspect.class);
@Before(value="execution(*sample.spring.chapter09.bankapp.service.*Service.*(..))")
publicvoidlog(JoinPointjoinPoint){
logger.info("Entering"
+joinPoint.getTarget().getClass().getSimpleName()+"'s"
+joinPoint.getSignature().getName());
Object[]args=joinPoint.getArgs();
for(inti=0;i<args.length;i++){
logger.info("args["+i+"]-->"+args[i]);
}
}
}
Inexamplelisting9-1:
·AspectJ’s@Aspecttype-levelannotationspecifiesthattheLoggingAspectclassisanAOPaspect
·AspectJs@Beforemethod-levelannotationspecifiesthatthelogmethodrepresentsanadvicethat
isappliedbeforethemethodsmatchedbythevalueattributeareexecuted.Refersection9-5tolearn
aboutdifferentadvicetypesthatyoucancreate.
·@BeforeannotationsvalueattributespecifiesapointcutexpressionthatisusedbySpringAOP
frameworktoidentifymethods(referredtoastargetmethods)towhichanadviceapplies.Insection
9-4, we’ll take an in-depth look at pointcut expressions. For now, you can assume that the pointcut
expressionexecution(* sample.spring.chapter09.bankapp.service.*Service.*(..)) specifies that
LoggingAspectslogmethodisappliedtoallthepublicmethodsdefinedbyclasses(orinterfaces)in
sample.spring.chapter09.bankapp.servicepackage,andwhosenamesendwithService.
· Thelogmethod’sJoinPointargumentrepresentsthetargetmethodtowhich the advice is being
applied.ThelogmethodusesJoinPointinstancetoretrieveinformationabouttheargumentspassedto
thetargetmethod.Inexamplelisting9-1,JoinPoint’sgetArgsmethodisinvokedtoretrievethemethod
argumentsbeingpassedtothetargetmethod.
YouneedtoregisteranaspectwiththeSpringcontainersothattheSpringAOPframeworkismadeaware
oftheaspect. In examplelisting 9-1, theLoggingAspect class isannotated withSprings @Component
annotationsothatitisautomaticallyregisteredwiththeSpringcontainer.
The following example listing shows the BankApp class that invokes methods of
BankAccountServiceImpl (implements BankAccountService interface) and FixedDepositServiceImpl
(implementsFixedDepositServiceinterface)classesofMyBankapplication:
Examplelisting9-2–BankAppclass
Project–ch09-simple-aop
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp
packagesample.spring.chapter09.bankapp;
.....
publicclassBankApp{
publicstaticvoidmain(Stringargs[])throwsException{
ApplicationContextcontext=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
BankAccountServicebankAccountService=context.getBean(BankAccountService.class);
BankAccountDetailsbankAccountDetails=newBankAccountDetails();
bankAccountDetails.setBalanceAmount(1000);
bankAccountDetails.setLastTransactionTimestamp(newDate());
bankAccountService.createBankAccount(bankAccountDetails);
FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);
FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,
12,"someemail@somedomain.com"));
}
}
In the above example listing, BankAccountServices createBankAccount and FixedDepositService’s
createFixedDeposit methods are invoked by BankApp’s main method. If you execute BankApp’s main
method,you’llseethefollowingoutputontheconsole:
INFOLoggingAspect-EnteringBankAccountServiceImpl'screateBankAccount
INFOLoggingAspect-args[0]-->BankAccountDetails[accountId=0,balanceAmount=1000,lastTransactionTimestamp=Sat
Oct2716:48:11IST2012]
INFOBankAccountServiceImpl-createBankAccountmethodinvoked
INFOLoggingAspect-EnteringFixedDepositServiceImpl'screateFixedDeposit
INFOLoggingAspect-args[0]-->id:1,depositamount:1000.0,tenure:12,email:someemail@somedomain.com
INFOFixedDepositServiceImpl-createFixedDepositmethodinvoked
The above output shows that LoggingAspect’s log method is executed before the execution of
BankAccountServicescreateBankAccountandFixedDepositService’screateFixedDepositmethod.
InthecontextofLoggingAspect,letslookathowSpringAOPframeworkworks.
NOTETouseAspectJannotation-styleaspects,ch09-simple-aopprojectdefinesdependencyonspring-
aop,aopalliance,aspectjrtandaspectjweaverJARfiles.Pleaserefertothepom.xmlfileofch09-simple-
aopprojectfordetails.
9-3SpringAOPframework
SpringAOPframeworkisproxy-based;aproxyobjectiscreatedforobjectsthataretargetofanadvice.
Aproxyisanintermediaryobject,introducedbytheAOPframework,betweenthecallingobjectandthe
targetobject.Atruntime,callstothetargetobjectareinterceptedbytheproxy,andadvicesthatapplyto
thetargetmethodareexecutedbytheproxy.InSpringAOP,atargetobjectisabeaninstanceregistered
withtheSpringcontainer.
ThefollowingdiagramshowshowtheLoggingAspectslogmethod(referexamplelisting9-1)isapplied
tothemethodsofBankAccountServiceandFixedDepositServiceobjects(referexamplelisting9-2):
Figure9-1Theproxyobjectisresponsibleforinterceptingmethodcallstothetargetobjectandexecuting
theadvicesthatapplytothetargetmethod.
TheabovediagramshowsthataproxyiscreatedforbothBankAccountServiceandFixedDepositService
objects. The proxy for BankAccountService intercepts the call to BankAccountServices
createBankAccount method, and the proxy for FixedDepositService intercepts the call to
FixedDepositService’s createFixedDeposit method. The proxy for BankAccountService first executes
LoggingAspectslogmethod,followedbyBankAccountService’screateBankAccountmethodinvocation.
Similarly, the proxy for FixedDepositService first executes LoggingAspect’s log method, followed by
FixedDepositService’screateFixedDepositmethodinvocation.
Thetimingoftheexecutionofanadvice(likethelogmethodofLoggingAspectaspect)dependsonthe
typeoftheadvice.InAspectJannotation-style,typeofanadviceisspecifiedbytheAspectJannotationon
theadvice.Forinstance,AspectJ’s@Beforeannotationspecifiesthattheadviceisexecutedbeforethe
invocation of the target method, @After annotation specifies that the advice is executed after the
invocationofthetargetmethod,@Aroundannotationspecifiesthattheadviceisexecutedbothbeforeand
after the execution of the target method, and so on. As LoggingAspect’slog method is annotated with
@Beforeannotation,logmethodisexecutedbeforetheexecutionofthetargetobjectsmethod.
LetsnowlookathowSpringAOPframeworkcreatesaproxyobject.
Proxycreation
When using Spring AOP, you have the option to explicitly create AOP proxies via Springs
ProxyFactoryBean (refer to org.springframework.aop.framework package) or you can let Spring
automaticallycreateAOPproxies.TheautomaticgenerationofAOPproxiesbySpringAOPisreferredto
asautoproxying.
If you want to use AspectJ annotation-style for creating aspects, you need to enable support for using
AspectJannotation-stylebyspecifyingSpringaopschema’s<aspectj-autoproxy>element.The<aspectj-
autoproxy>elementalsoinstructsSpringAOPframeworktoautomaticallycreateAOPproxiesfortarget
objects.Thefollowingexamplelistingshowsusageof<aspectj-autoproxy>elementinch09-simple-aop
project:
Examplelisting9-3–applicationContext.xml-<aspectj-autoproxy>element
Project–ch09-simple-aop
Sourcelocation-src/main/resources/META-INF/spring
<beans.....
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=".....http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<context:component-scanbase-package="sample.spring"/>
<aop:aspectj-autoproxyproxy-target-class="false"expose-proxy="true"/>
</beans>
The <aspectj-autoproxy> elements proxy-target-class attribute specifies whether JavaSE- or CGLIB-
basedproxiesarecreatedfortargetobjects,andexpose-proxyattributespecifieswhethertheAOPproxy
itselfisavailabletothetargetobject.Ifexpose-proxysvalueissettotrue,thetargetobjectsmethodcan
accesstheAOPproxybycallingAopContextscurrentProxystaticmethod.
SpringAOPframeworkcreatesaCGLIB-orJavaSE-basedproxy.Ifthetargetobjectdoesn’timplement
any interface, Spring AOP creates a CGLIB-based proxy. If the target object implements one or more
interfaces, Spring AOP creates a JavaSE-based proxy. If the value of <aspectj-autoproxy> element’s
proxy-target-classattributeissettofalse,itinstructsSpringAOPtocreateaJavaSE-basedproxyifthe
targetobjectimplementsoneormoreinterface.Ifyousetproxy-target-classattribute’svaluetotrue, it
instructs Spring AOP to create CGLIB-based proxies even if a target object implements one or more
interfaces.
NOTEStartingwithSpring3.2,theCGLIBclassesarepackagedwithinthespring-coreJARfileitself;
therefore,youdontneedtoexplicitlyincludeCGLIBJARfileinyourapplicationtoallowSpringAOP
frameworktocreateCGLIB-basedproxiesfortargetobjects.
Letsnowlookatascenarioinwhichyou’dprefertosetexpose-proxyattributeof<aspectj-autoproxy>
elementtotrue.
IMPORT chapter 9/ch09-aop-proxy (The ch09-aop-proxy project shows the MyBank application in
which AopProxys currentProxy method is used by a target method to retrieve the AOP proxy object
createdbySpringAOPframework.Toruntheapplication,executethemainmethodoftheBankAppclass
ofthisproject)
expose-proxyattribute
The following example listing shows a modified BankAccountServiceImpl class in which the
createBankAccountmethodinvokestheisDuplicateAccountmethodtocheckifabankaccountwithsame
detailsalreadyexistsinthesystem:
Examplelisting9-4–BankAccountServiceImplclass
@Service(value="bankAccountService")
publicclassBankAccountServiceImplimplementsBankAccountService{
@Autowired
privateBankAccountDaobankAccountDao;
@Override
publicintcreateBankAccount(BankAccountDetailsbankAccountDetails){
if(!isDuplicateAccount(bankAccountDetails)){
returnbankAccountDao.createBankAccount(bankAccountDetails);
}else{
thrownewBankAccountAlreadyExistsException("Bankaccountalreadyexists");
}
}
@Override
publicbooleanisDuplicateAccount(BankAccountDetailsbankAccountDetails){.....}
}
The above example listing shows that the createBankAccount method invokes the isDuplicateAccount
methodtocheckifthebankaccountalreadyexistsinthesystem.
Now,thequestionarisesthatwhethertheLoggingAspect’slogmethod(referexamplelisting9-1)willbe
executedwhentheisDuplicateAccountmethodisinvokedbythecreateBankAccountmethod?Eventhough
theisDuplicateAccountmethodmatchesthepointcutexpressionspecifiedby@Beforeannotationonthe
LoggingAspectslogmethod(referexamplelisting9-1),theLoggingAspectslogmethodisnotinvoked.
ThisisbecausemethodsinvokedbythetargetobjectonitselfarenotproxiedbytheAOPproxy.Asthe
methodinvocationdoesntgothroughtheAOPproxyobject,anyadvicethatisassociatedwiththetarget
methodisnotexecuted.
To ensure that the call to isDuplicateAccount method goes to the target object through the AOP proxy,
retrieve the AOP proxy object in the createBankAccount method and invoke the isDuplicateAccount
methodontheAOPproxyobject.ThefollowingexamplelistingshowshowtoretrieveAOPproxyobject
insidethecreateBankAccountmethod:
Examplelisting9-5–BankAccountServiceImplclass
Project–ch09-aop-proxy
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp/service
packagesample.spring.chapter09.bankapp.service;
importorg.springframework.aop.framework.AopContext;
.....
@Service(value="bankAccountService")
publicclassBankAccountServiceImplimplementsBankAccountService{
.....
@Override
publicintcreateBankAccount(BankAccountDetailsbankAccountDetails){
//--obtaintheproxyandinvoketheisDuplicateAccountmethodviaproxy
booleanisDuplicateAccount=

((BankAccountService)AopContext.currentProxy()).isDuplicateAccount(bankAccountDetails);
if(!isDuplicateAccount){.....}
.....
}

@Override
publicbooleanisDuplicateAccount(BankAccountDetailsbankAccountDetails){.....}
}
Intheaboveexamplelisting,calltoAopContext’scurrentProxymethodreturnstheAOPproxythatmade
thecalltothecreateBankAccountmethod.IfthecreateBankAccountmethodisnotinvokedthroughSpring
AOPframeworkorthevalueofexpose-proxyattributeof<aspectj-autoproxy>elementisfalse,calltothe
currentProxy method will result in throwing java.lang.IllegalStateException. As the AOP proxy
implementsthesameinterfaceasthetargetobject,theaboveexamplelistingshowsthattheAOPproxy
returned by the currentProxy method is cast to BankAccountService type and BankAccountService’s
isDuplicateAccountmethodisinvoked.
If you now go to ch09-aop-proxyproject and execute BankApp’s main method, youll notice that
LoggingAspects log method is executed when isDuplicateAccount method is invoked by the
createBankAccountmethod.
Letsnowtakeatanin-depthlookatpointcutexpressions.
9-4Pointcutexpressions
WhenusingSpringAOP,apointcutexpressionidentifiesthejoinpointstowhichanadviceisapplied.In
SpringAOP,joinpointsarealwaysbeanmethods.Ifyouwanttoapplyanadvicetofields,constructors,
non-publicmethods,andtoobjectsthatarenotSpringbeans,youshoulduseAspectJinsteadofSpring
AOPframework.IfyouwanttodevelopaspectsusingAspectJannotation-style,youhavetheoptionto
specify a pointcut expression using AspectJ’s @Pointcut annotation or by using AspectJ’s @Before,
@After,andsoon,annotationsthatspecifytheadvicetype.
Pointcut expressions use pointcut designators, like execution, args, within, this, and so on, to find
matchingmethodstowhichanadviceisapplied.Forinstance,inexamplelisting9-1,@Beforeannotation
made useofexecution pointcutdesignator tofind methods towhich the LoggingAspects log method is
applied.
Letsnowlookathowpointcutexpressionsarespecifiedusing@Pointcutannotation.
IMPORTchapter9/ch09-aop-pointcuts(Thech09-aop-pointcutsprojectshowstheMyBankapplication
thatusesAspectJs@Pointcutannotationtospecifyapointcutexpression.Toruntheapplication,execute
themainmethodoftheBankAppclassofthisproject)
@Pointcutannotation
@Pointcut annotations value attribute specifies the pointcut expression. To use @Pointcut annotation,
createanemptymethodandannotateitwith@Pointcutannotation.Theemptymethodmustbedefinedto
returnvoid.Anadvicethatreferstothenameofthe@Pointcutannotatedmethodisappliedtothemethods
matchedbythepointcutexpressionspecifiedbythe@Pointcutannotation.
NOTEUsing@Pointcutannotationisparticularlyusefulif apointcutexpressionis shared bymultiple
advicesinthesameordifferentaspects.
The following example listing shows a modified version of LoggingAspect (refer example listing 9-1)
classthatuses@Pointcutannotation:
Examplelisting9-6–LoggingAspectclass
Project–ch09-aop-pointcuts
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspects
packagesample.spring.chapter09.bankapp.aspects;
importorg.aspectj.lang.annotation.Before;
importorg.aspectj.lang.annotation.Pointcut;
@Aspect
@Component
publicclassLoggingAspect{
@Pointcut(value="execution(*sample.spring.chapter09.bankapp.service.*Service.*(..))")
privatevoidinvokeServiceMethods(){}

@Before(value="invokeServiceMethods()")
publicvoidlog(JoinPointjoinPoint){
logger.info("Entering"+joinPoint.getTarget().getClass().getSimpleName()+"'s"
+joinPoint.getSignature().getName());
.....
}
}
Intheaboveexamplelisting,theinvokeServiceMethodsmethodisannotatedwith@Pointcutannotation,
and@BeforeannotationsvalueattributereferstotheinvokeServiceMethodsmethod.Thismeansthatthe
log method is applied to the methods that match the pointcut expression specified by the @Pointcut
annotationontheinvokeServiceMethodsmethod.
Astheexecutionandargspointcutdesignatorsaremostlyusedwhenspecifyingpointcutexpressions,lets
lookatexecutionandargspointcutdesignatorsindetail.
executionandargspointcutdesignators
Theexecutionpointcutdesignatorhasthefollowingformat:
execution(<access-modifier-pattern><return-type-pattern> <declaring-type-pattern><method-
name-pattern>(<method-param-pattern>)<throws-pattern>)
If you compare an execution expression to a method declaration, youll notice that an execution
expressionissimilartoamethoddeclaration.
Figure9-2Differentpartsofanexecutionexpressionmaptodifferentpartsofamethoddeclaration.
Figure9-2showshowthedifferentpartsofanexecutionexpressionmaptoamethoddeclaration:
Spring AOP framework matches different parts of an execution expression with different parts of a
methoddeclaration(asshownabove)tofindthemethodstowhichanadviceisapplied.The<declaring-
type-pattern>isnotshownintheabovefigurebecause<declaring-type-pattern>isonlyusedwhenyou
wanttorefertomethodscontainedinaparticulartypeorpackage.
Thefollowingtabledescribesdifferentpartsofanexecutionexpression:
Expressionpart Description
access-modifier-pattern
Specifiestheaccessmodifierofthetargetmethod.InSpringAOP,theonlyvaluethatcan
be specified for this expression part is public. This part of execution expression is
optional.
return-type-pattern Specifiesthefully-qualifiednameofthereturntypeofthetarget method.A valueof*
meansthatthereturntypeofamethoddoesn’tmatter.
declaring-type-pattern Specifiesthefully-qualifiednameofthetypethatcontainsthetargetmethod.Thispart
of execution expression isoptional. A value of * means that all types (classes and
interfaces)intheapplicationareconsideredbythepointcutexpression.
method-name-pattern Specifies the method name pattern. For instance, a value of save* means that the
methodswhosenamesbeginwithsavearetargetofadvice.
method-param-pattern Specifies themethodparameter pattern. Ifthevalueis (..),itmeans target method can
containanynumberofargumentsornoargumentsatall.
throws-pattern Specifies the exception(s) thrown by the target method. This part of execution
expressionisoptional.
The args pointcut designator specifies the arguments that must be accepted by the target method at
runtime. For instance, if you want pointcut expression to locate methods that accept an instance of
java.util.List at runtime, then the args expression looks like: args(java.util.List). Later in this section,
we’ll see how args pointcut designator can be used to make arguments passed to the target method
availabletoanadvice.
Letsnowlookatsomepointcutexpressionsthatuseexecutionandargspointcutdesignators:
Example1
Figure9-3executionexpressionthatusesamethodnamepattern
The methods matched by the above pointcut expression are the methods whose names start with
createFixed.Thereturntypeisspecifiedas*,whichmeansthetargetmethodmayreturnanytype.The(..)
specifiesthatthetargetmethodmayacceptzeroormorearguments.
Example2
Figure9-4executionexpressionthatspecifiesthetype(classorinterface)containingthetargetmethod(s)
ThemethodsmatchedbytheabovepointcutexpressionarethemethodsdefinedbytheMyServicetypein
samplepackage.
Example3
Figure9-5executionexpressionthatspecifiesanexceptionpatternforthemethod
The methods matched bythe abovepointcut expressionare the methodsof sample.MyService type that
specifyathrowsclause.
Example4
Figure9-6argspointcutdesignatorspecifiestheobjectinstancepassedtothetargetmethod
Intheabovepointcutexpression,combinationsofexecutionandargspointcutdesignatorshavebeenused.
Youcancombinepointcutdesignatorsusing&&and||operatorstocreatecomplexpointcutexpressions.
Themethodsmatchedbytheabovepointcutexpressionarethemethodsdefinedinsample.MyServicetype
thatacceptaninstanceofSomeObjectatruntime.The&&intheabovepointcutexpressionspecifiesthat
thetargetmethodmustmatchtheexpressionsspecifiedbytheexecutionandargspointcutdesignators.
If you want an advice to have access to one or more method arguments passed to the target method,
specifynamesofthemethodargumentsintheargsexpression,asshownhere:
Figure9-7argspointcutdesignatorspecifiesthetargetmethod’sargument(s)thatmustbemadeavailable
totheadvice
Intheabovepointcutexpression,argsexpressionspecifiesthatthetargetmethodmustacceptanargument
oftypeSomeObject,andthatargumentisavailabletoadviceviaxyzparameter.Letssee,arealexample
thatmakesuseofthisfeaturetopassargumentstotheadvice.
Passingtargetmethodsargumentstoanadvice
The following example listing shows a modified version of LoggingAspect in which log method is
executedonlyifthemethodargumentpassedtothetargetmethodisaninstanceofFixedDepositDetails,
andthatFixedDepositDetailsinstanceisalsomadeavailabletothelogmethod:
Examplelisting9-7–LoggingAspectclass–passingtargetmethod’sargumentstoanadvice
importorg.aspectj.lang.annotation.Before;
importorg.aspectj.lang.annotation.Pointcut;
@Aspect
@Component
publicclassLoggingAspect{
.....
@Pointcut(value=
"execution(*sample.spring.chapter09.bankapp.service.*Service.*(..))
&&args(FixedDepositDetails)")
privatevoidinvokeServiceMethods(FixedDepositDetailsFixedDepositDetails){
}
@Before(value="invokeServiceMethods(FixedDepositDetails)")
publicvoidlog(JoinPointjoinPoint,FixedDepositDetailsFixedDepositDetails){
.....
}
}
Intheaboveexamplelisting,theargsexpressionspecifiesthattheFixedDepositDetailsinstancepassedto
thetargetmethodisavailabletologmethod(anadvice)viaFixedDepositDetailsparameter.Astheargs
expressionprovideslogmethodwithaninstanceofFixedDepositDetailsobject,thelogmethodhasbeen
modifiedtoacceptanadditionalargumentoftypeFixedDepositDetails.
Pointcutdesignators,likeexecution,args,within,this,target,andsoon,aredefinedbyAspectJ.Spring
AOPdefinesabeanpointcutdesignatorthatisspecifictoSpringAOPframework.Let’stakeaquicklook
atbeanpointcutdesignator.
beanpointcutdesignator
Thebeanpointcutdesignatorisforlimitingthetargetmethodstothespecifiedbeanid(orname).Youcan
specify the exact bean id or name, or you can specify a pattern. Lets look at a few examples of bean
pointcutdesignator:
Example1
Figure9-8beanpointcutdesignatorspecifiesthebeanidornamewhosemethodsaretargetoftheadvice
The methods matched by the above pointcut expression are the methods defined by the bean named
someBean.
Example2
Figure9-9beanpointcutdesignatorspecifiesthatanadviceisappliedtothemethodsofthe
beanswhoseidornamebeginwithsomeBean.
In the above pointcut expression, bean pointcut designator specifies that an advice is applied to the
methodsofthebeanswhoseidornamebeginwithsomeBean.
NOTELikeanyotherpointcutdesignator,youcancombinebeanpointcutdesignatorwithotherpointcut
designatorsusing&&and||operatorstoformcomplexpointcutexpressions.
Letsnowlookatpointcutdesignatorsthatperformmatchingbasedonannotations.
Annotations-basedpointcutdesignators
AspectJalsoprovidespointcutdesignators,like@annotation,@target,@withinand@argsthatyoucan
usewithSpringAOPtofindtargetmethods.Letslookatcoupleofexamplesthatshowusageofthese
pointcutdesignators:
Example1
Figure9-10@annotationpointcutdesignatorspecifiesthatanadviceisappliedtothemethodsannotated
withSpringsCacheableannotation
The methods matched by the above pointcut expression are the methods annotated with Springs
@Cacheableannotation.
Example2
Figure 9-11 @target pointcut designator specifies that advice is applied to the methods of objects
annotatedwithSprings@Componentannotation
Themethodsmatchedbytheabovepointcutexpressionarethemethodscontainedinanobjectannotated
withSprings@Componentannotation.
Inthissection,welookedatsomeofthepointcutdesignatorsdefinedbyAspectJ.Itisimportanttonote
thatnotallpointcutdesignatorsdefinedbyAspectJaresupportedbySpringAOPframework.Ifyouuse
an unsupported pointcut designator in pointcut expressions, Spring AOP framework throws a
java.lang.IllegalArgumentException. For instance, if you use call, set and get pointcut designators in
pointcutexpressions,SpringAOPwillthrowjava.lang.IllegalArgumentException.
Letsnowlookatdifferentadvicetypesandhowtocreatethem.
9-5Advicetypes
Sofar inthis chapter,weve seenexamples of before advice type. A beforeadvice typeis createdby
annotating a method of an aspect with @Before annotation (refer listing 9-1, 9-6 and 9-7). The other
advicetypesthatyoucancreateareafter,afterreturning,afterthrowing,afterandaround.
IMPORTchapter9/ch09-aop-advices (The ch09-aop-advices project shows the MyBank application
thatusesdifferentadvicetypes.Toruntheapplication,executethemainmethodoftheBankAppclassof
thisproject)
Letsnowlookatsalientfeaturesofvariousadvicetypes,andhowtocreatethem.
Beforeadvice
Abefore advice is executed before the target method is executed. If a before advice doesnt throw an
exception, the target method will always be invoked. You can control whether the target method is
executed or not, by using anaround advice (explained later in this section). As discussed earlier,
AspectJ’s@Beforeannotationisusedtoindicatethatanadviceisabeforeadvice.
@BeforeannotatedmethodmaydefineitsfirstargumenttobeoftypeJoinPoint.YoucanusetheJoinPoint
argument inside the advice to retrieve information about the target method. For instance, listing 9-1
showed that the JoinPoint instance can be used to obtain the class name of the target object and the
argumentspassedtothetargetmethod.
Afterreturningadvice
Anafter returning advice is executed after the target method returns. You should note that anafter
returningadviceisnotexecutedifthetargetmethodthrowsanexception.Anafterreturningadviceis
annotated with AspectJ’s @AfterReturning annotation. Anafterreturning advice can access the value
returnedbythetargetmethod,andmodifyitbeforeitisreturnedtothecallingobject.
TheSampleAspectclassofch09-aop-advicesprojectrepresentsanAOPaspect.Thefollowingexample
listingshowsthattheSampleAspectclassdefinesanafterreturningadvicethatprintsthevaluereturned
byBankAccountService’screateBankAccountmethod:
Examplelisting9-8–SampleAspectclass–afterreturningadvice
Project–ch09-aop-advices
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspects
packagesample.spring.chapter09.bankapp.aspects;
importorg.aspectj.lang.annotation.AfterReturning;
.....
@Aspect
publicclassSampleAspect{
privateLoggerlogger=Logger.getLogger(SampleAspect.class);
@Pointcut(value="execution(*sample.spring..BankAccountService.createBankAccount(..))")
privatevoidcreateBankAccountMethod(){}
@AfterReturning(value="createBankAccountMethod()",returning="aValue")
publicvoidafterReturningAdvice(JoinPointjoinPoint,intaValue){
logger.info("Valuereturnedby"+joinPoint.getSignature().getName()
+"methodis"+aValue);
}
.....
}
In the above example listing, afterReturningAdvice method represents anafter returning advice. The
pointcutexpressionspecifiedbythe@PointcutannotationlimitsthejoinpointtoBankAccountServices
createBankAccountmethod.The..intheexecutionexpressionspecifiesthatthesample.springpackage
anditssub-packagesaresearchedtofindtheBankAccountServicetype.
Inexamplelisting9-8,SampleAspectsafterReturningAdvicemethodisinvokedaftertheinvocationof
BankAccountServicescreateBankAccountmethod.Thereturningattributeof@AfterReturningannotation
specifiesthenamewithwhichthereturnvalueofthetargetmethodisavailabletotheadvice.Intheabove
example listing, the value returned by the createBankAccount method is made available to the
afterReturningAdvicemethodviaaValueargument.ThetypeoftheaValueargumenthasbeenspecifiedas
intbecausethecreateBankAccountmethodreturns an int value. You should note thatif you specify the
returning attribute, the advice is applied only to methods that return the specified type. If anafter
returningadviceisappliedtomethodsthatreturndifferentvaluetypes(includingvoid),youcanspecify
argumenttypeofthereturnedvalueasObject.
Asshowninexamplelisting9-8,a@AfterReturningannotatedmethodmaydefineitsfirstargumenttobe
oftypeJoinPointtoaccesstargetmethodinformation.
Afterthrowingadvice
Anafterthrowing advice is executed when the target method throws an exception. Anafter throwing
advicecanaccesstheexceptionthrownbythetargetmethod.Anafterthrowingadviceisannotatedwith
AspectJ’s@AfterThrowingannotation.
The following example listing shows anafter throwing advice that is executed when an exception is
thrownbytargetmethods:
Examplelisting9-9–SampleAspectclass–afterthrowingadvice
Project–ch09-aop-advices
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspects
packagesample.spring.chapter09.bankapp.aspects;
importorg.aspectj.lang.annotation.AfterThrowing;
.....
@Aspect
publicclassSampleAspect{
privateLoggerlogger=Logger.getLogger(SampleAspect.class);
.....
@Pointcut(value="execution(*sample.spring..FixedDepositService.*(..))")
privatevoidexceptionMethods(){}
.....
@AfterThrowing(value="exceptionMethods()",throwing="exception")
publicvoidafterThrowingAdvice(JoinPointjoinPoint,Throwableexception){
logger.info("Exceptionthrownby"+joinPoint.getSignature().getName()
+"Exceptiontypeis:"+exception);
}
}
Intheaboveexamplelisting,SampleAspectsafterThrowingAdvicemethodrepresentsanafterthrowing
advice. The afterThrowingAdvice method is executed when an exception is thrown by any of the
FixedDepositService objects methods. In the above example listing, the throwing attribute of
@AfterThrowingannotationspecifiesthenamewithwhichtheexceptionthrownbythetargetmethodis
madeavailabletotheafterThrowingAdvice method.As the throwingattribute’svalue is exception, the
exceptionispassed totheafterThrowingAdvicemethodvia argumentnamedexception. Notice thatthe
type of the exception argument is java.lang.Throwable, which means that the afterThrowingAdvice
method is executed for all exceptions thrown by the target method. If you want afterThrowingAdvice
methodisexecutedonlywhenaspecificexceptiontypeisthrownbythetargetmethod,changethetypeof
theexceptionargument.Forinstance,ifyouwanttheafterThrowingAdvicemethodisexecutedonlywhen
the target method throws java.lang.IllegalStateException, specify java.lang.IllegalStateException as the
typeoftheexceptionargument.
Asshowninexamplelisting9-9,@AfterThrowingannotatedmethodmaydefineitsfirstargumenttobeof
typeJoinPointtoaccesstargetmethodinformation.
Afteradvice
Anafteradviceisexecutedafterthetargetmethodisexecuted,irrespectiveofwhetherthetargetmethod
completes normally or throws an exception. Anafter advice is annotated with AspectJ’s @After
annotation.
The following example listing shows anafter advice that is executed for BankAccountService’s
createBankAccountmethod,andforthemethodsdefinedbytheFixedDepositServiceinterface:
Examplelisting9-10–SampleAspectclass–afteradvice
Project–ch09-aop-advices
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspects
packagesample.spring.chapter09.bankapp.aspects;
importorg.aspectj.lang.annotation.After;
.....
@Aspect
publicclassSampleAspect{
privateLoggerlogger=Logger.getLogger(SampleAspect.class);
@Pointcut(value="execution(*sample.spring..BankAccountService.createBankAccount(..))")
privatevoidcreateBankAccountMethod(){}
@Pointcut(value="execution(*sample.spring..FixedDepositService.*(..))")
privatevoidexceptionMethods(){}
.....
@After(value="exceptionMethods()||createBankAccountMethod()")
publicvoidafterAdvice(JoinPointjoinPoint){
logger.info("Afteradviceexecutedfor"+joinPoint.getSignature().getName());
}
}
In the above example listing, SampleAspects afterAdvice method represents anafter advice. The
afterAdvicemethodisexecutedafterthetargetmethodisexecuted.Noticethatthe@Afterannotation’s
value attribute uses || operator to combine pointcut expressions represented by the
createBankAccountMethodandexceptionMethodsmethodstoformanewpointcutexpression.
Asshowninexamplelisting9-10,@Afterannotatedmethodmaydefineitsfirstargumenttobeoftype
JoinPoint,toaccesstargetmethodinformation.
Aroundadvice
Anaround advice is executed bothbefore and after the execution of the target method. Unlike other
advices,anaroundadvicecancontrolwhetherthetargetmethodisexecutedornot.Anaroundadviceis
annotatedwithAspectJ’s@Aroundannotation.
The following example listing shows anaround advice defined by SampleAspect class of ch09-aop-
advicesproject:
Examplelisting9-11–SampleAspectclass–aroundadvice
Project–ch09-aop-advices
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspects
packagesample.spring.chapter09.bankapp.aspects;
importorg.aspectj.lang.ProceedingJoinPoint;
importorg.aspectj.lang.annotation.Around;
importorg.springframework.util.StopWatch;
.....
@Aspect
publicclassSampleAspect{
.....
@Around(value="execution(*sample.spring..*Service.*(..))")
publicObjectaroundAdvice(ProceedingJoinPointpjp){
Objectobj=null;
StopWatchwatch=newStopWatch();
watch.start();
try{
obj=pjp.proceed();
}catch(Throwablethrowable){
//--performanyactionthatyouwant
}
watch.stop();
logger.info(watch.prettyPrint());
returnobj;
}
}
In the above example listing, the aroundAdvice method represents anaround advice. The
ProceedingJoinPointargumenttothearoundAdvicemethodismeantforcontrollingtheinvocationofthe
targetmethod.ItisimportanttonotethatProceedingJoinPointargumentmustbethefirstargumentpassed
to anaround advice. When you invoke ProceedingJoinPoints proceed method, the target method is
invoked.ThismeansthatifyoudontinvoketheProceedingJoinPointsproceedmethod,thetargetmethod
isnotinvoked.IfyoupassanObject[]totheproceedmethod,thevaluescontainedintheObject[]are
passedasargumentstothetargetmethod.Ifanaroundadvicechoosesnottoinvokethetargetmethod,the
aroundadvicemayitselfreturnavalue.
As the target method is invoked only when you call ProceedingJoinPoints proceed method, around
adviceallowsyoutoperformactionsbeforeandaftertheinvocationofthetargetmethod,andtoshare
information between these action. In example listing 9-11, the aroundAdvice method records the time
taken for the target method to execute. The aroundAdvice method starts a stop watch (represented by
Springs StopWatch object) before calling ProceedingJoinPoints proceed method, and stops the stop
watchaftercallingProceedingJoinPointsproceedmethod.StopWatchsprettyPrintmethodisthenusedto
printthetimetakenbythetargetmethodtoexecute.
If you want to modify the value returned by the target method, cast the returned value of
ProceedingJoinPoints proceed method to the return type of the target method and modify it. A calling
method sees the value returned by the around advice; therefore, youmust define the return type of an
advicemethodasObjectorthetypethatisreturnedbythetargetmethod.Anadvicemethodhastheoption
toreturnthevaluereturnedby thetargetmethod, ortoreturnadifferentvaluealtogether.Forinstance,
insteadofinvokingthetargetmethod,anaroundadvicemayinspecttheargument(s)beingpassedtothe
targetmethodandreturnavaluefromthecacheifacacheentryexistsforthesamesetofarguments.
SofarwehavelookedatexamplesthatshowedhowtouseAspectJannotation-styletocreateaspects.
LetsnowlookathowtousearegularSpringbeanasanAOPaspect.
9-6SpringAOP-XMLschema-style
In XML schema-style, a regular Spring bean acts as an aspect. A method defined in an aspect is
associatedwithanadvicetypeandapointcutexpressionusingSpringsaopschema.
IMPORT chapter 9/ch09-aop-xml-schema (The ch09-aop-xml-schema project is same as ch09-aop-
advices project, except that ch09-aop-xml-schema’s SampleAspect class is a simple Java class that
doesntuseAspectJ’sannotations)
The following example listing shows the SampleAspect class of ch09-aop-xml-schema project that
definesadvices:
Examplelisting9-12–SampleAspectclass
Project–ch09-aop-xml-schema
Sourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspects
packagesample.spring.chapter09.bankapp.aspects;
.....
publicclassSampleAspect{
.....
publicvoidafterReturningAdvice(JoinPointjoinPoint,intaValue){
logger.info("Valuereturnedby"+joinPoint.getSignature().getName()+"methodis"+aValue);
}
publicvoidafterThrowingAdvice(JoinPointjoinPoint,Throwableexception){
logger.info("Exceptionthrownby"+joinPoint.getSignature().getName()
+"Exceptiontypeis:"+exception);
}
.....
}
The above example listing shows that the SampleAspect class defines methods that represent AOP
advices.NoticethattheSampleAspectclassisnotannotatedwith@Aspectannotationandthemethods
arenotannotatedwith@After,@AfterReturning,andsoon,annotations.
Letsnowlookat how <config>elementofSprings aopschema is usedtoconfigure aregular Spring
beanasanAOPaspect.
ConfiguringanAOPaspect
InXMLschema-style,AOP-specificconfigurationsareenclosedwithin<config>elementofSpringsaop
schema.And,anAOPaspectisconfiguredusing<aspect>sub-elementof<config>element.
The following example listing shows how the SampleAspect class is configured using <aspect> sub-
elementof<config>element:
Examplelisting9-13–applicationContext.xml–Springsaopschemausage
Project–ch09-aop-xml-schema
Sourcelocation-src/main/resources/META-INF/spring
<beans.....xmlns:aop="http://www.springframework.org/schema/aop".....>
.....
<beanid="sampleAspect"
class="sample.spring.chapter09.bankapp.aspects.SampleAspect"/>
<aop:configproxy-target-class="false"expose-proxy="true">
<aop:aspectid="sampleAspect"ref="sampleAspect">
.....
</aop:aspect>
</aop:config>
</beans>
As the <config> element relies on autoproxying, the <config> element defines proxy-target-class and
expose-proxy attributes. If you remember, the same attributes were defined by <aspectj-autoproxy>
elementof Springs aopschema. Refer section 9-3to knowmore about proxy-target-class and expose-
proxyattributes.
In example listing 9-13, the sampleAspect bean definition defines SampleAspect class as a bean. The
<aspect> element configures the sampleAspect bean as an AOP aspect. The <aspect> elements id
attributespecifiesauniqueidentifierforanaspect,andtherefattributespecifiestheSpringbeanthatyou
wanttoconfigureasanAOPaspect.
Now,thatwehaveconfiguredanAOPaspect,let’slookathowtomapmethodsdefinedinanAOPaspect
todifferentadvicetypesandpointcutexpressions.
Configuringanadvice
You configure an advice using one of the following sub-elements of <aspect> element: <before> (for
configuring abefore advice type), <after-returning> (for configuring anafter returning advice type),
<after-throwing>(forconfiguringanafterthrowingadvicetype),<after>(forconfiguringanafteradvice
type)and<around>(forconfiguringanaroundadvicetype).
LetsnowlookathowtheadvicesdefinedintheSampleAspectclassofch09-aop-xml-schemaproject
areconfiguredintheapplicationcontextXMLfile.
Configuringanafterreturningadvice
The following figure shows how the SampleAspect’s afterReturningAdvice method is configured as an
afterreturningadviceusing<after-returning>element:
Figure 9-12 afterReturningAdvice method of SampleAspect class is configured as anafter returning
adviceusing<after-returning>elementofSpringsaopschema
The <after-returning> elements method attribute specifies the name of the method which you want to
configure as anafter returning advice. The returning attribute serves the same purpose as the
@AfterReturning annotations returning attribute; it makes the returned value from the target method
available to the advice. The pointcut attribute specifies the pointcut expression used for finding the
methodstowhichtheadviceisapplied.
Configuringanafterthrowingadvice
The following figure shows how the SampleAspectsafterThrowingAdvice method is configured as an
afterthrowingadviceusing<after-throwing>element:
Figure 9-13 afterThrowingAdvice method of SampleAspect class is configured as anafter throwing
adviceusing<after-throwing>elementofSpringsaopschema
The <after-throwing> elements method attribute specifies the name of the method which you want to
configure as anafter throwing advice. The throwing attribute serves the same purpose as the
@AfterThrowing annotations throwing attribute; it makes the exception thrown by the target method
available to the advice. The pointcut attribute specifies the pointcut expression used for finding the
methodstowhichtheadviceisapplied.
Theotheradvicetypes(before,afterandaround)areconfiguredthesamewayastheafterreturningand
afterthrowingadvicesthatwejustsaw.
Letsnowlookatdifferentwaysinwhichyoucanassociateapointcutexpressionwithanadvice.
Associatingapointcutexpressionwithanadvice
The <after>, <after-returning>, <after-throwing>, <before> and <around> elements of Springs aop
schemadefineapointcutattributethatyoucanusetospecifythepointcutexpressionassociatedwiththe
advice.Ifyouwanttosharepointcutexpressionsbetweendifferentadvices,youcanusethe<pointcut>
sub-elementofthe<config>elementtodefinepointcutexpressions.
The following example listing shows that the <pointcut> element is used for defining pointcut
expressions:
Examplelisting9-14–applicationcontextXML-<pointcut>element
<beans.....xmlns:aop="http://www.springframework.org/schema/aop".....>
.....
<beanid="sampleAspect"
class="sample.spring.chapter09.bankapp.aspects.SampleAspect"/>
<aop:configproxy-target-class="false"expose-proxy="true">
<aop:pointcutexpression="execution(*sample.spring..*Service.*(..))"id="services"/>

<aop:aspectid="sampleAspect"ref="sampleAspect">
<aop:aftermethod="afterAdvice"pointcut-ref="services"/>
<aop:aroundmethod="aroundAdvice"pointcut-ref="services"/>
</aop:aspect>
</aop:config>
</beans>
In the above example listing, the <pointcut> element specifies a pointcut expression. The expression
attributespecifiesthepointcutexpression,andtheidattributespecifiesauniqueidentifierforthepointcut
expression. The pointcut expression defined by a <pointcut> element is referenced by <after>, <after-
returning>, and so on, advice type elements using pointcut-ref attribute. For instance, in the above
examplelisting,<after>and<around>elementsusepointcut-refattributetorefertotheservicespointcut
expressions.
9-7Summary
Inthis chapter, welookedatAOPconceptsandhowSpring AOPcanbeused toaddresscross-cutting
concernsinSpringapplications.WesawhowtocreateaspectsusingAspectJannotation-styleandXML
schema-style.Wealsodiscussedhowtocreateandconfiguredifferentadvicetypes.Wetoucheduponthe
pointcut expressions that you can create to find matching methods in the application. For a more
comprehensive coverage of Spring AOP please refer to Spring reference documentation. In the next
chapter, we’ll look at how to develop web applications using Spring Web MVC module of Spring
Framework.
Chapter10–SpringWebMVCbasics
10-1Introduction
The Spring Web MVC module of Spring Framework provides an MVC (Model-View-Controller)
frameworkthatyoucanusefordevelopingservlet-basedwebapplications.SpringWebMVCisanon-
intrusiveframeworkthatprovidesaclearseparationofconcernsbetweenapplicationobjectsthatform
theweblayer.Forinstance,acontrollerobjectisusedforprocessingtherequest,avalidatorobjectis
used for performing validation, and a command object is used for storing form data, and so on. It is
important to note that none of these application objects implement or extend from any Spring-specific
interfaceorclass.
In this chapter, we’ll first look at the directory structure that will be followed by all the sampleweb
projectsdiscussedinthischapter.We’llthenlookatasimpleHelloWorld’webapplicationdeveloped
usingSpringWebMVC.Intherestofthischapter,welllookatsomeoftheSpringWebMVCannotations
inthecontextofourMyBankwebapplication.Thischaptersetsthestagefordiscussingmoreadvanced
SpringWebMVCfeaturesinthenextchapter.
IMPORTchapter10/ch10-helloworld(ThisprojectshowsasimpleHelloWorld’webapplicationthat
usesSpringWebMVC.ReferappendixAtolearnhowtodeploysamplewebprojectsonTomcatserver.
Once you have deployed the application, go to the following URL:http://localhost:8080/ch10-
helloworld/helloworld/sayhello. If the application is deployed successfully, it will show you ‘Hello
World!!message.)
10-2Directorystructureofsamplewebprojects
Figure10-1describestheimportantdirectoriesofch10-helloworldwebproject.Someoftheimportant
pointsthatyouneedtorememberare:
§Thesrc/main/resources/META-INF/springfoldercontainstherootwebapplication context XML
filethatdefinesbeansthataresharedbyalltheservletsandfiltersofthewebapplication.Theroot
web application context XML file typically defines data sources, services, DAOs, transaction
managers, and so on. The root web application context XML file is loaded by Springs
ContextLoaderListener (ajavax.servlet.ServletContextListener implementation). Refer section 10-
10tolearnabouthowContextLoaderListenerisconfiguredinweb.xmlfile.
§Thesrc/main/webapp/WEB-INF/springfoldercontainsthewebapplicationcontextXMLfilethat
definesbeansthatformpartoftheweblayeroftheapplication.ThewebapplicationcontextXML
filetypicallydefinescontrollers(alsoreferredtoashandlers),handlermappings,viewresolvers,
exceptionresolvers,andsoon.We’lllearnabouttheseobjectslaterinthischapter.
§ThebeansdefinedintherootwebapplicationcontextXMLfileareavailabletothebeansdefined
inthewebapplicationcontextXMLfile.Thismeans,abeandefinedinthewebapplicationcontext
XMLfilecanbedependentonabeandefinedintherootwebapplicationcontextXMLfile,butnot
theotherwayround.
Figure10-1Directorystructureofch10-helloworldproject
Letsnowlookattheconfigurationfilesandtheclassesthatformthech10-helloworldproject.
10-3Understandingthe‘HelloWorldwebapplication
Ifyouright-clickonthech10-helloworldprojectinyourEclipseIDEandselectBuildPathàConfigure
Build Path option, youll notice that the project depends on spring-beans, spring-context, spring-core,
spring-expression,spring-webandspring-webmvcJARfiles.TheseJARfilesarerequiredforbuildinga
basicSpringWebMVCapplication.
Thefollowingtable describestheconfigurationfilesand the Javasourcefiles thatconstitute thech10-
helloworldproject.Laterinthissection,we’lltakeacloserlookatthesefilesandclasses.
Configuration file or Java
sourcefile Description
HelloWorldController.java
SpringWebMVCcontrollerthatisresponsibleforrequesthandling.
You’ll find this file inside sample.spring.chapter10.web package of src/main/java
folder.
helloworld.jsp JSPfilethatshowsthe‘HelloWorld!!’message
You’llfindthisfileinsidesrc/main/webapp/WEB-INF/jspfolder
myapp-config.xml
Web application context XM L file that contains bean definitions for controllers,
handlermappings,andsoon.
You’llfindthisfileinsidesrc/main/webapp/WEB-INF/springfolder
web.xml Webapplicationdeploymentdescriptor
You’llfindthisfileinsidesrc/main/webapp/WEB-INFfolder
Apartfromthefilesshownintheabovetable,thech10-helloworldprojectalsocontainslog4j.properties
file that contains Log4j configuration, and pom.xml file that goes as input to the maven build tool. To
know more about these files refer to Log4j (http://logging.apache.org/log4j/1.2/) and Maven
(http://maven.apache.org/index.html)documentation.
Letsnowtakeacloserlookateachofthefilesdescribedintheabovetable.
HelloWorldController.javaHelloWorldwebapplication’scontrollerclass
In Spring Web MVC applications, the request handling logic is contained in controller classes. The
followingexamplelistingshowstheHelloWorldControllercontrollerclassofch10-helloworldproject:
Examplelisting10-1–HelloWorldControllerclass
Project–ch10-helloworld
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importorg.springframework.web.servlet.ModelAndView;
importorg.springframework.web.servlet.mvc.Controller;
.....
publicclassHelloWorldControllerimplementsController{
@Override
publicModelAndViewhandleRequest(HttpServletRequestrequest,
HttpServletResponseresponse)throwsException{
Map<String,String>modelData=newHashMap<String,String>();
modelData.put("msg","HelloWorld!!");
returnnewModelAndView("helloworld",modelData);
}
}
The above example listing shows that the HelloWorldController class implements Springs
Controller interface. The Controller interface defines a handleRequest method, which you need to
implement to provide the request handling logic. The handleRequest method returns a ModelAndView
objectthatcontainsthefollowinginformation:
§thedata(referredtoasmodeldata)tobeshowntotheuser,and
§logicalnameoftheJSPpage(referredtoasview)thatshowsthemodeldata
Themodeldataisusuallyrepresentedasajava.util.Maptypeobject,andeachentryinthejava.util.Map
object represents amodelattribute. The name of the view (the JSP page) to be shown to the user is
specifiedasaStringvalue.
Example listing 10-1 shows that the HelloWorldControllers handleRequest method returns a
ModelAndView object that contains helloworld (a String value) as the view name and modelData (a
java.util.Maptypeobject)asthemodeldata.ThemodelDatacontainsamsgmodelattributewhosevalue
isthe‘HelloWorld!!message.We’llsoonseethatthemsgmodelattributeisusedbythehelloworld
view(aJSPpage)toshowthe‘HelloWorld!!messagetotheusers.
The following diagram summarizes how HelloWorldControllers handleRequest method renders a JSP
page:
Figure10-2SpringWebMVCframeworkinvokestheHelloWorldControllershandleRequestmethodand
usesthereturnedModelAndViewobjecttorenderthehelloworld.jsppage
TheabovefigureshowsthattheSpringWebMVCframeworkinterceptsanincomingHTTPrequestand
invokes the HelloWorldControllers handleRequest method. The handleRequest method returns a
ModelAndView object that contains the model data and the view information. After receiving the
ModelAndViewobjectfromthehandleRequestmethod,theSpringWebMVCframeworkdispatchesthe
HTTPrequesttothehelloworld.jsppageandmakesthemodelattributesavailabletothehelloworld.jsp
pageasrequestattributes.
NOTE Spring Web MVC makes the model attributes available to the view technology (like JSP and
Velocity) ina format that is suitable forthe view technology.For instance, if you are using JSPas the
viewtechnology,modelattributesaremadeavailabletotheJSPpagesasrequestattributes.
helloworld.jsp–JSPpagethatshowsthe‘HelloWorld!!message
Thefollowingexamplelistingshowsthehelloworld.jsppageofch10-helloworldproject:
Examplelisting10-2–helloworld.jspJSPpage
Project–ch10-helloworld
Sourcelocation-src/main/webapp/WEB-INF/jsp
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<c:outvalue="${msg}"/>
Intheaboveexamplelisting,<c:out>printsthevalueofmsgrequestattribute.Themsgrequestattribute
refers to the msg model attribute returned by HelloWorldControllers handleRequest method (refer
examplelisting10-1).Asthevalueofmsgmodelattributeis‘HelloWorld!!,helloworld.jspJSPpage
shows‘HelloWorld!!message.
myapp-config.xmlWebapplicationcontextXMLfile
Thefollowingexamplelistingshowsthebeansconfiguredinmyapp-config.xmlfileofch10-helloworld
project:
Examplelisting10-3–myapp-config.xml
Project–ch10-helloworld
Sourcelocation-src/main/webapp/WEB-INF/spring
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<beanname="helloWorldController"
class="sample.spring.chapter10.web.HelloWorldController"/>
<beanid="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<propertyname="urlMap">
<map>
<entrykey="/sayhello"value-ref="helloWorldController"/>
</map>
</property>
</bean>
<beanid="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<propertyname="prefix"value="/WEB-INF/jsp/"/>
<propertyname="suffix"value=".jsp"/>
</bean>
</beans>
The above example listing shows that apart from the HelloWorldController, Springs
SimpleUrlHandlerMappingandInternalResourceViewResolverbeansarealsoconfiguredinthemyapp-
config.xmlfile.
SimpleUrlHandlerMapping bean (an implementation of Springs HandlerMapping interface) maps an
incomingHTTPrequesttothecontrollerresponsibleforhandlingtherequest.SimpleUrlHandlerMapping
bean uses the URL path to map a request to a controller. The urlMap property (of type java.util.Map)
specifies URL path to controller bean mapping. In example listing 10-3, the "/sayhello" URL path
(specifiedbythekeyattribute)ismappedtotheHelloWorldControllerbean(specifiedbythevalue-ref
attribute).YoushouldnotethattheURLpathspecifiedbythekeyattributeisrelativetotheURLpathto
which Springs DispatcherServlet (a servlet) is mapped in the web application deployment descriptor.
DispatcherServletisdiscussedlaterinthissection.
InternalResourceViewResolverbean(animplementationofSpringsViewResolverinterface)locatesthe
actualview(like,JSPorservlet)basedontheviewnamecontainedintheModelAndViewobject.The
actual view is located byprepending the value of prefix property and appending the value of suffix
propertytotheviewname.Theexamplelisting10-3showsthatthevalueofprefixpropertyis/WEB-
INF/jsp, and the valueofsuffixpropertyis.jsp. As the HelloWorldControllershandleRequest method
returnsaModelAndViewobjectwhichcontainshelloworldastheviewname,theactualviewis/WEB-
INF/jsp/helloworld.jsp(astringthatisobtainedbyprepending/WEB-INF/jspandappending.jsptothe
helloworldviewname).
The following figure shows the role played by SimpleUrlHandlerMapping and
InternalResourceViewResolverbeansinthe‘HelloWorld’webapplication:
Figure 10-3 SimpleUrlHandlerMapping locates the controller to be invoked and
InternalResourceViewResolverresolvestheactualviewbasedontheviewname
SimpleUrlHandlerMapping and InternalResourceViewResolver beans are automatically detected by
Spring Web MVC and used for finding the controller for request handling and resolving views,
respectively.
web.xmlWebapplicationdeploymentdescriptor
In Spring Web MVC based applications, requests are intercepted by a DispatcherServlet (a servlet
providedbySpringWebMVC)thatisresponsiblefordispatchingrequeststotheappropriatecontroller.
The following example listing shows the configuration of DispatcherServlet in web.xml file of ch10-
helloworldproject:
Examplelisting10-4–web.xml
Project–ch10-helloworld
Sourcelocation-src/main/webapp/WEB-INF/spring
<web-appxmlns="java.sun.com/xml/ns/javaee"
xmlns:xsi="w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="java.sun.com/xml/ns/javaeejava.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/myapp-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/helloworld/*</url-pattern>
</servlet-mapping>
</web-app>
A DispatcherServlet is associated with a web application context XML file which is identified by the
contextConfigLocation servlet initialization parameter. In the above example listing, the
contextConfigLocationinitializationparameterreferstothemyapp-config.xmlfile(referexamplelisting
10-3).
If you don’t specify the contextConfigLocation parameter, the DispatcherServlet looks for the web
application context XML file named <name-of-DispatcherServlet>-servlet.xml file in the   WEB-INF
directory of the web application. Here, the value of <name-of-DispatcherServlet> is the servlet name
specified by the <servlet-name> sub-element of <servlet> that configures the DispatcherServlet. For
instance, if we had not specified the contextConfigLocation parameter in example listing 10-3, the
DispatcherServletwouldhavelookedforafilenamedhello-servlet.xmlintheWEB-INFdirectory.
TheHandlerMappingandViewResolverbeansdefinedinthewebapplicationcontextXMLfileareused
by the DispatcherServlet for request processing. DispatcherServlet uses the HandlerMapping
implementation for finding the appropriate controller for the request, and uses the ViewResolver
implementationforresolvingtheactualviewbasedontheviewnamereturnedbythecontroller.
InthecontextofHelloWorld’webapplication,thefollowingfiguresummarizestheroleplayedbythe
DispatcherServletservletinrequestprocessing:
Figure10-4DispatcherServletusesHandlerMappingandViewResolverbeansforrequestprocessing.
The above figure shows that the following sequence of activities are performed by Spring Web MVC
duringrequestprocessing:
§requestisfirstinterceptedbytheDispatcherServletservlet
§DispatcherServletusestheHandlerMappingbean(whichisSimpleUrlHandlerMappingbeanincase
of‘HelloWorld’webapplication)tofindanappropriatecontrollerforhandlingtherequest
§  DispatcherServlet calls the request handling method of the controller (which is
HelloWorldController’shandleRequestmethodincaseof‘HelloWorld’webapplication)
§DispatcherServletsendstheviewnamereturnedbythecontrollertotheViewResolverbean(which
isInternalResourceViewResolverbeanincaseofHelloWorld’webapplication)tofindtheactual
view(JSPorservlet)toberendered
§  DispatcherServlet dispatches the request to the actual view (JSP or servlet). The model data
returnedbythecontrolleraremadeavailabletotheviewasrequestattributes.
The DispatcherServlet of ‘Hello World’ web application is mapped to /helloworld/* pattern (refer
examplelisting10-4),andSimpleUrlHandlerMappingmaps/sayhelloURLpathtoHelloWorldController
bean (refer example listing 10-3). If you access the URLhttp://localhost:8080/ch10-
helloworld/helloworld/sayhello, itresults in invocation of handleRequest method of
HelloWorldController controller. The following figure shows how Spring Web MVC maps the URL
http://localhost:8080/ch10-helloworld/helloworld/sayhellototheHelloWorldControllercontroller:
Figure10-5HowtheURLpathhttp://localhost:8080/ch10-helloworld/helloworld/sayhelloismappedto
theHelloWorldControllerbySpringWebMVC
Intheabovefigure,the/ch10-helloworldpartoftheURLrepresentsthecontextpathoftheHelloWorld’
webapplication,the/helloworldpartoftheURLmapstotheDispatcherServletservlet(referexample
listing 10-4), and the /sayhello part of the URL maps to the HelloWorldController controller (refer
examplelisting10-3).
In this section, we saw how a simple ‘Hello World’ web application is developed using Spring Web
MVC.LetsnowtakeacloserlookattheDispatcherServletservletthatactsafrontcontrollerinaSpring
WebMVCapplication.
10-4DispatcherServlet–thefrontcontroller
Intheprevioussection,wesawthattheDispatcherServletactsasafrontcontrollerthatinteractswiththe
HandlerMapping andViewResolver beans defined in the web application context XML file to process
requests.Inthissection,we’lllookathowDispatcherServletworksbehindthescenes.
Atthetimeofinitialization,aDispatcherServletloadsthecorrespondingwebapplicationcontextXML
file(whichcouldbespecifiedviacontextConfigLocationinitializationparameter,orisnamedas<name-
of-DispatcherServlet>-servlet.xmlfileandplacedintheWEB-INFdirectory),andcreatesaninstanceof
SpringsWebApplicationContextobject.WebApplicationContextisasub-interfaceofApplicationContext
interface that provides features that are specific to web applications. For instance, beans in the
WebApplicationContext can have additional scopes, like request and session. You can think of
WebApplicationContext object as an object that represents a Spring container instance in Spring Web
MVCapplications.
Thefollowingtabledescribestheadditionalscopesthatyoucanspecifyforbeansconfiguredintheweb
applicationcontextXMLfile:
Beanscope Description
request
SpringcontainercreatesanewbeaninstanceforeveryHTTPrequest.Thebeaninstanceisdestroyed
bytheSpringcontainerwhentheHTTPrequestcompletes.
This scope is valid only for ApplicationContext implementations that are applicable in web
application scenarios. For instance, if you are using XmlWebApplicationContext or
AnnotationConfigWebApplicationContext,onlythenyoucanspecifytherequestscopeforabean.
session
SpringcontainercreatesanewbeaninstancewhenanHTTPSessioniscreated.Thebeaninstanceis
destroyedbytheSpringcontainerwhentheHTTPSessionisdestroyed.
This scope is valid only for ApplicationContext implementations that are applicable in web
application scenarios. For instance, if you are using XmlWebApplicationContext or
AnnotationConfigWebApplicationContext,onlythenyoucanspecifythesessionscopeforabean.
globalS ession Thisscopeisapplicableonlyincaseofportletapplications.
Ifyourwebapplicationconsistsofmultiplemodules,youmaydefineaDispatcherServletforeachofthe
modules in the web.xml file. In such a scenario, each DispatcherServlet has its own web application
contextXMLfilethatcontainsbeans(likecontrollers,viewresolvers,andsoon)specifictothatmodule.
YoushouldnotethatthesebeansarenotsharedbetweenDispatcherServletinstances.Thebeansthatare
sharedbetweenDispatcherServletinstancesaredefinedintherootwebapplicationcontextXMLfile.As
mentionedearlier,therootwebapplicationcontextXMLfiledefinesdatasources,servicesandDAOs,
andsoon,thataretypicallysharedbydifferentmodulesofawebapplication.Refertosection10-10to
learnabouthowtherootwebapplicationcontextXMLfileisloaded.
ThefollowingfigureshowsrelationshipbetweenbeansdefinedbythewebapplicationcontextXMLfile
associatedwithaDispatcherServletandthebeansdefinedbytherootwebapplicationcontextXMLfile:
Figure 10-6 Beans in the root WebApplicationContext are inherited by the WebApplicationContext
instanceassociatedwithaDispatcherServlet
In the above figure, servlet1, servlet2 and servlet3 are the names of DispatcherServlet instances
configured in the web.xml file. And, servlet1-servlet.xml,servlet2-servlet.xml and servlet3-servlet.xml
arewebapplicationcontextXMLfilesthatareloadedbyservlet1,servlet2andservlet3, respectively.
When DispatcherServlet instances are initialized, an instance of WebApplicationContext is created
corresponding to each servlet1-servlet.xml, servlet2-servlet.xml and servlet3-servlet.xml files and
associated with the DispatcherServlet instance. A WebApplicationContext instance is also created
correspondingtotherootwebapplicationcontextXMLfile,root-servlet.xml.Thebeanscontainedinthe
root WebApplicationContext instance are available to all the WebApplicationContext instances
associatedwithDispatcherServlets.
LetsnowlookathowacontrolleroranyotherSpringbeandefinedinawebapplicationcontextXML
filecanaccessServletContextandServletConfigobjects.
AccessingServletContextandServletConfigobjects
In some scenarios, beans defined in the web application context XML file may require access to the
ServletContextorServletConfigobjectassociatedwiththewebapplication.
ServletContextisaServletAPIobjectthatabeancanusetocommunicatewiththeservletcontainer.For
instance,youcanuseittogetandsetcontextattributes,obtaincontextinitializationparameters,andsoon.
If a bean class implements Springs ServletContextAware interface (a callback interface), the Spring
containerprovidesthebeaninstancewithaninstanceofServletContextobject.
ServletConfig isaServletAPIobjectthatabeancanusetoobtain configuration informationaboutthe
DispatcherServlet that intercepted the request. For instance, you can use it to obtain initialization
parameterspassedtotheDispatcherServletandthenamewithwhichtheDispatcherServletisconfigured
inweb.xml.IfabeanclassimplementsSpringsServletConfigAwareinterface(acallbackinterface),the
SpringcontainerprovidesthebeaninstancewithaninstanceofServletConfigobject.
The following example listing shows a bean class that implements ServletContextAware and the
ServletConfigAwareinterface:
Examplelisting10-5–ServletContextAwareandServletConfigAwareusage
importjavax.servlet.ServletConfig;
importjavax.servlet.ServletContext;
importorg.springframework.web.context.ServletConfigAware;
importorg.springframework.web.context.ServletContextAware;
publicclassABeanimplementsServletContextAware,ServletConfigAware{
privateServletContextservletContext;
privateServletConfigservletConfig;
@Override
publicvoidsetServletContext(ServletContextservletContext){
this.servletContext=servletContext;
}
@Override
publicvoidsetServletConfig(ServletConfigservletConfig){
this.servletConfig=servletConfig;
}
publicvoiddoSomething(){
//--useServletContextandServletConfigobjects
}
}
The above example listing shows that the ABean class implements ServletContextAware and
ServletConfigAware interface. The ServletContextAware interface defines a setServletContext method
whichisinvokedbytheSpringcontainertoprovideABeaninstancewithaninstanceofServletContext
object. The ServletConfigAware interface defines a setServletConfig method which is invoked by the
SpringcontainertoprovideABeaninstancewithaninstanceofServletConfigobject.
WesawearlierthatyoucancreateacontrollerbyimplementingtheControllerinterface.Letsnowlook
at@Controllerand@RequestMappingannotationsthatsimplifydevelopingcontrollers.
10-5 Developing controllers using @Controller and
@RequestMappingannotations
Spring Web MVC provides classes, like MultiActionController, UrlFilenameViewController,
AbstractController,andsoon,thatyoucanextendtocreateyourcontrollerimplementation.Ifyouextend
aSpring-specificclassorimplementaSpring-specificinterfacetocreateacontroller,thecontrollerclass
becomes tightly coupled with Spring. Spring 2.5 introduced annotations like @Controller,
@RequestMapping, @ModelAttribute, and so on, that allow you to create controllers with flexible
methodsignatures. In this section,well look at differentSpring Web MVC annotations for developing
annotatedcontrollers.
LetsfirstlookataHelloWorld’webapplicationthatusesanannotatedcontrollertoshowtheHello
World!!message.
IMPORTchapter 10/ch10-annotation-helloworld(This project shows a simple ‘Hello World’ web
applicationthatusesanannotatedcontrollertoshowHelloWorld!!message.Ifyoudeploytheproject
on Tomcat server and access the URL http://localhost:8080/ch10-annotation-
helloworld/helloworld/saySomething/sayhello,youllseethe‘HelloWorld!!message.)
Developinga‘HelloWorld’webapplicationusinganannotatedcontroller
Thech10-annotation-helloworldprojectissimilartoch10-helloworld, except that the ch10-annotation-
helloworld project uses an annotated controller to show ‘Hello World !!’ message. The web.xml and
helloworld.jspfilesinboththeprojectsareexactlythesame,butHelloWorldController.javaandmyapp-
config.xmlfilesaredifferent.Forthisreason,wellrestrictourdiscussiontoHelloWorldController.java
andmyapp-config.xmlfilesinthissection.
Letsfirstlookathowtocreateacontrollerusing@Controllerand@RequestMappingannotations.
@Controllerand@RequestMappingannotations
You designate a particular class as a Spring Web MVC controller by annotating it with @Controller
annotation. And, you use @RequestMapping annotation to map an incoming request to the appropriate
methodofacontroller.
The following example listing shows the HelloWorldController class that uses @Controller and
@RequestMappingannotations:
Examplelisting10-6–HelloWorldControllerclass-@Controllerand@RequestMappingusage
packagesample.spring.chapter10.web;
importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.servlet.ModelAndView;
.....
@Controller(value="sayHelloController")
@RequestMapping("/saySomething")
publicclassHelloWorldController{
@RequestMapping("/sayhello")
publicModelAndViewsayHello(){
Map<String,String>modelData=newHashMap<String,String>();
modelData.put("msg","HelloWorld!!");
returnnewModelAndView("helloworld",modelData);
}
}
In the above example listing, the HelloWorldController class is annotated with @Controller and
@RequestMappingannotations,andthesayHellomethodisannotatedwith@RequestMappingannotation.
@Controllerannotationisaspecializedformof@Componentannotation(referchapter6)thatindicates
thattheHelloWorldControllerisacontrollercomponent.
Like @Service (refer chapter 6) and @Repository (refer chapter 7) annotated classes, @Controller
annotated classes are automatically registered with the Spring container; you dont need to explicitly
define a @Controller annotated class in the web application context XML file. The value attribute of
@ControllerannotationspecifiesthenamewithwhichtheclassisregisteredwiththeSpringcontainer.
Thevalueattributeservesthesamepurposeasthe<bean>element’sidattribute.Ifthevalueattributeis
not specified,thename (beginning with lowercasefirst letter)of the classis usedtoregister the class
withtheSpringcontainer.
@RequestMappingannotationmapsincomingwebrequeststoappropriatecontrollersand/orcontroller
methods.@RequestMappingannotationatthetype-levelmapsarequesttotheappropriatecontroller.For
instance,@RequestMapping("/saySomething")onHelloWorldControllerclassindicatesthatallrequests
to/saySomethingrequestpatharehandledbytheHelloWorldControllercontroller.
@RequestMapping at the method-level narrows down the @RequestMapping at the type-level to a
specific method in the controller class. For instance, @RequestMapping("/sayhello") annotation on
sayHellomethodinexamplelisting10-6specifiesthatthesayHellomethodisinvokedwhentherequest
pathis/saySomething/sayhello.NoticethattheHelloWorldController’ssayHellomethoddoesn’taccept
anyargumentsandreturnsaModelAndViewobject.Thisispossiblebecauseannotatedcontrollerscan
have flexible method signatures. In section 10-7, we’ll look at possible arguments and return types
@RequestMappingannotatedmethodscandefine.
@RequestMapping annotation at the type-level usually specifies a request path or a path pattern. And,
@RequestMapping annotation at the method-level usually specifies an HTTP method or a request
parametertofurthernarrowdownthemappingspecifiedbythetype-level@RequestMappingannotation.
The following figure shows how http://localhost:8080/ch10-annotation-
helloworld/helloworld/saySomething/sayhello URL will resultin invocationof HelloWorldController’s
sayHellomethodbySpringWebMVC:
Figure10-7HowarequestURLismappedtoanappropriate@RequestMappingannotatedmethodofa
controller
Theabovefigure shows howaparticularrequestURLresults ininvocation ofHelloWorldControllers
sayHellomethod.
Letsnowlookathowannotation-drivendevelopmentofSpringWebMVCcontrollersisenabledinan
application.
EnablingSpringWebMVCannotations
TouseannotatedcontrollersinyourSpringWebMVCapplication,youneedtoenableSpringWebMVC
annotations using <annotation-driven> element of Springs mvc schema, as shown in the following
examplelisting:
Examplelisting10-7–myapp-config.xml
Project–ch10-annotation-helloworld
Sourcelocation-src/main/webapp/WEB-INF/spring
<beans.....
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation=".....http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd.....">
<mvc:annotation-driven/>
<context:component-scanbase-package="sample.spring.chapter10.web"/>
<beanid="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<propertyname="prefix"value="/WEB-INF/jsp/"/>
<propertyname="suffix"value=".jsp"/>
</bean>
</beans>
In the aboveexample listing,<mvc:annotation-driven>element ofSprings mvc schema enables use of
Spring Web MVC annotations in implementing controllers. Also, <component-scan> element (refer
section6-2formoredetails)ofcontextschemaisusedtoautomaticallyregister@Controllerannotated
classeswiththeSpringcontainer.
Inthissection,wesawhowtodevelopasimpleHelloWorld’webapplicationusing@Controllerand
@RequestMappingannotations.LetsnowlookattherequirementsoftheMyBankwebapplicationthat
we’lldevelopinthischapterusingSpringWebMVCannotations.
10-6MyBankwebapplicationsrequirements
ThefollowingfigureshowsthehomepageofMyBankwebapplicationthatdisplaysalistofcurrently
activefixeddepositsinthesystem:
Figure10-8MyBankwebapplicationshomepageshowsfixeddepositdetails.Thewebpageprovides
theoptiontoclose,editandcreateafixeddeposit.
In the above figure, the ID column shows the unique identifier for a fixed deposit. The ID value is
assignedtoafixeddepositwhenitiscreatedbyauser.CloseandEdithyperlinksallowausertoremove
oreditdetailsofafixeddeposit.TheCreatenewFixedDepositbuttonshowstheOpenfixeddeposit
formforenteringdetailsofthefixeddeposittobeopened,asshowninthefollowingfigure:
Figure10-9Openfixeddeposit’formforopeningfixeddeposits.Amount,TenureandEmailfieldsare
mandatory.
Intheabovefigure,clickingtheSavebuttonsavesthefixeddepositdetailsinthedatastore,andGoBack
hyperlinktakestheuserbacktothewebpagethatshowsthefixeddepositlist(referfigure10-8).The
above figure shows that appropriate error messages are displayed if the entered data doesnt meet the
constraintssetonAmount,TenureandEmailfields.
WhenyouclicktheEdithyperlinkinfigure10-8,aformsimilartofigure10-9isshownformodifying
details of the selected fixed deposit. And, clicking the Close hyperlink in figure 10-8 removes the
selectedfixeddepositfromthelistoffixeddeposits.
Now,thatweknowtheMyBankwebapplicationrequirements,letslookathowweimplementitusing
SpringWebMVCannotations.
10-7 Spring Web MVC annotations - @RequestMapping and
@RequestParam
Insection10-5,wesawthatwecanuse@Controllerand@RequestMapping annotations todevelop a
simple controller. Inthis section,well take acloser look at @RequestMapping and other Spring Web
MVCannotationsthatsimplifydevelopingannotatedcontrollers.
IMPORTchapter10/ch10-bankapp(This project shows the MyBank web application that allows its
user to manage fixed deposits. If you deploy the project on Tomcat server and access the URL
http://localhost:8080/ch10-bankapp,youllseethelistoffixeddeposits(asshowninfigure10-8)inthe
system.)
Letsbeginbylookingatthe@RequestMappingannotation.
Mappingrequeststocontrollersorcontrollermethodsusing@RequestMapping
Insection10-5,wesawthatthe@RequestMapping annotation isused atthetypeandmethod-level to
map requests to controllers and its methods. In this section, we’ll first look at how Spring Web MVC
mapsawebrequesttoaparticularcontrollermethodthatuses@RequestMappingannotation.Wellthen
look at the attributes of @RequestMapping annotation, and the arguments and return types that
@RequestMappingannotatedmethodscanhave.
@RequestMappingannotationandRequestMappingHandlerMapping
Thefollowingexample listing shows@RequestMapping annotation usage inSomeController (a Spring
WebMVCcontroller)class:
Examplelisting10-8–SomeControllerclass-@RequestMappingusage
@Controller
@RequestMapping("/type_Level_Url")
publicclassSomeController{
@RequestMapping("/methodA_Url")
publicModelAndViewmethodA(){.....}
@RequestMapping("/methodB_Url")
publicModelAndViewmethodB(){.....}
}
The <annotation-driven> element of Springs mvc schema creates an instance of
RequestMappingHandlerMapping(aHandlerMappingimplementation)thatisresponsibleformappinga
web request to an appropriate @RequestMapping annotated method. RequestMappingHandlerMapping
considers controller methods as endpoints, and is responsible for uniquely mapping a request to a
controller method based on the @RequestMapping annotations at type- and method-level. In case of
SomeController, if the request path is /type_Level_Url/methodA_Url, methodA is invoked, and if the
request path is /type_Level_Url/methodB_Url, methodB is invoked. You should note that if a request
cannotbemappeduniquelytoacontrollermethod,thenaHTTP404(whichmeans,resourcenotfound)
statuscodeisreturned.
Theattributesof@RequestMappingannotationareusedtonarrowdownthemappingofarequesttoa
particular controlleroracontrollermethod.Youcanspecifytheseattributesatbothtype-andmethod-
level@RequestMappingannotations.Let’snowlookattheattributesof@RequestMappingannotation.
Mappingrequestsbasedonrequestpath
@RequestMappingsvalueattributespecifiestherequestpathtowhichacontrollerorcontrollermethod
is mapped. You can specify the request path without explicitly specifying the value attribute in the
@RequestMapping annotation. For instance, you can specify @RequestMapping(value =
"/type_Level_Url")as@RequestMapping("/type_Level_Url").
YoucanalsospecifyAnt-stylepathpatternsasthevalueofvalueattribute.Forinstance,youcanspecify
patterns,like/myUrl/*,/myUrl/**and/myUrl/*.do,asthevalueofvalueattribute.Thefollowingexample
listingshowsa@RequestMappingannotationthatspecifies/myUrl/**asthepathpattern:
Examplelisting10-9–SomeControllerclass–Ant-stylerequestpathpatternusage
@Controller
@RequestMapping("/myUrl/**")
publicclassSomeController{.....}
Intheaboveexamplelisting,@RequestMapping("/myUrl/**")annotationatthetype-levelspecifiesthat
theSomeControllercontrollerhandlesallrequeststhatbeginwith/myUrlpath.Forinstance,requeststo
/myUrl/abc,/myUrl/xyzand/myUrl/123/somethingpathsarehandledbySomeControllercontroller.
MappingrequestsbasedonHTTPmethods
@RequestMappings method attribute specifies the HTTP method that is handled by the controller or
controller method. So, if the method attribute specifies an HTTP GET method, the controller or the
controllermethodhandlesonlyHTTPGETrequests.
The following example listing shows the FixedDepositControllers listFixedDeposits method that is
responsibleforrenderingthelistoffixeddepositsinthesystem:
Examplelisting10-10–@RequestMappingsmethodattributeusage
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importorg.springframework.web.bind.annotation.RequestMethod;
.....
@Controller
@RequestMapping(value="/fixedDeposit")
publicclassFixedDepositController{
.....
@RequestMapping(value="/list",method=RequestMethod.GET)
publicModelAndViewlistFixedDeposits(){.....}
.....
}
In the above example listing, @RequestMapping annotation on the listFixedDeposits method specifies
value of method attribute as RequestMethod.GET. The RequestMethod is an enum that defines HTTP
request methods, like GET,POST,PUT,DELETE, and so on. As the value of the method attribute is
RequestMethod.GET,thelistFixedDepositsmethodisinvoked onlyif an HTTP GET requestis sentto
/fixedDeposit/list path. For instance, if you send an HTTP POST request to /fixedDeposit/list path,
applicationwillreturnanHTTP405(whichmeans,theHTTPmethodisnotsupported)statuscode.
You can also specify an array of HTTP methods as the value of method attribute, as shown in the
followingexamplelisting:
Examplelisting10-11–SpecifyingmultipleHTTPmethodsasthevalueofmethodattribute
@Controller
@RequestMapping(value="/sample")
publicclassMyController{
@RequestMapping(value="/action"method={RequestMethod.GET,RequestMethod.POST})
publicModelAndViewaction(){.....}
}
In the above example listing, the action method is annotated with @RequestMapping annotation whose
methodattribute’s value is { RequestMethod.GET,RequestMethod.POST}. This means that the action
methodisinvokedifanHTTPGETorPOSTrequestissentto/sample/actionpath.
Mappingrequestsbasedonrequestparameters
@RequestMappingsparamsattributetypicallyspecifiesthenameandvalueoftherequestparameterthat
must be present in the request. The following example listing shows the FixedDepositControllers
showOpenFixedDepositForm method that is responsible for showing the form for creating a fixed
deposit:
Examplelisting10-12–@RequestMappingsparamsattributeusage
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importorg.springframework.web.bind.annotation.RequestMethod;
.....
@Controller
@RequestMapping(value="/fixedDeposit")
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=createFDForm",method=RequestMethod.POST)
publicModelAndViewshowOpenFixedDepositForm(){.....}
.....
}
Intheaboveexamplelisting,@RequestMappingannotationontheshowOpenFixedDepositFormmethod
specifies the value of params attribute as fdAction=createFDForm. As the FixedDepositController is
mapped to /fixedDeposit path, the showOpenFixedDepositForm method is invoked if an HTTP POST
requestcontainingrequestparameternamedfdActionwithvaluecreateFDFormissentto/fixedDeposit
path.
Ifyouwanttomaprequeststoacontrollerorcontrollermethodbasedonthevaluesofmultiplerequest
parameters, you can specify an array of request parameter name-value pairs as the value of params
attribute,asshowninthefollowingexamplelisting:
Examplelisting10-13–Specifyingmultiplerequestparametername-valuepairsasthevalueofparams
attribute
@RequestMapping(params={"x=a","y=b"})
publicvoidperform(){.....}
Intheaboveexamplelisting,theperformmethodisinvokedonlyiftherequestcontainsparametersnamed
xandywithvaluesaandb,respectively.
You can also map requests to a controller or controller method based on the existence of a request
parameterintherequest.Allyouneedtodoistosimplyspecifythenameoftherequestparameterasthe
value of params attribute. For instance, the perform method shown here is invoked irrespective of the
valueofrequestparameterx:
Examplelisting10-14–performmethodisinvokedifrequestparameterxisfound
@RequestMapping(params="x")
publicvoidperform(){.....}
To map requests to a controller or controller method if a request parameter does not exist, use the !
operator. For example, the following perform method is invoked if request parameter named x is not
foundintherequest:
Examplelisting10-15–performmethodisinvokedifrequestparameterxisnotfound
@RequestMapping(params="!x")
publicvoidperform(){.....}
You can use != operator to map requests to a controller or controller method if the value of a request
parameterisnotequaltothespecifiedvalue,asshownhere:
Examplelisting10-16–performmethodisinvokedifthevalueofrequestparameterxisnotequaltoa
@RequestMapping(params="x!=a")
publicvoidperform(){.....}
Intheaboveexamplelisting,performmethodisinvokedonlyiftherequestcontainsarequestparameter
namedx,andthevalueofxisnotequaltoa.
MappingrequestsbasedontheMIMEtypeoftherequest
TheContent-TyperequestheaderspecifiestheMIMEtypeoftherequest.@RequestMappingsconsumes
attributespecifiestheMIMEtypeoftherequestthatacontrolleroracontrollermethodhandles.So,ifthe
valueofconsumesattributematchesthevalueoftheContent-Typerequestheader,therequestismapped
tothatparticularcontrollerorcontrollermethod.
The following example listing shows that the perform method is invoked if the Content-Type request
headersvalueisapplication/json:
Example listing 10-17 – perform method is invoked if the value of Content-Type header is
application/json
@RequestMapping(consumes="application/json")
publicvoidperform(){.....}
Aswiththeparamsattribute,youcanuse!operatortospecifytheconditionthataContent-Typeheader
valueisnotpresent.Forinstance,thefollowingperformmethodisinvokediftheContent-Typeheaders
valueisnotapplication/json:
Example listing 10-18 – perform method is invoked if the value of Content-Type header is not
application/json
@RequestMapping(consumes="!application/json")
publicvoidperform(){.....}
Youcanspecifyanarrayofvaluesintheconsumesattribute,inwhichcasetherequestismappedtothe
controllerorthecontrollermethodiftheContent-Typevaluematchesoneofthevaluesspecifiedbythe
consumesattribute.Inthefollowingexamplelisting,theperformmethodisinvokediftheContent-Typeis
application/jsonortext/plain:
Examplelisting10-19–performmethodisinvokedifContent-Typeisapplication/jsonortext/plain
@RequestMapping(consumes={"application/json","text/plain")
publicvoidperform(){.....}
MappingrequestsbasedontheacceptableMIMEtypeoftheresponse
The Accept request header specifies the acceptable MIME type of the response. @RequestMappings
produces attribute specifies the acceptable MIME type of the response. So, if the value of produces
attributevaluematchestheAcceptrequestheader,therequestismappedtothatparticularcontrolleror
controllermethod.
ThefollowingexamplelistingshowsthattheperformmethodisinvokediftheAcceptrequestheaders
valueisapplication/json:
Examplelisting10-20–performmethodisinvokedifthevalueofAcceptheaderisapplication/json
@RequestMapping(produces="application/json")
publicvoidperform(){.....}
As with the consumes attribute, you can use ! operator to specify the condition that an Accept header
valueisnotpresentintherequest.Ifyouspecifyanarrayofvaluesfortheproducesattribute,requestis
mappedtothecontrollerorthecontrollermethodiftheAcceptheadervaluematchesoneofthevalues
specifiedbytheproducesattribute.
Mappingrequestsbasedonarequestheadervalue
To map requests based on request headers, you can use @RequestMappings headers attribute. The
followingexamplelistingshowsthattherequestismappedtotheperformmethodifthevalueofContent-
Typeheaderistext/plain:
Examplelisting10-21–performmethodisinvokedifthevalueofContent-Typeheaderistext/plain
@RequestMapping(headers="Content-Type=text/plain")
publicvoidperform(){.....}
Aswiththeparamsattribute,youcanuse!and!=operatorswhilespecifyingvalueofheadersattribute.
Forinstance,thefollowingexamplelistingshowsthattherequestismappedtotheperformmethodifthe
valueofContent-Typeheaderisnotequaltoapplication/json,theCache-Controlheaderdoesn’texistin
therequest,andtheFromheaderexistsintherequestwithanyvalue:
Examplelisting10-22–Using!and!=operatorsforspecifyingvalueofheadersattribute
@RequestMapping(headers={"Content-Type!=application/json","!Cache-Control","From"})
publicvoidperform(){.....}
Now,thatwehavelookedattheattributesof@RequestMappingannotation,letslookatthearguments
thatyoucanpassto@RequestMappingannotatedmethods.
@RequestMappingannotatedmethodsarguments
@RequestMappingannotatedmethodscanhaveflexiblemethodsignatures.Theargumenttypesthatcan
be passed to @RequestMapping annotated methods include HttpServletRequest, HttpSession,
java.security.Principal, org.springframework.validation.BindingResult,
org.springframework.web.bind.support.SessionStatus,org.springframework.ui.Model,andsoon.Toview
acompletelistofargumentsthatcanbepassedto@RequestMappingannotatedmethod,pleasereferto
@RequestMappingJavadoc.
As we discuss different Spring Web MVC features in this book, we’ll come across scenarios which
requireustopassdifferentargumenttypesto@RequestMappingannotatedmethods.Fornow,welllook
atascenarioinwhichweneedtosendHttpServletRequestobjectasanargument.
ThefollowingexamplelistingshowstheFixedDepositControllersviewFixedDepositDetailsmethodthat
acceptsanargumentoftypeHttpServletRequest:
Examplelisting10-23–FixedDepositControllerclass-passingHttpServletRequestargument
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importjavax.servlet.http.HttpServletRequest;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=view",method=RequestMethod.GET)
publicModelAndViewviewFixedDepositDetails(HttpServletRequestrequest){
FixedDepositDetailsfixedDepositDetails=fixedDepositService
.getFixedDeposit(Integer.parseInt(request.getParameter("fixedDepositId")));
.....
}
.....
}
TheviewFixedDepositDetailsmethodisinvokedwhenyouclicktheEdithyperlink corresponding toa
fixeddeposit(referfigure10-8).HttpServletRequestisusedbytheviewFixedDepositDetailsmethodto
obtainthefixedDepositIdrequestparameterthatuniquelyidentifiesafixeddepositinthesystem.
Letsnowlookatthereturntypesthataresupportedfor@RequestMappingannotatedmethods.
@RequestMappingannotatedmethodsreturntypes
The supported return types for @RequestMapping annotated methods include ModelAndView,
org.springframework.web.servlet.View,String,java.util.concurrent.Callable,void,andsoon.Toviewa
complete list of return types supported for @RequestMapping annotated methods, please refer to
@RequestMappingJavadoc.
As we discuss different Spring Web MVC features in this book, we’ll come across scenarios which
require@RequestMapping annotated methods to have different return types. In this section, we’ll only
lookatexamplesthatshowmethodsthathaveStringorModelAndViewasreturntypes.
ThefollowingexamplelistingshowsFixedDepositController’sshowOpenFixedDepositFormmethodthat
renderstheHTMLformforopeninganewfixeddeposit(referfigure10-9):
Examplelisting10-24–FixedDepositControllerclass-ModelAndViewreturntypeexample
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importorg.springframework.ui.ModelMap;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=createFDForm",method=RequestMethod.POST)
publicModelAndViewshowOpenFixedDepositForm(){
FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();
fixedDepositDetails.setEmail("Youmustenteravalidemail");
ModelMapmodelData=newModelMap();
modelData.addAttribute(fixedDepositDetails);
returnnewModelAndView("createFixedDepositForm",modelData);
}
.....
}
TheshowOpenFixedDepositForm method returns a ModelAndView object that contains an instance of
FixedDepositDetailsasamodelattributeandcreateFixedDepositFormstringvalueastheviewname.
If you compare the above example listing with 10-1 and 10-6, youll notice that the
showOpenFixedDepositForm method uses Springs ModelMap object instead of java.util.Map to store
model attributes. ModelMap is an implementation of java.util.Map interface that allows you to store
modelattributeswithoutexplicitlyspecifyingtheirnames.ModelMapautomaticallygeneratesthenameof
themodelattributebasedon apre-definedstrategy.Forinstance, ifyouaddacustomJavaobjectasa
modelattribute,thename(beginningwithlowercasefirstletter)oftheobjectsclassisusedasthename
ofthemodelattribute.Intheaboveexamplelisting,whenaninstanceofFixedDepositDetailsisaddedto
theModelMap,itisstoredintheModelMapwiththenamefixedDepositDetails.
Whena@RequestMappingannotatedmethodreturnsastringvalue,itisconsideredasthenameofthe
viewthatisresolvedtoanactualview(like,JSPpageorservlet)bytheViewResolverconfiguredforthe
web application. The following example listing shows the configuration of
InternalResourceViewResolverinch10-bankappproject:
Examplelisting10-25–bankapp-config.xml–ViewResolverconfiguration
Project–ch10-bankapp
Sourcelocation-src/main/webapp/WEB-INF/spring
<beanid="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<propertyname="prefix"value="/WEB-INF/jsp/"/>
<propertyname="suffix"value=".jsp"/>
</bean>
The above configuration suggests that when a string value xyz is returned, it is resolved to /WEB-
INF/jsp/xyz.jsp.Refersection10-3tolearnmoreabouttheInternalResourceViewResolverconfiguration
shownabove.
If the string value returned by the @RequestMapping annotated method has the prefix redirect:, it is
treated as a redirect URL and not as a view name. The following example listing shows
FixedDepositController’scloseFixedDepositmethodthatisresponsibleforclosingafixeddepositwhen
auserclickstheClosebutton(referfigure10-9):
Examplelisting10-26–FixedDepositControllerclass-Stringreturntypeexample
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
@RequestMapping(params="fdAction=close",method=RequestMethod.GET)
publicStringcloseFixedDeposit(.....intfdId){
fixedDepositService.closeFixedDeposit(fdId);
return"redirect:/fixedDeposit/list";
}
FixedDepositController’s closeFixedDeposit method closes the fixed deposit identified by the fdId
argumentandreturnsredirect:/fixedDeposit/liststringvalue.Asthereturnedstringvalueisprefixedwith
redirect:,theuserisredirectedtothe/fixedDeposit/listURLthatshowsthelistoffixeddeposits(refer
figure10-8).
Letsnowlookatthe@RequestParamannotationthatallowsyoutoassignarequestparametervaluetoa
controllermethodargument.
Passingrequestparameterstocontrollermethodsusing@RequestParam
Wesawinexamplelisting10-23thatwecanpassHttpServletRequestobjecttoacontrollermethodand
useittoretrieverequestparameters.InsteadofpassingHttpServletRequestobjecttoacontrollermethod,
you can annotate a method argument with @RequestParam annotation to assign value of a request
parametertothemethodargument.
NOTEYoushouldnotethatthe@RequestParamannotationcanonlybeusedifthemethodisannotated
with@RequestMappingor@ModelAttribute(explainedinchapter11)annotation.
ThefollowingexamplelistingshowsFixedDepositControllerscloseFixedDepositmethodthatisinvoked
whenauserclickstheClosebutton(referfigure10-8)tocloseafixeddeposit:
Examplelisting10-27–FixedDepositControllerclass-@RequestParamusage
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importorg.springframework.web.bind.annotation.RequestParam;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=close",method=RequestMethod.GET)
publicStringcloseFixedDeposit(@RequestParam(value="fixedDepositId")intfdId){
fixedDepositService.closeFixedDeposit(fdId);
return"redirect:/fixedDeposit/list";
}
.....
}
@RequestParamsvalueattributespecifiesthenameoftherequestparameterwhosevalueisassignedto
themethodargument.Intheaboveexamplelisting,@RequestParamannotationisusedtoassignthevalue
offixedDepositId request parameter to fdId method argument. As the type of the fdId argument is int,
SpringisresponsibleforconvertingthefixedDepositIdrequestparametertointtype.Bydefault,Spring
automaticallyprovidestypeconversionforsimpleJavatypes,likeint,long,java.util.Date,andsoon.To
convert request parameters to custom Java types (like Address), you need to register custom
PropertyEditors with Springs WebDataBinder instance or org.springframework.format.Formatters with
SpringsFormattingConversionService instance. We’ll learnmore about WebDataBinder in chapter 11,
andFormatterandFormattingConversionServiceinchapter13.
Letsnowlookathowyoucanaccessalltherequestparametersinacontrollermethod.
Passingalltherequestparameterstoacontrollermethod
Topassalltherequestparameterstoacontrollermethod,defineanargumentoftypeMap<String,String>
orMultiValueMap<String,String>(anobjectprovidedbySpringthatimplementsjava.util.Mapinterface)
andannotateitwith@RequestParamannotation.
ThefollowingexamplelistingshowsFixedDepositControllersopenFixedDepositmethodthatcreatesa
fixed deposit when a user enters fixed deposit details and clicks the Save button on the ‘Open fixed
depositformforopeningfixeddeposits(referfigure10-9):
Examplelisting10-28–FixedDepositControllerclass–accessingallrequestparameters
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importjava.util.Map;
.....
@RequestMapping(value="/fixedDeposit")
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicModelAndViewopenFixedDeposit(@RequestParamMap<String,String>params){
StringdepositAmount=params.get("depositAmount");
Stringtenure=params.get("tenure");
.....
}
}
In the above example listing, params argument of type Map<String, String> is annotated with
@RequestParamannotation.Noticethatthevalueattributeof@RequestParamannotationisnotspecified.
If@RequestParamsvalueattributeisnotspecifiedandthetypeofthemethodargumentisMap<String,
String> or MultiValueMap<String, String>, Spring copies all the requests parameters into the method
argument.EachrequestparametersvalueisstoredintheMap(orMultiValueMap)withthenameofthe
requestparameterasthekey.
The following example listing shows FixedDepositController’s editFixedDeposit method that is
responsibleformakingchangestoanexistingfixeddeposit:
Examplelisting10-29–FixedDepositControllerclass–accessingallrequestparameters
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importorg.springframework.util.MultiValueMap;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)
publicModelAndVieweditFixedDeposit(@RequestParamMultiValueMap<String,String>params)
{
StringdepositAmount=params.get("depositAmount").get(0);
Stringtenure=params.get("tenure").get(0);
.....
}
}
In the above example listing, editFixedDeposits params argument is of type MultiValueMap<String,
String>,andisannotatedwith@RequestParamannotation.IfanobjectisoftypeMultiValueMap<K,V>,
thenitmeansthatKisthetypeofthekeyandList<V>isthetypeofthevalue.Astheparamsargumentis
oftypeMultiValueMap<String, String>, it means that the key is of type String and the value is of type
List<String>. When storing request parameters in MultiValueMap<String, String> type, Spring uses
request parameters name as key and the value of the request parameter is added to the List<String>
value.MultiValueMapisparticularlyusefulifyouhavemultiplerequestparameterswiththesamename.
AsthevaluecorrespondingtoarequestparameterisoftypeList<String>,callingparams.get(Stringkey)
returnsaList<String>type.Forthisreason,get(0)iscalledonthereturnedList<String>togetthevalue
ofrequestparametersdepositAmount,tenure,andsoon.Alternatively,youcanusegetFirst(String key)
methodofMultiValueMaptoobtainthefirstelementfromtheList<String>value.
Letsnowtakeacloserlookatthevariousattributesof@RequestParamannotation.
Specifyingrequestparameternameusingvalueattribute
Wesawearlierthat@RequestParam’svalueattributespecifiesthenameoftherequestparameterwhose
valueisassignedtothemethodargument.Ifyoudon’tspecifythenameofarequestparameter,method
argumentnameisconsideredasthenameoftherequestparametername.Forinstance,inthefollowing
examplelisting,valueofrequestparameternamedparamisassignedtotheparamargument:
Examplelisting10-30–@RequestParamusage-unspecifiedrequestparametername
@RequestMapping(.....)
publicStringdoSomething(@RequestParamStringparam){.....}
Intheaboveexamplelisting,@RequestParamdoesntspecifythenameoftherequestparameterwhose
value is assigned to the param argument; therefore, param is considered as the name of the request
parameter.
Specifyingrequestparameterisoptionalormandatorybyusingrequiredattribute
Bydefault,requestparameterspecifiedbythe@RequestParamannotationismandatory;ifthespecified
request parameter is not found in the request, an exception is thrown. You can specify that the request
parameterisoptionalbysettingthevalueofrequiredattributetofalse,asshownhere:
Examplelisting10-31–@RequestParamsrequiredattribute
@RequestMapping(.....)
publicStringperform(@RequestParam(value="myparam",required=false)Stringparam){.....}
Intheaboveexamplelisting,@RequestParamsrequiredattributevalueissettofalse,whichmeansthat
themyparam requestparameterisoptional. Now, if the myparam requestparameter is not foundinthe
request,itllnotresultinanexception.Instead,anullvalueisassignedtotheparammethodargument.
SpecifyingdefaultvalueforarequestparameterusingdefaultValueattribute
@RequestParamsdefaultValueattributespecifiesthedefaultvalueforarequestparameter.Iftherequest
parameterspecifiedby@RequestParamsvalueattributeisnotfoundintherequest,thevaluespecified
by the defaultValue attribute is assigned to the method argument. The following example listing shows
usageofdefaultValueattribute:
Examplelisting10-32–@RequestParamsdefaultValueattribute
@RequestMapping(.....)
publicStringperform(@RequestParam(value="location",defaultValue="earth")Stringparam){
.....
}
Intheaboveexamplelisting,ifrequestparameternamedlocationisnotfoundintherequest,thevalue
earthisassignedtotheparammethodargument.
In this section, we looked at @RequestMapping and @RequestParam annotations to create the
FixedDepositController of MyBank application. Lets now look at how validation of form data is
performedintheFixedDepositControllerclass.
10-8Validation
WesawearlierthatFixedDepositController’sshowOpenFixedDepositFormmethod(referexamplelisting
10-24) renders createFixedDepositForm.jsp JSP page that shows the form for opening a new fixed
deposit. When the form is submitted, the data entered in the form is validated by
FixedDepositController’sopenFixedDepositmethod(referexamplelisting10-28).Iferrorsarereported
during validation, the createFixedDepositForm.jsp JSP page is rendered again with validation error
messagesandtheoriginalformdatathatwasenteredbytheuser(referfigure10-9).
Thefollowingexamplelistingshowsthe<form>elementofcreateFixedDepositForm.jspJSPpage:
Examplelisting10-33–createFixedDepositForm.jsp–<form>element
Project–ch10-bankapp
Sourcelocation-src/main/webapp/WEB-INF/jsp
<formname="createFixedDepositForm"method="POST"
action="${pageContext.request.contextPath}/fixedDeposit?fdAction=create">
.....
<inputtype="submit"value="Save"/>
</form>
Intheaboveexamplelisting,<form>elementsmethodattributespecifiesPOSTastheHTTPmethod,and
actionattributespecifies/fixedDeposit?fdAction=createastheURLtowhichtheformissubmittedwhen
the user clicks the Save button. Submission of the form results in the invocation of
FixedDepositController’sopenFixedDepositmethod.
ThefollowingexamplelistingshowshowthevalidationisperformedbytheopenFixedDepositmethod,
andhowtheoriginalformdataenteredbytheuserisshownagainincaseofvalidationerrors:
Examplelisting10-34–FixedDepositControllersopenFixedDepositmethod
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
.....
importorg.apache.commons.lang3.math.NumberUtils;
@RequestMapping(value="/fixedDeposit")
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicModelAndViewopenFixedDeposit(@RequestParamMap<String,String>params){
StringdepositAmount=params.get("depositAmount");
.....
Map<String,Object>modelData=newHashMap<String,Object>();
if(!NumberUtils.isNumber(depositAmount)){
modelData.put("error.depositAmount","enteravalidnumber");
}elseif(NumberUtils.toInt(depositAmount)<1000){
modelData.put("error.depositAmount","mustbegreaterthanorequalto1000");
}
.....
FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();
fixedDepositDetails.setDepositAmount(depositAmount);
.....
if(modelData.size()>0){//--thismeanstherearevalidationerrors
modelData.put("fixedDepositDetails",fixedDepositDetails);
returnnewModelAndView("createFixedDepositForm",modelData);
}else{
fixedDepositService.saveFixedDeposit(fixedDepositDetails);
returnnewModelAndView("redirect:/fixedDeposit/list");
}
}
.....
}
TheopenFixedDepositmethodvalidatesdepositamount,tenureandemailinformationenteredbytheuser.
Notice that to simplify validation of data, NumberUtils class of Apache Commons Lang
(http://commons.apache.org/proper/commons-lang/)libraryhasbeenused.ThemodelDatavariableisa
java.util.MapobjectthatstoresmodelattributesthatwewanttopasstothecreateFixedDepositForm.jsp
JSPpageincaseofvalidationerrors.
As we want to show validation error messages and the original form data if validation fails, the
validationerrormessagesandtheoriginalformdataarestoredinmodelData.Forinstance,ifthedeposit
amount entered by the user fails validation, an appropriate validation error message is stored in the
modelDatawithnameerror.depositAmount.Thevaluesenteredbytheuseraresetonanewinstanceof
FixedDepositDetails object. If validation errors are reported, the newly created FixedDepositDetails
instanceisaddedtothemodelDatawithnamefixedDepositDetails,andthecreateFixedDepositForm.jsp
JSP page is rendered. Alternatively, if no validation errors are reported, the newly created
FixedDepositDetailsobjectissavedinthedatasource,andthepagethatshowsthecompletelistoffixed
depositsisrendered.
AsweareusingFixedDepositDetailsobject tostore theoriginalform data enteredbytheuser, allthe
attributesofFixedDepositDetailshavebeendefinedoftypeString,asshownhere:
Examplelisting10-35–FixedDepositDetailsclass
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/domain
packagesample.spring.chapter10.domain;
publicclassFixedDepositDetails{
privatelongid;//--idvalueissetbythesystem
privateStringdepositAmount;
privateStringtenure;
privateStringemail;
//--gettersandsettersforfields
.....
}
AsdepositAmountandtenurefieldsaredefinedoftypeString,wehadtowriteextralogictoconvertthem
intonumericvaluesforperformingnumericalcomparisons.Inchapter11,welllookathowSpringWeb
MVCsimplifiesbindingformdatatoformbackingobjects(likeFixedDepositDetails)andre-displaying
theoriginalformdataincaseofvalidationerrors.
The following fragments from the createFixedDepositForm.jsp JSP page demonstrate how validation
errormessagesandtheoriginalformdataaredisplayedintheMyBankapplication:
Examplelisting10-36–createFixedDepositForm.jsp
Project–ch10-bankapp
Sourcelocation-src/main/webapp/WEB-INF/jsp
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<formname="createFixedDepositForm"method="POST"
action="${pageContext.request.contextPath}/fixedDeposit?fdAction=create">
.....
<tdclass="td"><b>Amount(inUSD):</b></td>
<tdclass="td">
<inputtype="text"name="depositAmount"
value="${requestScope.fixedDepositDetails.depositAmount}"/>
<fontstyle="color:#C11B17;">
<c:outvalue="${requestScope['error.depositAmount']}"/></font>
</td>
.....
<inputtype="submit"value="Save"/>
</form>
In the above example listing, the value of depositAmount form field is specified as
${requestScope.fixedDepositDetails.depositAmount}. In the openFixedDeposit method (refer example
listing10-34),weaddedaFixedDepositDetailsinstanceasamodelattributenamedfixedDepositDetails;
therefore,the${requestScope.fixedDepositDetails.depositAmount}expressionshows theoriginalvalue
thattheuserenteredforthedepositAmountfield.
The expression ${requestScope['error.depositAmount']} refers to the error.depositAmount request
attribute. In the openFixedDeposit method (refer example listing 10-34), we saw that the
error.depositAmountcontainsvalidationerrormessagecorrespondingtothefixeddepositamountentered
bytheuser;therefore,the<c:outvalue="${requestScope['error.depositAmount']}"/>elementshowsthe
validationerrormessagecorrespondingtothefixeddepositamountenteredbytheuser.
LetsnowlookathowtohandleexceptionsinSpringWebMVCapplications.
10-9Handlingexceptionsusing@ExceptionHandlerannotation
@ExceptionHandlerannotationisusedinanannotatedcontrollertoidentifythemethodresponsiblefor
handling exceptions thrown by the controller. Springs HandlerExceptionResolver is responsible for
mapping an exception to an appropriate controller method responsible for handling the exception. You
should note that the <annotation-driven> element of Springs mvc schema configures an instance of
ExceptionHandlerExceptionResolver (a HandlerExceptionResolver implementation) that maps an
exceptiontoanappropriate@ExceptionHandlerannotatedmethod.
Thefollowingexamplelistingshowsusageof@ExceptionHandlerannotationinch10-bankappproject:
Examplelisting10-37–@ExceptionHandlerannotationusage
Project–ch10-bankapp
Sourcelocation-src/main/java/sample/spring/chapter10/web
packagesample.spring.chapter10.web;
importorg.springframework.web.bind.annotation.ExceptionHandler;
.....
@Controller
@RequestMapping(value="/fixedDeposit")
publicclassFixedDepositController{
.....
@ExceptionHandler
publicStringhandleException(Exceptionex){
return"error";
}
}
TheaboveexamplelistingshowsthattheFixedDepositControllershandleExceptionmethodisannotated
with@ExceptionHandlerannotation.ThismeansthatthehandleExceptionmethodisinvokedbySpring
Web MVC to handle exceptions thrown during execution of FixedDepositController controller.
@ExceptionHandler methods typically render an error page containing error details. An
@ExceptionHandler annotations value attribute specifies the list of exceptions that the
@ExceptionHandlerannotatedmethodhandles.Ifthevalueattributeisnotspecified,theexceptiontypes
specified as method arguments are handled by the @ExceptionHandler annotated method. In the above
examplelisting,thehandleExceptionmethodhandlesexceptionsoftypejava.lang.Exception.
Like@RequestMappingmethods,@ExceptionHandlermethodscanhaveflexiblemethodsignatures.The
return types supported for @ExceptionHandler methods include ModelAndView, View, String, void,
Model, and so on. The argument types supported for @ExceptionHandler methods include
HttpServletRequest,HttpServletResponse,HttpSession,andsoon.Referto@ExceptionHandlerJavadoc
forthecompletelistofsupportedargumentsandreturntypes.
The view information returned by an @ExceptionHandler annotated method is used by the
DispatcherServlettorenderanappropriateerrorpage.Forinstance,inexamplelisting10-37,theerror
stringvaluereturnedbythehandleExceptionmethodisusedbytheDispatcherServlettorender/WEB-
INF/jsp/error.jsppage.Ifthe@ExceptionHandlermethoddoesntreturnanyviewinformation(thatis,the
return type is void or Model), Springs RequestToViewNameTranslator class (refer section 11-2 of
chapter11fordetails)isusedtodeterminetheviewtoberendered.
You can define multiple @ExceptionHandler annotated methods in your controller class for handling
differentexceptiontypes.Thevalueattributeof@ExceptionHandlerannotationallowsyoutospecifythe
exception types that are handled by the method. The following example listing shows that the
myExceptionHandler method handles exceptions of type IOException and FileNotFoundException, and
myOtherExceptionHandlermethodhandlesexceptionsoftypeTimeoutException:
Examplelisting10-38–Specifyingthetypeofexceptionshandledbyan@ExceptionHandlermethod
@Controller
.....
publicclassMyController{
.....
@ExceptionHandler(value={IOException.class,FileNotFoundException.class})
publicStringmyExceptionHandler(){
return"someError";
}
@ExceptionHandler(value=TimeoutException.class)
publicStringmyOtherExceptionHandler(){
return"otherError";
}
}
IfMyControllerthrowsanexceptionoftypeIOExceptionorFileNotFoundException(oranexceptionthat
isasubtypeofIOExceptionorFileNotFoundException),themyExceptionHandlermethodisinvokedto
handletheexception.IfMyControllerthrowsanexceptionoftypeTimeoutException(oranexceptionthat
is a subtype of TimeoutException), the myOtherExceptionHandler method is invoked to handle the
exception.
LetsnowlookathowSpringsContextLoaderListenerisusedtoloadrootwebapplicationcontextXML
file(s).
10-11LoadingrootwebapplicationcontextXMLfile(s)
Asmentionedatthebeginningofthischapter,therootwebapplicationcontextfiledefinesbeansthatare
shared by all the servlets and filters of the web application. The following example listing shows the
configurationofContextLoaderListener:
Examplelisting10-39–ContextLoaderListenerconfiguration
Project–ch10-bankapp
Sourcelocation-src/main/webapp/WEB-INF/web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/META-INF/spring/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
In the above example listing, <listener> element configures the ContextLoaderListener (a
ServletContextListener) that is responsible for loading the root web application context XML file(s)
specified by the contextConfigLocation servlet context initialization parameter. The <context-param>
element is used to specify a servlet context initialization parameter. ContextLoaderListener creates an
instanceoftherootWebApplicationContextwithwhichthebeansloadedfromtherootwebapplication
contextXMLfile(s)areregistered.
In the above example listing, contextConfigLocation parameter specifies /META-
INF/spring/applicationContext.xml file as the root web application context XML file. You can specify
multipleapplicationcontextXMLfilesseparatedbycommaornewlineorwhitespaceorsemicolon.If
you dont specify the contextConfigLocation parameter, the ContextLoaderListener treats /WEB-
INF/applicationContext.xmlfileastherootwebapplicationcontextXMLfile.
10-12Summary
Inthischapter,welookedatsomeoftheimportantobjectsofasimpleSpringWebMVCapplication.We
also looked at how to use @Controller, @RequestMapping, @RequestParam and @ExceptionHandler
annotations to create annotated controllers. In the next chapter, we’ll look at how Spring transparently
bindsrequestparameterstoformbackingobjectsandperformsvalidation.
Chapter11–ValidationanddatabindinginSpringWebMVC
11-1Introduction
In the previous chapter, we looked at the MyBank web application that was developed using
@Controller, @RequestMapping and @RequestParam annotations. We saw that the form data was
retrievedfromtherequest(referexamplelisting10-23,10-28and10-29)andexplicitlysetontheform
backing object (which was FixedDepositDetails object). Also, the validation logic was written in the
controllermethoditself(referexamplelisting10-34).
Inthischapter,we’lldiscuss:
·@ModelAttributeand@SessionAttributesannotationsthatareusefulwhendealingwithmodel
attributes
·howSpringsWebDataBindersimplifiesbindingformdatatoformbackingobjects
·        validating form backing objects using Spring Validation API and JSR 303’s constraint
annotations
·SpringsformtaglibrarythatsimplifieswritingJSPpages
Letsfirstlookatthe@ModelAttributeannotationthatisusedforaddingandretrievingmodelattributes
toandfromSpringsModelobject.
11-2 Adding and retrieving model attributes using
@ModelAttributeannotation
Inthepreviouschapter,wesawthata@RequestMappingmethodstoresmodelattributesinaHashMap
(or ModelMap) instance and returns these model attributes via ModelAndView object. The model
attributesreturnedbya@RequestMappingmethodarestoredinSpringsModelobject.
Amodelattributemayrepresentaformbackingobjectorareferencedata.FixedDepositDetailsobjectin
theMyBankwebapplicationisanexampleofaformbackingobject;whentheformforopeninganew
fixed deposit is submitted, the information contained in the form is stored in the FixedDepositDetails
object. Typically, domain objects or entities in an application are used as form backing objects.
Referencedatareferstotheadditionalinformation(otherthantheformbackingobject)requiredbythe
view.Forinstance,ifyouaddausercategory(likemilitarypersonnel,seniorcitizen,andsoon)toeach
fixeddeposit,theformforopeningnewfixeddepositswouldneedtoshowacomboboxdisplayingthe
listofcategories.Thelistofcategorieswouldbethereferencedataneededfordisplayingtheformfor
openingnewfixeddeposits.
@ModelAttribute annotation is used on methods and method arguments to store and retrieve model
attributesfromSpringsModelobject,respectively.@ModelAttributeannotationonamethodindicates
thatthemethodaddsoneormoremodelattributestotheModelobject.And,@ModelAttributeannotation
on a method argument is used to retrieve a model attribute from the Model object and assign it to the
methodargument.
IMPORTchapter 11/ch11-bankapp (This project shows the MyBank web application that uses
@ModelAttribute annotation and Spring’s form tag library. The MyBank web application functionality
offered by ch11-bankapp and ch10-bankapp projects is the same. If you deploy the project on Tomcat
serverandaccesstheURLhttp://localhost:8080/ch11-bankapp,youllseethelistoffixeddepositsinthe
system.)
Letsfirstlookat@ModelAttributeannotatedmethods.
Addingmodelattributesusingmethod-level@ModelAttributeannotation
ThefollowingexamplelistingshowsFixedDepositControllersgetNewFixedDepositDetailsmethodthat
isannotatedwith@ModelAttributeannotation:
Examplelisting11-1–@ModelAttributeannotationusageatmethodlevel
Project–ch11-bankapp
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
importorg.springframework.web.bind.annotation.ModelAttribute;
importsample.spring.chapter11.domain.FixedDepositDetails;
.....
@Controller
@RequestMapping(value="/fixedDeposit")
.....
publicclassFixedDepositController{
privatestaticLoggerlogger=Logger.getLogger(FixedDepositController.class);
.....
@ModelAttribute(value="newFixedDepositDetails")
publicFixedDepositDetailsgetNewFixedDepositDetails(){
FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();
fixedDepositDetails.setEmail("Youmustenteravalidemail");
logger.info("getNewFixedDepositDetails()method:Returninganewinstanceof
FixedDepositDetails");
returnfixedDepositDetails;
}
.....
}
The getNewFixedDepositDetails method creates and returns a new instance of FixedDepositDetails
object. As the getNewFixedDepositDetails method is annotated with @ModelAttribute annotation, the
returnedFixedDepositDetailsinstanceisaddedtotheModelobject.@ModelAttribute’svalueattribute
specifiesthatthereturnedFixedDepositDetailsobjectisstoredwithnamenewFixedDepositDetailsinthe
Model object. Notice that the getNewFixedDepositDetails method logs the following message -
‘getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetails’.
NOTEYoushouldnotethatthescopeofmodelattributesisrequest.Thismeansthatthemodelattributes
arelostwhenarequestcompletes,orifarequestisredirected.
Later in this section, we’ll see how the createFixedDepositForm.jsp JSP page (refer
src/main/webapp/WEB-INF/jsp/createFixedDepositForm.jspfile)ofch11-bankappprojectusesSprings
form tag library to access the FixedDepositDetails object named newFixedDepositDetails from the
Modelobject.
Ifyoudon’tspecify@ModelAttribute’svalueattribute,thereturnedobjectisstoredintheModelobject
usingthesimplenameofthereturnedobjectstype.Inthefollowingexamplelisting,theSampleobject
returnedbythegetSamplemethodisstoredwithnamesampleintheModelobject:
Examplelisting11-2–@ModelAttributeusage–valueattributeisnotspecified

importorg.springframework.ui.Model;
.....
publicclassSampleController{
@ModelAttribute
publicSamplegetSample(){
returnnewSample();
}
}
A@ModelAttributeannotatedmethodacceptssametypesofargumentsasa@RequestMappingmethod.
Thefollowingexamplelistingshowsa@ModelAttributeannotatedmethodthatacceptsanargumentof
typeHttpServletRequest:
Examplelisting11-3–@ModelAttributeannotatedmethodthatacceptsHttpServletRequestasargument
@ModelAttribute(value="myObject")
publicSomeObjectdoSomething(HttpServletRequestrequest){.....}
In chapter 10, we saw that the @RequestParam annotation is used to pass request parameters to a
@RequestMapping annotated method. @RequestParam annotation can also be used to pass request
parameterstoa@ModelAttributeannotatedmethod,asshowninthefollowingexamplelisting:
Examplelisting11-4–Passingrequestparameterstoa@ModelAttributeannotatedmethod
@ModelAttribute(value="myObject")
publicSomeObjectdoSomething(@RequestParam("someArg")Stringmyarg){.....}
As@RequestMappingand@ModelAttributeannotatedmethodscanacceptModelobjectsasargument,
youcandirectlyaddmodelattributestotheModelobjectina@ModelAttributeor@RequestMapping
annotated method. The following example listing shows a @ModelAttribute method that directly adds
modelattributestotheModelobject:
Examplelisting11-5–AddingmodelattributesdirectlytoModelobject
importorg.springframework.ui.Model;
.....
publicclassSampleWebController{
@ModelAttribute
publicvoiddoSomething(Modelmodel){
model.addAttribute("myobject",newMyObject());
model.addAttribute("otherobject",newOtherObject());
}
}
Intheaboveexamplelisting,theModelobjectispassedasanargumenttothedoSomethingmethodthat
directly adds model attributes to the Model object. As the doSomething method adds model attributes
directly to the Model object, the doSomething method’s return type is specified as void, and the
@ModelAttribute’svalueattributeisnotspecified.
It is possible to have a single method annotated with both @RequestMapping and @ModelAttribute
annotations. The following example listing shows FixedDepositControllers listFixedDeposits method
thatisannotatedwithboth@RequestMappingand@ModelAttributeannotations:
Examplelisting11-6–@ModelAttributeand@RequestMappingannotationsonthesamemethod
Project–ch11-bankapp
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
.....
@Controller
@RequestMapping(value="/fixedDeposit")
.....
publicclassFixedDepositController{
privatestaticLoggerlogger=Logger.getLogger(FixedDepositController.class);
@RequestMapping(value="/list",method=RequestMethod.GET)
@ModelAttribute(value="fdList")
publicList<FixedDepositDetails>listFixedDeposits(){
logger.info("listFixedDeposits()method:Gettinglistoffixeddeposits");
returnfixedDepositService.getFixedDeposits();
}
.....
}
The listFixedDeposits method renders the list.jsp JSP page (refer src/main/webapp/WEB-
INF/jsp/fixedDeposit/list.jsp file of ch11-bankapp project) that shows the list of fixed deposits in the
system.Whenamethodisannotatedwithboth@RequestMappingand@ModelAttributeannotations,the
value returned by the method is considered as a model attribute, and not as a view name. In such a
scenario,viewnameisdeterminedbySpringsRequestToViewNameTranslatorclassthatdeterminesthe
view to render based on the request URI of the incoming request. Later in this chapter, we’ll discuss
RequestToViewNameTranslator in detail. In example listing 11-6, notice that the listFixedDeposits
methodlogsthefollowingmessage–‘listFixedDeposits()method:Gettinglistoffixeddeposits.
Itisimportanttonotethatyoucandefinemultiplemethodsannotatedwith@ModelAttributeannotationin
acontroller.Whenarequestisdispatchedtoa@RequestMappingannotatedmethodofacontroller,all
the @ModelAttribute annotated methods of that controller are invoked before the @RequestMapping
annotated method is invoked. The following example listing shows a controller that defines
@RequestMappingand@ModelAttributeannotatedmethods:
Examplelisting11-7–@RequestMappingmethodisinvokedafterallthe@ModelAttributemethodsare
invoked
@RequestMapping("/mycontroller")
publicclassMyController{
@RequestMapping("/perform")
publicStringperform(){.....}
@ModelAttribute(value="a")
publicAgetA(){.....}
@ModelAttribute(value="b")
publicBgetB(){.....}
}
Intheaboveexamplelisting,ifarequestismappedtoMyController’sperformmethod,SpringWebMVC
willfirstinvokegetAandgetBmethods,followedbyinvokingtheperformmethod.
Ifa methodis annotatedwithboth @RequestMappingand@ModelAttributeannotations, the methodis
invoked onlyonce for processing the request. The following example listing shows a controller that
definesamethodthatisannotatedwithboth@RequestMappingand@ModelAttributeannotations:
Examplelisting11-8–Methodannotatedwithboth@RequestMappingand@ModelAttributeannotations
isinvokedonlyonceforprocessingtherequest
@RequestMapping("/mycontroller")
publicclassMyController{
@RequestMapping("/perform")
@ModelAttribute
publicStringperform(){.....}
@ModelAttribute(value="a")
publicAgetA(){.....}
@ModelAttribute(value="b")
publicBgetB(){.....}
}
Intheaboveexamplelisting,ifarequestismappedtoMyController’sperformmethod,SpringWebMVC
will first invoke getA and getB methods, followed by invoking the perform method. As the perform
method is annotated with both @RequestMapping and @ModelAttribute annotations, Springs
RequestToViewNameTranslator class is used for determining the name of the view to render after the
performmethodisexecuted.
If you now deploy the ch11-bankapp project on Tomcat and go to http://localhost:8080/ch11-
bankapp/fixedDeposit/listURL,youllseeawebpageshowingthelistoffixeddeposits.Also,you’llsee
thefollowingsequenceofmessagesontheconsole:
INFOsample.spring.chapter11.web.FixedDepositControllergetNewFixedDepositDetails()method:Returninganewinstanceof
FixedDepositDetails
INFOsample.spring.chapter11.web.FixedDepositControllerlistFixedDeposits()method:Gettinglistoffixeddeposits
The above output shows that the getNewFixedDepositDetails method (which is annotated with
@ModelAttributeannotation)isinvokedfirst,followedbythelistFixedDeposits(whichisannotatedwith
both@ModelAttributeand@RequestMappingannotation).
Lets now look at how model attributes are retrieved from the Model object using @ModelAttribute
annotationonamethodargument.
Retrievingmodelattributesusing@ModelAttributeannotation
You can use @ModelAttribute annotation on arguments of a @RequestMapping annotated method to
retrievemodelattributesfromtheModelobject.
The following example listing shows FixedDepositController’s openFixedDeposit method that uses
@ModelAttributeannotationtoretrievenewFixedDepositDetailsobjectfromtheModelobject:
Examplelisting11-9–@ModelAttributeannotationonamethodargument
Project–ch11-bankapp
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
.....
@Controller
@RequestMapping(value="/fixedDeposit")
.....
publicclassFixedDepositController{
.....
@ModelAttribute(value="newFixedDepositDetails")
publicFixedDepositDetailsgetNewFixedDepositDetails(){
.....
logger.info("getNewFixedDepositDetails()method:Returninganewinstanceof
FixedDepositDetails");
.....
}
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value="newFixedDepositDetails")
FixedDepositDetailsfixedDepositDetails,.....){
.....
fixedDepositService.saveFixedDeposit(fixedDepositDetails);
logger.info("openFixedDeposit()method:Fixeddepositdetailssuccessfullysaved.
Redirectingtoshowthelistoffixeddeposits.");
.....
}
}
.....
}
Intheaboveexamplelisting,@ModelAttributeannotatedgetNewFixedDepositDetailsmethodisinvoked
before @RequestMapping annotated openFixedDeposit method. When the getNewFixedDepositDetails
methodisinvoked,thereturnedFixedDepositDetails instance is stored inthe Model object with name
newFixedDepositDetails. Now, the openFixedDeposit method’s fixedDepositDetails argument is
annotated with @ModelAttribute(value="newFixedDepositDetails"); therefore, the
newFixedDepositDetails object is obtained from the Model object and assigned to the
fixedDepositDetailsargument.
If you look at the FixedDepositControllers openFixedDeposit method, youll notice that we havenot
writtenanylogicto obtain valuesoftenure, amountand email fieldsfrom therequestandpopulatethe
newFixedDepositDetailsinstance.ThisisbecausetheSpringsWebDataBinderobject(explainedlaterin
this chapter) is responsible for transparently retrieving request parameters from the request and
populating the fields (with matching names) of newFixedDepositDetails instance. For instance, if a
requestparameternamedtenureisfoundintherequest,WebDataBindersetsthevalueoftenurefieldof
newFixedDepositDetailsinstancetothevalueoftenurerequestparameter.
Figure 11-1 summarizes the sequence of actions that are performed by Spring when a request is
dispatchedtoFixedDepositControllersopenFixedDepositmethod.
Figure 11-1 Order in which @ModelAttribute and @RequestMapping annotated methods of
FixedDepositControllerareinvoked
Intheabovefigure,theRequestMappingHandlerAdapterobjectofSpringWebMVCisresponsiblefor
invoking @ModelAttribute and @RequestMapping annotated methods of a controller. At first, the
getNewFixedDepositDetailsmethodisinvokedandthereturnedFixedDepositDetailsinstanceisstoredin
the Model object with name newFixedDepositDetails. Next, the newFixedDepositDetails instance is
retrievedfromtheModelandpassedasanargumenttotheopenFixedDepositmethod.
Letsnowlookatwhattimesduringtheprocessingofarequesta@ModelAttributeannotatedmethodis
invoked.
Requestprocessingand@ModelAttributeannotatedmethods
In example listing 11-6, we saw that the execution of listFixedDeposits method logs the following
message:
listFixedDeposits()method:Gettinglistoffixeddeposits
In example listing 11-9, we saw that the execution of getNewFixedDepositDetails method logs the
followingmessage:
getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetails
And,theopenFixedDepositmethodlogsthefollowingmessage:
openFixedDeposit() method: Fixed deposit details successfully saved. Redirecting to show the list of
fixeddeposits
To see the order in which the listFixedDeposits, getNewFixedDepositDetails and openFixedDeposit
methodsareinvoked,deploythech11-bankappprojectandfollowthesesteps:
1.    Go to http://localhost:8080/ch11-bankapp/fixedDeposit/list URL. You’ll see the list of fixed
depositsinthesystemandthe‘CreatenewFixedDeposit’button(referfigure10-8ofchapter10).
2.Clickthe‘CreatenewFixedDepositbuttonthatshowstheHTMLformforopeninganewfixed
deposit(referfigure10-9ofchapter10).
3.EnterfixeddepositdetailsandclicktheSave’button.Ifnovalidationerrors are found inthe
entered data, the fixeddepositdetailsaresuccessfullysavedand the list offixeddepositsinthe
system(whichincludesthenewlycreatedfixeddeposit)isdisplayedonceagain.
The following table describes the actions performed by you and the corresponding messages that are
printedbytheMyBankapplicationontheconsole:
Action Messagesprintedontheconsole
Gotohttp://localhost:8080/ch11-
bankapp/fixedDeposit/listURL
getNewFixedDepositDetails() method: Returning a new instance of
FixedDepositDetails
listFixedDeposits()method:Gettinglistoffixeddeposits
Clickthe‘CreatenewFixedDeposit
button
getNewFixedDepositDetails() method: Returning a new instance of
FixedDepositDetails
showOpenFixedDepositForm()method:Showingformforopeninganewfixed
deposit
Enter fixed deposit details and click
the‘Save’button
getNewFixedDepositDetails() method: Returning a new instance of
FixedDepositDetails
openFixedDeposit() method: Fixed deposit details successfully saved.
Redirectingtoshowthelistoffixeddeposits.
getNewFixedDepositDetails() method: Returning a new instance of
FixedDepositDetails
listFixedDeposits()method:Gettinglistoffixeddeposits
Theabovetableshowsthatthe@ModelAttributeannotatedgetNewFixedDepositDetailsmethodiscalled
beforeeachinvocationof@RequestMappingannotatedmethodoftheFixedDepositControllerclass.As
the getNewFixedDepositDetails method creates a new instance of FixedDepositDetails object, a new
instance of FixedDepositDetails object is created each time a request is handled by the
FixedDepositController.
Ifa@ModelAttributeannotatedmethodfiresSQLqueriesorinvokesanexternalwebservicetopopulate
the modelattribute returned bythe method,multiple invocations of@ModelAttribute annotated method
willadverselyaffecttheperformanceoftheapplication.Laterinthischapter,wellseethatyoucanuse
@SessionAttributes annotation to avoid multiple invocations of a @ModelAttribute annotated method.
@SessionAttributes annotation instructs Spring to cache the object returned by the @ModelAttribute
annotatedmethod.
Lets now look at a scenario in which the model attribute referred by the @ModelAttribute annotated
methodargumentisnotfoundintheModelobject.
Behaviorof@ModelAttributeannotatedmethodarguments
We saw earlier that the @ModelAttribute annotation can be used on a method argument to retrieve a
modelattributefromtheModelobject.Ifthemodelattributespecifiedbythe@ModelAttributeannotation
is not found in the Model, Spring automatically creates a new instance of the method argument type,
assigns itto the method argument and also puts it intothe Model object. To allow Spring to create an
instance of the method argument type, the Java class of the method argument type must provide a no-
argumentconstructor.
LetsconsiderthefollowingSomeControllercontrollerthatdefinesasingle@RequestMappingmethod,
doSomething:
Examplelisting11-10–@ModelAttributeargumentisnotavailableintheModelobject
@Controller
@RequestMapping(value="/some")
publicclassSomeController{
.....
@RequestMapping("/do")
publicvoiddoSomething(@ModelAttribute("myObj")MyObjectmyObject){
logger.info(myObject);
.....
}
}
The above example listing shows that the SomeController class doesn’t define any @ModelAttribute
annotatedmethodthataddsanobjectnamedmyObjoftypeMyObjectintheModel.Forthisreason,when
arequestfordoSomethingmethodisreceived,SpringcreatesaninstanceofMyObject,assignsittothe
myObjectargumentandalsoputsthenewlycreatedMyObjectinstanceintotheModelobject.
LetsnowlookatSpringsRequestToViewNameTranslatorobject.
RequestToViewNameTranslator
RequestToViewNameTranslatordeterminestheviewtoberenderedwhena@RequestMappingannotated
methoddoesn’texplicitlyspecifytheviewtoberendered.
We saw earlier that when a @RequestMapping method is also annotated with @ModelAttribute
annotation,thevaluereturnedby themethodisconsideredasamodelattribute.Insuch asituation,the
RequestToViewNameTranslatorobjectisresponsiblefordeterminingtheviewtoberenderedbasedon
the incoming web request. Similarly, if a @RequestMapping annotated method returns void,
org.springframework.ui.Model or java.util.Map, the RequestToViewNameTranslator object determines
theviewtoberendered.
DefaultRequestToViewNameTranslator is an implementation of RequestToViewNameTranslator that is
usedbydefaultbyDispatcherServlet todetermine theview toberendered when no view is explicitly
returnedbya@RequestMappingmethod.DefaultRequestToViewNameTranslatorusestherequestURIto
determine the name of the logical view to render. DefaultRequestToViewNameTranslator removes the
leadingandtrailingslashesandthefileextensionfromtheURItodeterminetheviewname.Forinstance,
iftheURLishttp://localhost:8080/doSomething.htm,theviewnamebecomesdoSomething.
In case of MyBank web application, the FixedDepositController’s listFixedDeposits method (refer
examplelisting11-6orFixedDepositController.javafileofch11-bankappproject)isannotatedwithboth
@RequestMapping and @ModelAttribute; therefore, RequestToViewNameTranslator is used by the
DispatcherServlettodeterminetheviewtorender.AsthelistFixedDepositsmethodismappedtorequest
URI/fixedDeposit/list,RequestToViewNameTranslatorreturns/fixedDeposit/listastheviewname.The
ViewResolver configured in the web application context XML file of MyBank web application (refer
bankapp-config.xml file of ch11-bankapp project) maps /fixedDeposit/list view name to /WEB-
INF/jsp/fixedDeposit/list.jspJSPview.
Letsnowlookat@SessionAttributesannotation.
11-3Cachingmodelattributesusing@SessionAttributesannotation
In the previous section, we saw that all the @ModelAttribute annotated methods of a controller are
alwaysinvokedbeforethe@RequestMappingannotatedmethod.Thisbehaviormaynotbeacceptablein
situations in which @ModelAttribute methods obtain data from the database or from an external web
service to populate the model attribute. In such scenarios, you can annotate your controller class with
@SessionAttributesannotationthatspecifiesthemodelattributesthatarestoredinHttpSessionbetween
requests.
If @SessionAttributes annotation is used, a @ModelAttribute annotated method is invoked only if the
model attribute specified by the @ModelAttribute annotation isnot found in the HttpSession. Also,
@ModelAttribute annotation on a method argument will result in creation of a new instance of model
attributeonlyifthemodelattributeisnotfoundintheHttpSession.
IMPORTchapter11/ch11-session-attributes(Thisprojectshowsamodifiedversionofch11-bankapp
projectthatuses@SessionAttributesannotationtotemporarilystoremodelattributesinHttpSession.The
MyBankwebapplicationfunctionalityofferedbych11-session-attributesandch10-bankappprojectsare
the same. If you deploy the project on Tomcat server and access the URL http://localhost:8080/ch11-
session-attributes,you’llseethelistoffixeddepositsinthesystem.)
Thefollowingexamplelistingshowsusageof@SessionAttributesannotationinch11-session-attributes
project to temporarily store newFixedDepositDetails and editableFixedDepositDetails model attributes
inHttpSession:
Examplelisting11-11–@SessionAttributesannotationusage
Project–ch11-session-attributes
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
importorg.springframework.web.bind.annotation.SessionAttributes;
.....
@SessionAttributes(value={"newFixedDepositDetails","editableFixedDepositDetails"})
publicclassFixedDepositController{
.....
@ModelAttribute(value="newFixedDepositDetails")
publicFixedDepositDetailsgetNewFixedDepositDetails(){
FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();
fixedDepositDetails.setEmail("Youmustenteravalidemail");
returnfixedDepositDetails;
}
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetails
fixedDepositDetails,
.....){.....}
.....
@RequestMapping(params="fdAction=view",method=RequestMethod.GET)
publicModelAndViewviewFixedDepositDetails(
@RequestParam(value="fixedDepositId")intfixedDepositId){
FixedDepositDetailsfixedDepositDetails=fixedDepositService
.getFixedDeposit(fixedDepositId);
Map<String,Object>modelMap=newHashMap<String,Object>();
modelMap.put("editableFixedDepositDetails",fixedDepositDetails);
.....
returnnewModelAndView("editFixedDepositForm",modelMap);
}
}
@SessionAttributes annotations value attribute specifiesnames of the model attributes that are
temporarily stored in HttpSession. In the above example listing, model attributes named
newFixedDepositDetails and editableFixedDepositDetails are stored in HttpSession between requests.
The newFixedDepositDetails model attribute is returned by @ModelAttribute annotated
getNewFixedDepositDetailsmethod,andtheeditableFixedDepositDetailsmodelattributeisreturnedby
the@RequestMappingannotatedviewFixedDepositDetailsmethod.
A controller contributes model attributes via @ModelAttribute annotated methods, @RequestMapping
methods (that return ModelAndView, Model or Map), and by directly adding model attributes to the
Modelobject.Themodelattributescontributedbythecontrollerthroughanyapproacharecandidatefor
storageintheHttpSessionby@SessionAttributesannotation.
When using @SessionAttributes annotation, you should ensure that the model attributes stored in the
HttpSession are removed when they are no longer required. For instance, the newFixedDepositDetails
model attribute represents an instance of FixedDepositDetails that is used by the ‘Open fixed deposit’
form to show the default value(s) of Email form field as ‘You must enter a valid email’ (refer
getNewFixedDepositDetails method in example listing 11-11). Also, when the user clicks the ‘Save’
button on the ‘Open fixed deposit’ form, the fixed deposit details entered by the user are set on the
newFixedDepositDetails instance (refer openFixedDepositmethod in example listing 11-11). After the
fixed deposit is successfully created, the newFixedDepositDetails instance is no longer required;
therefore, it must be removed from the HttpSession. Similarly, editableFixedDepositDetails model
attributeisnotrequiredafteryouhavesuccessfullymodifieddetailsofafixeddeposit.
You can instruct Spring to removeall the model attributes stored in HttpSession by calling
setComplete method of Springs SessionStatus object. The following example listing shows
FixedDepositController’sopenFixedDeposit and editFixedDeposit methods that invoke SessionStatus’s
setCompletemethodafterafixeddepositissuccessfullycreatedormodified:
Examplelisting11-12–RemovingmodelattributesfromHttpSessionusingSessionStatusobject
Project–ch11-session-attributes
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
importorg.springframework.web.bind.support.SessionStatus;
.....
@SessionAttributes(value={"newFixedDepositDetails","editableFixedDepositDetails"})
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,
.....,SessionStatussessionStatus){
fixedDepositService.saveFixedDeposit(fixedDepositDetails);
sessionStatus.setComplete();
}
}
@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)
publicStringeditFixedDeposit(
@ModelAttribute("editableFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,
.....,SessionStatussessionStatus){
fixedDepositService.editFixedDeposit(fixedDepositDetails);
sessionStatus.setComplete();
.....
}
}
.....
}
TheaboveexamplelistingshowsthatbothopenFixedDepositandeditFixedDepositmethodsaredefined
toacceptanargumentoftype SessionStatus. Whena@RequestMapping annotated method specifies an
argumentoftypeSessionStatus,SpringsuppliesaninstanceofSessionStatustothemethod.Thecallto
setComplete method instructs Spring to remove thecurrent controllers model attributes from the
HttpSessionobject.
In examplelisting 11-11and11-12, we saw thatthe @SessionAttributes’s value attribute specifies the
namesofmodelattributesthataretemporarilystoredinHttpSession.Ifyouwantthatonlycertaintypesof
modelattributesarestoredinHttpSession,youcanuse@SessionAttributes’stypesattribute.Forinstance,
the following @SessionAttributes annotation specifies that attributes named x and y, and all model
attributesthatareoftypeMyObject,aretemporarilystoredinHttpSession:
@SessionAttributes(value={"x","y"},types={MyObject.class})
You can see the order in which listFixedDeposits, getNewFixedDepositDetails and openFixedDeposit
methodsareinvokedbydeployingch11-session-attributesproject andperformtheactions described in
thefollowingtable:
Action Messagesprintedontheconsole
Gotohttp://localhost:8080/ch11-
session-attributes/fixedDeposit/list
URL
getNewFixedDepositDetails()method:Returninganewinstanceof
FixedDepositDetails
listFixedDeposits()method:Gettinglistoffixeddeposits
Clickthe‘CreatenewFixedDeposit
button
showOpenFixedDepositForm()method:Showingformforopeninganewfixed
deposit
Enterfixeddepositdetailsandclick
the‘Save’button
openFixedDeposit()method:Fixeddepositdetailssuccessfullysaved.
Redirectingtoshowthelistoffixeddeposits.
getNewFixedDepositDetails()method:Returninganewinstanceof
FixedDepositDetails
listFixedDeposits()method:Gettinglistoffixeddeposits
In ch11-bankapp project, we saw that the @ModelAttribute annotated getNewFixedDepositDetails
method of FixedDepositController was invoked each time a request was dispatched to
FixedDepositController.TheabovetableshowsthatthegetNewFixedDepositDetailsmethodisinvoked
when request is handled by the FixedDepositController for the first time. As the openFixedDeposit
method removes the model attributes stored in the HttpSession, request to listFixedDeposits method
resultsininvocationofgetNewFixedDepositDetailsmethodonceagain.
Now,thatwehaveseenhowtouse@ModelAttributeand@SessionAttributesannotations,letslookat
howdatabindingisperformedinSpringWebMVCapplications.
11-4DatabindingsupportinSpring
WhenaformissubmittedinaSpringWebMVCapplication,requestparameterscontainedintherequest
areautomaticallysetonthemodelattributethatactsastheformbackingobject.Thisprocessofsetting
requestparametersontheformbackingobjectisreferredtoasdatabinding.Inthissection,we’lllookat
SpringsWebDataBinderinstancethatbindsrequestparameterstoformbackingobjects.
IMPORTchapter 11/ch11-data-binding (This project shows a modified version of ch11-session-
attributesprojectthatshowshowtoregisterPropertyEditorimplementationswithSpringcontainer.Ifyou
deploytheprojectonTomcatserverandaccesstheURLhttp://localhost:8080/ch11-data-binding,you’ll
seethelistoffixeddepositsinthesystem.)
ThefollowingexamplelistingshowstheFixedDepositDetailsclassofch11-data-bindingproject:
Examplelisting11-13–FixedDepositDetailsclass
Project–ch11-data-binding
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.domain;
importjava.util.Date;
publicclassFixedDepositDetails{
.....
privatelongdepositAmount;
privateDatematurityDate;
.....
publicvoidsetDepositAmount(longdepositAmount){
this.depositAmount=depositAmount;
}
publicvoidsetMaturityDate(DatematurityDate){
this.maturityDate=maturityDate;
}
.....
}
The above example listing shows that the depositAmount and maturityDate fields are of type long and
java.util.Date,respectively.ThevaluesofdepositAmountandmaturityDatefieldsaresetwhenthe‘Open
fixeddepositformofch11-data-bindingprojectissubmitted.Thefollowingfigureshowsthe‘Openfixed
depositformofch11-data-bindingprojectthatisusedforopeningnewfixeddeposits:
Figure11-2‘Openfixeddepositformforopeningnewfixeddeposits
Intheabovefigure,‘Amount(inUSD)’and‘Maturitydate’formfieldscorrespondtodepositAmountand
maturityDate fields of FixedDepositDetails class (refer example listing 11-13). One of the important
thingstonoteisthatthe‘Maturitydate’fieldacceptsadateintheformat‘MM-dd-yyyy’,like01-27-2013.
AsdepositAmountfieldisoftypelong,andmaturityDateisoftypejava.util.Date,Springsdatabinding
mechanism is responsible for doing the type conversion from String to the type defined by the
FixedDepositDetailsinstance.
ThefollowingexamplelistingshowsFixedDepositControllersopenFixedDepositmethodthatisinvoked
whenauserfillsthe‘Openfixeddeposit’formandclicksthe‘Savebutton(referfigure11-2):
Examplelisting11-14–FixedDepositController-Automaticdatabindingexample
Project–ch11-data-binding
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
@Controller
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value = "newFixedDepositDetails") FixedDepositDetails
fixedDepositDetails,
BindingResultbindingResult,SessionStatussessionStatus){
....
}
.....
}
In the above example listing, the @ModelAttribute annotated FixedDepositDetails argument represents
theformbackingobjectonwhichtherequestparametersaresetwhenthe‘Openfixeddepositformis
submitted. Springs WebDataBinder instance binds request parameters to the FixedDepositDetails
instance.
LetsnowlookathowWebDataBinderperformsdatabinding.
WebDataBinder–databinderforwebrequestparameters
WebDataBinderusestherequestparameternametofindthecorrespondingJavaBean-stylesettermethod
ontheformbackingobject.IfaJavaBean-stylesettermethodisfound,WebDataBinderinvokesthesetter
methodandpassestherequestparametervalueasanargumenttothesettermethod.Ifthesettermethodis
defined to accept a non-String type argument, WebDataBinder uses an appropriate PropertyEditor to
performthetypeconversion.
The following example listing shows the MyObject class that acts as a form backing object in an
application:
Examplelisting11-15–MyObjectclass–aformbackingobject
publicclassMyObject{
privateStringx;
privateNy;
.....
publicvoidsetX(Stringx){
this.x=x;
}
publicvoidsetY(Ny){
this.y=y;
}
}
TheaboveexamplelistingshowsthattheMyObjectclassdefinespropertiesnamedxandyoftypeString
andN,respectively.
The following figure shows how WebDataBinder binds request parameters named x and y to x and y
propertiesofMyObjectinstance:
Figure11-3WebDataBinderperformsdatabindingbyusingregisteredPropertyEditorstoperformtype
conversion
TheabovefigureshowsthattheWebDataBinderusesaPropertyEditortoconvertStringvaluebtotype
N,beforecallingthesetYmethodofMyObjectinstance.
Springprovidesacoupleofbuilt-inPropertyEditorimplementationsthatareusedbyWebDataBinderfor
converting String type request parameter value to the type defined by the form backing object. For
instance,CustomNumberEditor,FileEditor,CustomDateEditor are some of the built-in PropertyEditors
provided by Spring. For a complete list of built-in PropertyEditors, refer to
org.springframework.beans.propertyeditorspackage.
CustomNumberEditorisusedforconvertingaStringvaluetoajava.lang.Numbertype,likeInteger,Long,
Double,andsoon.CustomDateEditorisusedforconvertingaStringvaluetoajava.util.Datetype.You
canpassajava.text.DateFormatinstancetoCustomDateEditortospecifythedateformattobeusedfor
parsing and rendering dates. Both these PropertyEditors are required in ch11-data-binding project
because we need to convert request parameter values to depositAmount (which is of type long) and
maturityDate (which is of type java.util.Date). CustomNumberEditor ispre-registered with the
WebDataBinderinstancebutyouneedtoexplicitlyregisterCustomDateEditor.
Lets now look at how you can configure a WebDataBinder instance and register a PropertyEditor
implementationwithit.
ConfiguringaWebDataBinderinstance
YoucanconfigureaWebDataBinderinstanceby:
·definingan@InitBinderannotatedmethodinthecontrollerclass
·configuringaWebBindingInitializerimplementationinthewebapplicationcontextXMLfile
·definingan@InitBinderannotatedmethodina@ControllerAdviceannotatedclass
Lets look at each of the above mentioned approach for configuring a WebDataBinder instance and
registeringaPropertyEditorwithit.
Definingan@InitBinderannotatedmethodinthecontrollerclass
An@InitBinderannotatedmethodinacontrollerclassspecifiesthatthemethodinitializesaninstanceof
WebDataBinderthatwillbeusedbythecontrollerduringdatabinding.Thevalueattributeof@InitBinder
annotationspecifiesthename(s)ofthemodelattributetowhichtheinitializedWebDataBinderinstance
applies.
ThefollowingexamplelistingshowsFixedDepositController’sinitBinder_Newmethodthatisannotated
with@InitBinder:
Examplelisting11-16–FixedDepositController-@InitBinderannotationusage
Project–ch11-data-binding
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
importjava.text.SimpleDateFormat;
importorg.springframework.beans.propertyeditors.CustomDateEditor;
importorg.springframework.web.bind.WebDataBinder;
importorg.springframework.web.bind.annotation.InitBinder;
@Controller
.....
publicclassFixedDepositController{
.....
@ModelAttribute(value="newFixedDepositDetails")
publicFixedDepositDetailsgetNewFixedDepositDetails(){.....}
@InitBinder(value="newFixedDepositDetails")
publicvoidinitBinder_New(WebDataBinderwebDataBinder){
webDataBinder.registerCustomEditor(Date.class,
newCustomDateEditor(newSimpleDateFormat("MM-dd-yyyy"),false));
}
.....
}
In the above example listing, the @InitBinder annotations value attribute is set to
newFixedDepositDetails,whichmeansthattheWebDataBinderinitializedbytheinitBinder_Newmethod
applies only to the newFixedDepositDetails model attribute. An @InitBinder annotated method can
acceptsamesetofarguments(likeHttpServletRequest,SessionStatus,andsoon)thatcanbepassedtoa
@RequestMappingannotatedmethod.But,an@InitBinderannotated methodcan’tbedefinedto accept
modelattributesandBindingResult(orErrors)objectsasarguments.Typically,WebDataBinderinstance,
alongwith SpringsWebRequestor java.util.Locale instance,ispassedtoan@InitBinder method. You
shouldnotethatthereturntypeofan@InitBindermethodmustbevoid.
WebDataBinders registerCustomEditor method is used for registering a PropertyEditor with the
WebDataBinderinstance.Inexamplelisting11-16,initBinder_NewmethodregistersCustomDateEditor
(aPropertyEditor)withtheWebDataBinderinstance.
You can define an @InitBinder annotated method for each model attribute of a controller, or you can
defineasingle@InitBinderannotatedmethodthatappliestoallthemodelattributesofthecontroller.If
youdontspecifythevalueattributeof@InitBinderannotation,theWebDataBinderinstanceinitializedby
themethodisapplicabletoallthemodelattributesofthecontroller.
ConfiguringaWebBindingInitializerimplementation
AWebDataBinder instance is first initialized by RequestMappingHandlerAdapter, followed by further
initializationbyWebBindingInitializerand@InitBindermethods.
The <annotation-driven> element of Springs mvc schema creates an instance of Springs
RequestMappingHandlerAdapterthatinitializestheWebDataBinder.Youcansupplyanimplementationof
Springs WebBindingInitializer interface to RequestMappingHandlerAdapter to further initialize
WebDataBinderinstances.Youcanadditionallyuse@InitBindermethodsinacontrollerclasstofurther
initializeWebDataBinderinstances.
The following figure shows the sequence in which RequestMappingHandlerAdapter,
WebBindingInitializerand@InitBindermethodsinitializeaWebDataBinderinstance:
Figure 11-4 The sequence in which a WebDataBinder instance is initialized by
RequestMappingHandlerAdapter,WebBindingInitializerand@InitBindermethodsofacontrollerclass
WebDataBinderinitializationbyan@InitBindermethod ofa controllerclass is applicable only tothat
controllersmodelattributes.Forinstance,ifyouusean@InitBindermethodincontrollerX to set the
CustomDateEditorpropertyeditorontheWebDataBinderinstance,thentheCustomDateEditor property
editor will be available only to the model attributes of controller X during data binding. In MyBank
application, the CustomDateEditor was required only by the model attributes of the
FixedDepositController; therefore, we used @InitBinder annotated methods in the
FixedDepositControllerclasstoregisterCustomDateEditorwithWebDataBinderinstance.
Springs WebBindingInitializer is a callback interface whose implementation is responsible for
initializingaWebDataBinderwiththeconfigurationthatappliestoallthecontrollers(andtherebytoall
the model attributes) in the application. Lets look at how to configure a custom WebBindingInitializer
whenusing<annotation-driven>elementofSpringsmvcschema.
The <annotation-driven> element of Springs mvc schema creates and registers
RequestMappingHandlerAdapterandRequestMappingHandlerMappingobjectswiththeSpringcontainer.
The other objects that are configured by <annotation-driven> element are LocalValidatorFactoryBean
(explained in section 11-5) and FormattingConversionServiceFactoryBean (explained in section 13-5).
The <annotation-driven> element provides couple of attributes that help you customize
RequestMappingHandlerAdapterandRequestMappingHandlerMappingobjects.Ifthecustomizationyou
want to make to RequestMappingHandlerAdapter or RequestMappingHandlerMapping object is not
providedbythe<annotation-driven>element,theonlyoptionistoremove<annotation-driven>element
and explicitly configure RequestMappingHandlerAdapter and RequestMappingHandlerMapping objects
inthewebapplicationcontextXMLfile.As<annotation-driven>elementdoesntprovideanyoptionto
supply a custom WebBindingInitializer instance to the RequestMappingHandlerAdapter object, youll
have to explicitly configure RequestMappingHandlerAdapter and RequestMappingHandlerMapping
objectsinthewebapplicationcontextXMLfile.
The following example listing shows howyoucanuse Springs ConfigurableWebBindingInitializer (an
implementationofWebBindingInitializer)tomakeCustomDateEditorpropertyeditoravailabletoallthe
controllersintheMyBankapplication:
Examplelisting11-17–WebBindingInitializerconfiguration
<beanid="handlerAdapter"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<propertyname="webBindingInitializer"ref="myInitializer"/>
</bean>
<beanid="handlerMapping"
    class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"
/>
<beanid="myInitializer"
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<propertyname="propertyEditorRegistrars">
<list>
<beanclass="mypackage.MyPropertyEditorRegistrar"/>
</list>
</property>
</bean>
The above example listing shows that RequestMappingHandlerAdapter and
RequestMappingHandlerMappingbeansareexplicitlydefinedinthewebapplicationcontextXMLfile.
The RequestMappingHandlerAdapters webBindingInitializer property refers to the
ConfigurableWebBindingInitializer bean that implements WebBindingInitializer interface.
ConfigurableWebBindingInitializer’spropertyEditorRegistrarspropertyspecifiesclassesthatregisterone
or more PropertyEditors with WebDataBinder. The following example listing shows how
MyPropertyEditorRegistrarclassregistersCustomDateEditorpropertyeditorwithWebDataBinder:
Examplelisting11-18–MyPropertyEditorRegistrarclass
importorg.springframework.beans.PropertyEditorRegistrar;
importorg.springframework.beans.PropertyEditorRegistry;
importorg.springframework.beans.propertyeditors.CustomDateEditor;
publicclassMyPropertyEditorRegistrarimplementsPropertyEditorRegistrar{
@Override
publicvoidregisterCustomEditors(PropertyEditorRegistryregistry){
registry.registerCustomEditor(Date.class,newCustomDateEditor(
newSimpleDateFormat("MM-dd-yyyy"),false));
}
}
The above example listing shows that the MyPropertyEditorRegistrar class implements Springs
PropertyEditorRegistrar interface, and provides implementation for registerCustomEditors method
defined in the PropertyEditorRegistrar interface. The PropertyEditorRegistry instance passed to the
registerCustomEditors method is used for registering property editors. PropertyEditorRegistrys
registerCustomEditor method is used for registering a PropertyEditor implementation with the
WebDataBinder.Intheaboveexamplelisting,PropertyEditorRegistrysregisterCustomEditorisusedfor
registeringtheCustomDateEditorpropertyeditorwiththeWebDataBinder.
As we saw, using WebBindingInitializer for initializing WebDataBinder is quite an involved task. A
simpler alternative to using WebBindingInitializer is to define @InitBinder annotated methods in a
@ControllerAdviceannotatedclass.
Definingan@InitBindermethodina@ControllerAdviceannotatedclass
Like @Service, @Controller and @Repository annotations, @ControllerAdvice annotation is a
specializedformof@Componentannotation.The@ControllerAdviceannotationonaclassindicatesthat
the class provides support to controllers. You can define @InitBinder, @ModelAttribute and
@ExceptionHandler annotated methods in the @ControllerAdvice annotated class, and these annotated
methods apply to all the annotated controllers in the application. As with @Service, @Controller and
@Repositoryannotations,<classpath-scanning>elementofSpringscontextschemaautomaticallydetects
andregisters@ControllerAdviceannotatedclasseswiththeSpringcontainer.
Ifyounoticethatyouareduplicating@InitBinder,@ModelAttributeand@ExceptionHandlermethodsin
multiple controllers, then considerdefiningsuch methodsina@ControllerAdvice annotated class. For
instance, if you want to initialize the WebDataBinder with the configuration that applies tomultiple
controllersintheapplication,thendefinean@InitBindermethodina@ControllerAdviceannotatedclass
insteadofdefiningan@InitBindermethodinmultiplecontrollerclasses.
ThefollowingtablesummarizesthethreeapproachesthatwediscussedforinitializingWebDataBinder:
@InitBindermethodincontroller
class WebBindingInitializer @InitBinder method in
@ControllerAdviceclass
Requires defining an @InitBinder
methodinacontroller
Requires explicitly configuring
RequestM appingHandlerAdapterintheweb
applicationcontextXM Lfile
Requires defining an @InitBinder
method in a @ControllerAdvice
annotatedclass
WebDataBinderinitializationapplies
only to the controller that contains
the@InitBindermethod
WebDataBinder initialization applies to all
theannotatedcontrollersintheapplication
WebDataBinder initialization applies
toalltheannotatedcontrollersinthe
application
Letsnowlookathowyoucanallowordisallowfieldsofamodelattributefromparticipatinginthedata
bindingprocess.
Allowingordisallowingfieldsfromdatabindingprocess
WebDataBinder allows you to specify fields of a model attribute that are allowed or disallowed from
participatinginthedatabindingprocess.Itisstronglyrecommendedthatyouspecifythefieldsofamodel
attribute that are allowed or disallowed from the data binding processes, as failing to do so may
compromisethesecurityofyourapplication.Let’slookatascenarioinwhichwewouldliketoallowor
disallowfieldsfromdatabinding.
InMyBankapplication,whenauserselectsafixeddepositforediting,thedetailsoftheselectedfixed
depositareloadedfromthedatastoreandtemporarilycachedintheHttpSession.Theusermakeschanges
tothefixeddepositandsavesthechanges.Thefollowingexamplelistingshowsthe@RequestMapping
methodsthatareresponsibleforloadingtheselectedfixeddepositandsavingtheupdatedfixeddeposit
information:
Examplelisting11-19–FixedDepositController
Project–ch11-data-binding
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
.....
@SessionAttributes(value={"newFixedDepositDetails","editableFixedDepositDetails"})
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=view",method=RequestMethod.GET)
publicModelAndViewviewFixedDepositDetails(
@RequestParam(value="fixedDepositId")intfixedDepositId){
FixedDepositDetailsfixedDepositDetails=fixedDepositService
.getFixedDeposit(fixedDepositId);
Map<String,Object>modelMap=newHashMap<String,Object>();
modelMap.put("editableFixedDepositDetails",fixedDepositDetails);
.....
returnnewModelAndView("editFixedDepositForm",modelMap);
}
.....
@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)
publicStringeditFixedDeposit(
@ModelAttribute("editableFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,){
.....
}
}
In MyBank application, a fixed deposit is uniquely identified by the id field of FixedDepositDetails
object (refer FixedDepositDetails class of ch11-data-binding project). When a user selects a fixed
deposit for editing, the id field value is passed to the viewFixedDepositDetails method via the
fixedDepositIdrequestparameter.TheviewFixedDepositDetailsmethodusesthevalueoffixedDepositId
requestparametertoloadfixeddepositdetailsandshowthemontheEditfixeddeposit’form,asshown
inthefollowingfigure:
Figure11-5‘Editfixeddeposit’formforeditinganexistingfixeddeposit
Astheidvalue(thatcorrespondstoidattributeofFixedDepositDetailsobject)uniquelyidentifiesafixed
depositinthesystem,the‘Editfixeddeposit’formdoesntprovideanymechanismtochangeit.Whenthe
user clicks the ‘Save’ button, the FixedDepositControllers editFixedDeposit method is invoked. The
editFixedDepositmethodsavesthechangestothefixeddepositdetail.
WhenFixedDepositController’seditFixedDepositmethodisinvoked,theWebDataBinderinstancebinds
request parameter values to the fields of editableFixedDepositDetails model attribute – the
FixedDepositDetailsobjectthatwasloadedbyviewFixedDepositDetailsmethodandtemporarilystored
inHttpSession(refer@SessionAttributesannotationinexamplelisting11-19).Ifamalicioususersendsa
requestparameternamedidwithvalue10,thentheWebDataBinderwillblindlygoaheadandsettheid
attributeofFixedDepositDetailsobjectto10duringdatabinding.Thisisnotdesirablebecausechanging
idattributeofaFixedDepositDetailsobjectwillcompromiseapplicationdata.
WebDataBinderprovidessetAllowedFieldsandsetDisallowedFieldsmethodsthatyoucanusetosetthe
namesofmodelattributefieldsthatcanandcannotparticipateinthedatabindingprocess.Thefollowing
examplelistingshowstheFixedDepositControllersinitBinder_Editmethodthatspecifiesthattheidfield
ofeditableFixedDepositDetailsmodelattributemustnotparticipateinthedatabindingprocess:
Examplelisting11-20–FixedDepositController–WebDataBinderssetDisallowedFieldsmethod
Project–ch11-data-binding
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)
publicStringeditFixedDeposit(
@ModelAttribute("editableFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,.....)
{
.....
}
.....
@InitBinder(value="editableFixedDepositDetails")
publicvoidinitBinder_Edit(WebDataBinderwebDataBinder){
webDataBinder.registerCustomEditor(Date.class,newCustomDateEditor(
newSimpleDateFormat("MM-dd-yyyy"),false));
webDataBinder.setDisallowedFields("id");
}
}
In the above example listing, the initBinder_Edit method initializes WebDataBinder instance for the
editableFixedDepositDetails model attribute. As the setDisallowedFields method specifies that the id
fieldofeditableFixedDepositDetailsmodelattributeisdisallowedtoparticipateinthebindingprocess,
theidfieldisnotsetevenifarequestparameternamedidiscontainedintherequest.
LetsnowlookatSpringsBindingResultobjectthatexposeserrorsthatoccurduring databindingand
validation.
InspectingdatabindingandvalidationerrorsusingBindingResultobject
SpringsBindingResultobjectprovidesacontrollermethodwiththeresultsofbindingrequestparameters
tothemodelattribute’sfields.Forinstance,ifanytypeconversionerroroccursduringdatabinding,they
arereportedbytheBindingResultobject.
ThefollowingexamplelistingshowsFixedDepositControllersopenFixedDepositmethodthatcreatesa
fixeddepositonlyifnoerrorsarereportedbytheBindingResultobject:
Example listing 11-21 – FixedDepositController – checking for binding and validation errors using
BindingResult
Project–ch11-data-binding
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
importorg.springframework.validation.BindingResult;
importorg.springframework.web.bind.annotation.ModelAttribute;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetails
fixedDepositDetails,
BindingResultbindingResult,SessionStatussessionStatus){
.....
if(bindingResult.hasErrors()){
return"createFixedDepositForm";
}else{
fixedDepositService.saveFixedDeposit(fixedDepositDetails);
sessionStatus.setComplete();
return"redirect:/fixedDeposit/list";
}
}
.....
}
In the above example listing, the BindingResult’s hasErrors method returns true if the BindingResult
object holds one or more data binding or validation errors. In section 11-5, well see how validation
errors are stored in the BindingResult object. If errors are reported by the BindingResult object, the
openFixedDepositmethodrendersthe‘Createfixeddeposit’formwithappropriateerrormessages.Ifno
errorsarereported,thefixeddepositdetailsaresavedinthedatastore.
YoushouldnotethattheBindingResultargumentmust immediatelyfollowthemodelattributeargument
whoseBindingResultobjectyouwanttoaccessinthecontrollermethod.Forinstance,inexamplelisting
11-21,theBindingResultargumentimmediatelyfollowsthenewFixedDepositDetailsmodelattribute.The
followingexamplelistingshowsanincorrectorderingofthemodelattributeandtheBindingResultobject
fortheopenFixedDepositmethod:
Examplelisting11-22–IncorrectorderingofthemodelattributeandtheBindingResultobject
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value = "newFixedDepositDetails") FixedDepositDetails
fixedDepositDetails,
SessionStatussessionStatus,BindingResultbindingResult){
.....
}
.....
}
In the above example listing, the ordering of the newFixedDepositDetails model attribute and the
BindingResultobjectisincorrectbecausetheSessionStatusargumentisdefinedbetweenthem.
Ifacontrollermethodacceptsmultiplemodelattributes,theBindingResultobjectcorrespondingtoeach
modelattributeisspecifiedimmediatelyaftereachmodelattributeargument,asshowninthefollowing
examplelisting:
Examplelisting11-23–MultiplemodelattributesandtheirBindingResultobjects
@RequestMapping
publicStringdoSomething(
@ModelAttribute(value="a")AObjectaObj,BindingResultbindingResultA,
@ModelAttribute(value="b")BObjectbObj,BindingResultbindingResultB,){
.....
}
Theaboveexamplelistingshowsthatbothmodelattributesaandbare immediatelyfollowed bytheir
correspondingBindingResultobjects.
Now,thatwehaveseenthedatabindingprocess,let’slookathowvalidationisperformedinSpringWeb
MVCapplications.
11-5ValidationsupportinSpring
Intheprevioussection,wesawthattheWebDataBinderbindsrequestparameterstomodelattributes.The
nextstepinrequestprocessingistovalidatemodelattributes.InSpringWebMVCapplications,youcan
validate model attributes using Spring Validation API (discussed in section 6-9 of chapter 6) or by
specifyingJSR303(BeanValidationAPI)constraints(discussedinsection6-10ofchapter6)onfields
ofmodelattributes.
NOTE In this chapter, Spring Validation API and JSR 303 (Bean Validation API) have been used to
validateformbackingobjects(whicharemodelattributes)intheweblayeroftheapplication.Youshould
notethatbothJSR303(BeanValidationAPI)andSpringValidationAPIcanbeusedtovalidateobjects
inanyapplicationlayer.
LetsfirstlookathowtovalidatemodelattributesusingSpringValidationAPIsValidatorinterface.
ValidatingmodelattributesusingSpring’sValidatorinterface
ThefollowingexamplelistingshowstheFixedDepositDetailsValidatorclassofMyBankapplicationthat
validatesFixedDepositDetailsobject:
Examplelisting11-24–FixedDepositDetailsValidator–SpringsValidatorinterfaceusage
Project–ch11-data-binding
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
importorg.springframework.validation.*;
importsample.spring.chapter11.domain.FixedDepositDetails;
publicclassFixedDepositDetailsValidatorimplementsValidator{
publicbooleansupports(Class<?>clazz){
returnFixedDepositDetails.class.isAssignableFrom(clazz);
}
publicvoidvalidate(Objecttarget,Errorserrors){
FixedDepositDetailsfixedDepositDetails=(FixedDepositDetails)target;
longdepositAmount=fixedDepositDetails.getDepositAmount();
.....
if(depositAmount<1000){
errors.rejectValue("depositAmount","error.depositAmount.less",
"mustbegreaterthanorequalto1000");
}
if(email==null||"".equalsIgnoreCase(email)){
ValidationUtils.rejectIfEmptyOrWhitespace(errors,"email","error.email.blank",
"mustnotbeblank");
}
.....
}
}
SpringsValidator interface defines supports and validate methods. The supports method checks if the
supplied object instance (represented by the clazz attribute) can be validated. If the supports method
returns true, the validate method is used to validate the object. In the above example listing, the
FixedDepositDetailsValidators supports method checks if the supplied object instance is of type
FixedDepositDetails. If the supports method returns true, the FixedDepositDetailsValidators validate
method validates the object. The validate method accepts the object instance to be validated, and an
Errorsinstance.Errorsinstance storesandexposeserrorsthatoccurduring validation.Errors instance
provides multiple reject and rejectValue methods to register errors with the Errors instance. The
rejectValuemethodsareusedtoreportfield-levelerrors,andrejectmethodsareusedtoreporterrorsthat
apply to the object being validated. Springs ValidationUtils class is a utility class that provides
conveniencemethodstoinvokeaValidator,andforrejectingemptyfields.
The following figure describes the parameters that were passed to the rejectValue method in example
listing11-24toreportavalidationerrorcorrespondingtoFixedDepositDetails’sdepositAmountfield:
Figure11-6DescriptionofparametersthatarepassedtorejectValuemethodofErrorsinstancetoreport
validationerrorcorrespondingtodepositAmountfieldofFixedDepositDetails
Theabovefigureshowsthatfieldname,errorcode(whichisbasicallyamessagekey)andadefaulterror
messageispassedtotherejectValuemethod.Inchapter13,we’llseehowthemessagekeysareusedby
JSPpagestoshowmessagesfromresourcebundles.
Youcanvalidatemodelattributesby:
§explicitlyinvokingvalidatemethodonValidatorimplementation
§settingValidatorimplementationonWebDataBinder,andannotatingthemodelattributeargumentin
the@RequestMappingmethodwithJSR303’s@Validannotation
Letslookateachoftheabovementionedapproachesindetail.
Validatingmodelattributesbyexplicitlycallingvalidatemethod
The following example listing shows the FixedDepositControllersopenFixedDeposit method that uses
FixedDepositDetailsValidator (refer example listing 11-24) to validate FixedDepositDetails model
attribute:
Example listing 11-25 – FixedDepositController– validation by explicitly invoking
FixedDepositDetailsValidatorsvalidatemethod
Project–ch11-data-binding
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value = "newFixedDepositDetails") FixedDepositDetails
fixedDepositDetails,
BindingResultbindingResult,SessionStatussessionStatus){
newFixedDepositDetailsValidator().validate(fixedDepositDetails,bindingResult);
if(bindingResult.hasErrors()){
logger.info("openFixedDeposit()method:Validationerrors
-re-displayingformforopeninganewfixeddeposit");
return"createFixedDepositForm";
}
.....
}
}
The above example listing shows that the openFixedDeposit method creates an instance of
FixedDepositDetailsValidator and invokes its validate method. As BindingResult is a sub-interface of
Errors, you can pass a BindingResult object where Errors object is expected. The openFixedDeposit
method passes the fixedDepositDetails model attribute and the BindingResult object to the validate
method.AsBindingResultalreadycontainsdatabindingerrors,passingBindingResultobjecttovalidate
methodaddsvalidationerrorsalsototheBindingResultobject.
InvokingmodelattributesvalidationusingJSR303s@Validannotation
You can instruct Spring to automatically validate a model attribute argument passed to a
@RequestMappingmethodbyaddingJSR303’s@Validannotationtothemodelattributeargument,and
settingthevalidatorforthemodelattributeontheWebDataBinderinstance.
ThefollowingexamplelistingshowshowFixedDepositControllersopenFixedDepositmethod canuse
@ValidannotationtovalidateFixedDepositDetailsmodelattribute:
Examplelisting11-26–FixedDepositController–invokingvalidationusing@Validannotation
importjavax.validation.Valid;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@Valid@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetails
fixedDepositDetails,BindingResultbindingResult,SessionStatussessionStatus){
if(bindingResult.hasErrors()){
logger.info("openFixedDeposit()method:
Validationerrors-re-displayingformforopeninganewfixeddeposit");
return"createFixedDepositForm";
}
.....
}
.....
@InitBinder(value="newFixedDepositDetails")
publicvoidinitBinder_New(WebDataBinderwebDataBinder){
webDataBinder.registerCustomEditor(Date.class,newCustomDateEditor(
newSimpleDateFormat("MM-dd-yyyy"),false));
webDataBinder.setValidator(newFixedDepositDetailsValidator());
}
.....
}
Intheaboveexamplelisting,theinitBinder_NewmethodcallsWebDataBinderssetValidatormethodto
setFixedDepositDetailsValidatorasthevalidatorfornewFixedDepositDetailsmodelattribute,andinthe
openFixedDeposit method the newFixedDepositDetails model attribute is annotated with JSR 303’s
@Validannotation.WhentheopenFixedDepositmethodisinvoked,bothdatabindingandvalidationare
performedonthenewFixedDepositDetailsmodelattribute,andtheresultsofdatabindingandvalidation
aremadeavailableviatheBindingResultargument.
Itisimportanttonotethatif@InitBinderannotationspecifiesnameofthemodelattribute,thevalidator
setontheWebDataBinderappliesonlytothatparticularmodelattribute.Forinstance,inexamplelisting
11-26,theFixedDepositDetailsValidatorappliesonlytothenewFixedDepositDetailsmodelattribute.Ifa
validator applies to multiple controllers in the application, consider defining an @InitBinder method
inside a @ControllerAdvice annotated class (or use WebBindingInitializer) to set a validator on the
WebDataBinder.
Lets now lookat how constraintsare specified onproperties ofJavaBeans componentusing JSR303
annotations.
SpecifyingconstraintsusingJSR303annotations
JSR303(BeanValidationAPI)definesannotationsthatyoucanusetospecifyconstraintsonpropertiesof
JavaBeanscomponents.
IMPORTchapter 11/ch11-jsr303-validation (This project shows a modified version of ch11-data-
bindingprojectthatusesJSR303annotationstospecifyconstraintsonFixedDepositDetailsobject.Ifyou
deploy the project on Tomcat server and access the URL http://localhost:8080/ch11-jsr303-validation,
you’llseethelistoffixeddepositsinthesystem.)
The following example listing shows the FixedDepositDetails class that uses JSR 303 annotations to
specifyconstraintsonitsfields:
Examplelisting11-27–FixedDepositDetails–specifyingJSR303constraints
Project–ch11-jsr303-validation
Sourcelocation-src/main/java/sample/spring/chapter11/domain
packagesample.spring.chapter11.domain;
importjavax.validation.constraints.*;
publicclassFixedDepositDetails{
privatelongid;
@Min(1000)
@Max(500000)
privatelongdepositAmount;
@Email
@Size(min=10,max=25)
privateStringemail;
@NotNull
privateDatematurityDate;
.....
}
@Min,@Max,@Email,@Size, and @NotNull are some of the annotations defined by JSR 303. The
above example listing shows that by using JSR 303 annotations FixedDepositDetails class clearly
specifies the constraintsthat apply on its fields. On the other hand, if you are using Springs Validator
implementation to validate an object, constraints are contained in the Validator implementation (refer
examplelisting11-24).
The following table describes the constraints enforced by JSR 303 annotations on the
FixedDepositDetailsobjectshowninexamplelisting11-27:
JSR303annotation Constraintdescription
@NotNull Theannotatedfieldmustnotbenull.Forinstance,maturityDatefieldmustnotbenull.
@Min
Theannotatedfield’svaluemustbegreaterthanorequaltothespecifiedminimumvalue.
For instance, @M in(1000) annotation on depositAmount field of FixedDepositDetails object
meansthatdepositAmountsvaluemustbegreaterthanorequalto1000.
@Max
Theannotatedfield’svaluemustbelessthanorequaltothespecifiedvalue.
Forinstance,@Max(500000) annotationon depositAmount fieldof FixedDepositDetails object
meansthatthedepositAmountsvaluemustbelessthanorequalto500000.
@Size
Theannotatedfield’ssizemustbebetweenthespecifiedminandmaxattributes.
For instance, @Size(min=5, max=100) annotation on email field of FixedDepositDetails object
meansthatthesizeoftheemailfieldmustbegreaterthanorequalto5andlessthanorequalto
100.
@Email
Theannotatedfield’svaluemustawell-formedemailaddress.
Forinstance,@EmailannotationontheemailfieldofFixedDepositDetailsobjectmeansthatthe
emailfield’svaluemustbeawell-formedemailaddress.
TouseJSR303annotations,ch11-jsr303-validationprojectspecifiesdependencyonJSR303APIJAR
file(validation-api-1.0.0.GA)andHibernateValidatorframework(hibernate-validation-4.3.0.Final).The
Hibernate Validator framework provides the reference implementation for JSR 303. The Hibernate
Validator framework provides additional constraint annotations that you can use along with JSR 303
annotations. For instance, you can use Hibernate Validators @NotBlank annotation to specify that a
field’svaluemustnotbenullorempty.
It is important tonote thatJSR303 also allows you to createcustom constraints and use them in your
application. For instance, you can create a @MyConstraint custom constraint and a corresponding
validatortoenforcethatconstraintonobjects.
Now, that we have specified JSR 303 constraints on FixedDepositDetails class, lets look at how to
validateFixedDepositDetailsobject.
ValidatingobjectsthatuseJSR303annotations
IfaJSR303provider(likeHibernateValidator)isfoundintheapplicationsclasspath,andyouhave
specified<annotation-driven>elementofSpringsmvcschemainthewebapplicationcontextXMLfile,
then Spring automatically enables support for JSR 303. Behind the scenes, the <annotation-driven>
element configures an instance of Springs LocalValidatorFactoryBean class that is responsible for
detectingthepresenceofaJSR303provider(likeHibernateValidator)intheapplicationsclasspathand
initializingit.
LocalValidatorFactoryBean implements JSR 303’s Validator and ValidatorFactory interfaces, and also
SpringsValidator interface. For this reason, you can choose to validate an object by calling validate
methodofSpringsValidatorinterfaceorbycallingvalidatemethodofJSR303’sValidator.Asdiscussed
earlier, you can also instruct Spring to automatically validate a model attribute argument passed to a
@RequestMappingmethodbysimplyadding@Validannotationonthemodelattributeargument.
Validatingmodelattributesbyexplicitlycallingvalidatemethod
The following example listing shows the FixedDepositController class that uses Springs Validator to
validatetheFixedDepositDetailsobject(referexamplelisting11-27)thatusesJSR303’sconstraints:
Example listing 11-28 – FixedDepositController– validating FixedDepositDetails using Spring
ValidationAPI
Project–ch11-jsr303-validation
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
importjavax.validation.Valid;
.....
publicclassFixedDepositController{
.....
@Autowired
privateValidatorvalidator;
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,
BindingResultbindingResult,SessionStatussessionStatus){
validator.validate(fixedDepositDetails,bindingResult);

if(bindingResult.hasErrors()){.....}.....
}
.....
}
In the above example listing, the LocalValidatorFactoryBean (that implements Springs Validator
interface) is autowired into FixedDepositControllers validator instance variable. In the
openFixedDeposit method, call to Validators validate method results in invocation of
LocalValidatorFactoryBeans validate(Object, Errors) method to validate the FixedDepositDetails
instance. The BindingResult object is passed to the validate method to hold the validation errors. An
importantpointtonoticeintheaboveexamplelistingisthattheFixedDepositControllerdoesn’tdirectly
dealwithJSR303-specificAPItovalidateFixedDepositDetailsobject.Instead,SpringValidationAPIis
usedtovalidateFixedDepositDetailsobject.
ThefollowingexamplelistingshowsanalternateversionofFixedDepositControllerthatusesJSR303-
specificAPItovalidateFixedDepositDetailsobject:
Example listing 11-29 – FixedDepositController– validating FixedDepositDetails using JSR 303-
specificAPI
importjavax.validation.ConstraintViolation;
importjavax.validation.Validator;
importjava.util.Set;
.....
publicclassFixedDepositController{
.....
@Autowired
privateValidatorvalidator;
.....
@RequestMapping(params="fdAction=create",method=RequestMethod.POST)
publicStringopenFixedDeposit(
@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,
BindingResultbindingResult,SessionStatussessionStatus){
Set<ConstraintViolation<FixedDepositDetails>>violations=
validator.validate(fixedDepositDetails);
Iterator<ConstraintViolation<FixedDepositDetails>>itr=violations.iterator();

if(itr.hasNext()){.....}.....
}
.....
}
In the above example listing, the LocalValidatorFactoryBean (that implements JSR 303’s Validator
interface) is autowired into FixedDepositControllers validator instance variable. In the
openFixedDeposit method, call to Validators validate method results in invocation of
LocalValidatorFactoryBeans validate(T) method to validate the FixedDepositDetails instance. The
validatemethodreturnsajava.util.SetobjectthatcontainstheconstraintviolationsreportedbytheJSR
303 provider. You can check the java.util.Set object returned by the validate method to find if any
constraintviolationswerereported.
InvokingmodelattributesvalidationusingJSR303s@Validannotation
You can instruct Spring to automatically validate a model attribute argument passed to a
@RequestMappingmethodbyaddingJSR303’s@Validannotationtothemodelattributeargument.The
following example listing shows FixedDepositControllers editFixedDeposit method that uses @Valid
annotationtovalidateeditableFixedDepositDetailsmodelattribute:
Examplelisting11-30–FixedDepositController–invokingvalidationusing@Validannotation
Project–ch11-jsr303-validation
Sourcelocation-src/main/java/sample/spring/chapter11/web
packagesample.spring.chapter11.web;
importjavax.validation.Valid;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)
publicStringeditFixedDeposit(
@Valid@ModelAttribute("editableFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,
BindingResultbindingResult,SessionStatussessionStatus){
if(bindingResult.hasErrors()){.....}.....
}
.....
}
Intheaboveexamplelisting,@ValidannotationoneditableFixedDepositDetailsmodelattributeresultsin
itsautomaticvalidationbySpring.Theconstraintviolationsreportedduringvalidationareaddedtothe
BindingResultobjectalongwithanydatabindingerrors.
LetsnowlookathowSpringsformtaglibrarysimplifieswritingformsinJSPpages.
11-6Spring’sformtaglibrary
Springs form tag library provides tags that simplify creating JSP pages for Spring Web MVC
applications.TheSpringsformtaglibraryprovidestagstorendervariousinputformelementsandfor
bindingformdatatoformbackingobjects.
ThefollowingexamplelistingshowsthecreateFixedDepositForm.jspJSPpageofch11-jsr303-validation
projectthatusesSpringsformtaglibrarytags:
Examplelisting11-31–createFixedDepositForm.jsp–Spring’sformtaglibraryusage
Project–ch11-jsr303-validation
Sourcelocation-src/main/webapp/WEB-INF/jsp
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<%@taglibprefix="form"uri="http://www.springframework.org/tags/form"%>
<html>
.....
<form:formcommandName="newFixedDepositDetails"
name="createFixedDepositForm"method="POST"
action="${pageContext.request.contextPath}/fixedDeposit?fdAction=create">
.....
<tr>
<tdclass="td"><b>Amount(inUSD):</b></td>
<tdclass="td"><form:inputpath="depositAmount"/>
<fontstyle="color:#C11B17;"><form:errorspath="depositAmount"/></font>
</td>
</tr>
<tr>
<tdclass="td"><b>Maturitydate:</b></td>
<tdclass="td"><form:inputpath="maturityDate"/>
<fontstyle="color:#C11B17;"><form:errorspath="maturityDate"/></font></td>
</tr>
.....
<tdclass="td"><inputtype="submit"value="Save"/>
.....
</form:form>
</html>
In the above example listing, the following taglib directive makes the Springs form tag library tags
accessibletotheJSPpage:
<%@taglibprefix="form"uri="http://www.springframework.org/tags/form"%>
Springsformtaglibrarys<form>tagrendersanHTMLformthatbindsformfieldstothepropertiesof
model attribute identified by the commandName attribute. The <form> tag contains <input> tags that
correspond to the properties ofthe model attribute specified by the commandNameattribute. When the
formisrendered,propertiesarereadfromthemodelattributeanddisplayedby<input>tags.And,when
theformissubmitted,thefieldvaluesintheformareboundtothecorrespondingpropertiesofthemodel
attribute.
In example listing 11-31, the <form> tag renders an HTML form for opening a fixed deposit. The
commandNameattribute’svalueisnewFixedDepositDetails,whichmeansthattheformfieldsaremapped
tothepropertiesofthenewFixedDepositDetailsmodelattribute.Thenameattributespecifiesthenameof
theHTMLformrenderedbythe<form>tag.ThemethodattributespecifiestheHTTPmethodtousefor
sendingformdatawhentheformissubmitted.TheactionattributespecifiestheURLtowhichtheform
dataissentwhentheformissubmitted.TheURLspecifiedbytheactionattributemustmaptoaunique
@RequestMappingannotatedmethodinyourSpringWebMVCapplication.Inexamplelisting11-31,the
URL ${pageContext.request.contextPath}/fixedDeposit?fdAction=create maps to
FixedDepositController’s openFixedDeposit method (refer FixedDepositController.java file of ch11-
jsr303-validation project). You should note that the expression ${pageContext.request.contextPath}
returnsthecontextpathofthewebapplication.
The<input>tagofSpringsformtaglibraryrendersanHTML<input>elementwithtypeattributesetto
text.Thepathattributespecifiesthepropertyofthemodelattributetowhichthefieldismapped.When
the form is rendered, the value of the property is displayed by the input field. And, when the form is
submitted,thevalueofthepropertyissettothevalueenteredbytheuserintheinputfield.
The<errors>tagofSpringsformtaglibraryshowsdatabindingandvalidationerrormessagesthatwere
added to the BindingResult during data binding and validation. If you want to display error messages
correspondingtoaparticularproperty,specifythenameofthepropertyasthevalueofthepathattribute.
If you want to display all the error messages stored in the BindingResult object, specify value of path
attributeas*.
ThecreateFixedDepositForm.jsppageusesonlyasubsetofSpringsformtaglibrarytags.Thefollowing
tableshowstheothertagsthatSpringsformtaglibraryoffers:
Tag Description
<checkbox>
RendersanHTM Lcheckbox(thatis,<inputtype="checkbox"/>)
AsthevalueofanHTMLcheckboxisnotsenttotheserverifthecheckboxisunchecked,the
<checkbox> tag additionally renders a hidden field corresponding to each checkbox to allow
sendingthestateofthecheckboxtotheserver.
Example:<form:checkboxpath="myProperty"/>
Thepathattributespecifiesthenameofthepropertytowhichthecheckboxvalueisbound.
<checkboxes>
RendersmultipleHTMLcheckboxes.
Example:<form:checkboxespath="myPropertyList"items="${someList}"/>
Thepathattributespecifiesthenameofthepropertytowhichtheselectedcheckboxesvalues
arebound.Theitemsattributespecifiesthenameofthemodelattributethatcontainsthelistof
optionstoshowascheckboxes.
<radiobutton>
RendersanHTM Lradiobutton(thatis,<inputtype="radio"/>)
Example:<form:radiobuttonpath="myProperty"value="myValue"/>
Thepathattributespecifiesthenameofthepropertytowhichtheradiobuttonisbound,and
thevalueattributespecifiesthevalueassignedtotheradiobutton.
<radiobuttons>
RendersmultipleHTMLradiobuttons.
Example:<form:radiobuttonspath="myProperty"items="${myValues}"/>
Theitemsattributespecifiesthelistofoptionstoshowasradiobuttons,andthepathattribute
specifiesthepropertytowhichtheselectedradiobuttonsvaluesarebound.
<password> RendersanHTM Lpasswordfield(thatis,<inputtype="password"/>)
<select>
RendersanHTM L<select>element.
Example:<form:selectpath="book"items="${books}"/>
Theitems attribute specifies the model attributep roperty that contains the list of options to
displayintheHTML<select>element.Thepathattributespecifiesthepropertytowhichthe
selectedoptionisbound.
<option>
RendersanHTM L<option>element.
Example:
<form:selectpath="book">
<form:optionvalue="GettingstartedwithS pringFramework"/>
<form:optionvalue="GettingstartedwithS pringWebMVC"/>
</form:select>
<options> RendersmultipleHTM L<option>elements.
<textarea> RendersanHTML<textarea>element.
<hidden> RendersanHTM Lhiddeninputfield(thatis,<inputtype="hidden"/>)
LetsnowlookatHTML5supportinSpringsformtaglibrary.
HTML5supportinSpringsformtaglibrary
StartingwithSpring3.0,theformtaglibraryallowsyoutouseHTML5-specificattributesinthetags.For
instance,thefollowing<textarea>tagusesHTML5’srequiredattribute:
<form:textareapath="myProperty"required="required"/>
Therequired="required" attribute specifies that it is mandatory for the user to enter information in the
textarea.TheuseofrequiredattributesavestheefforttowritetheJavaScriptcodetoperformclient-side
validationformandatoryfields.Iftheuserdoesn’tenteranyinformationinthetextareaandattemptsto
submittheform,thewebbrowsershowsamessagesayingthatthetextareaisrequiredandmustnotbe
leftblank.
InHTML5youcanspecifytypeattribute’svalueasemail,datetime,date,month,week,time,range,color,
reset,andsoon.StartingwithSpring3.1,<input>tagsupportsspecifyingtypeattributevalueotherthan
text.Forinstance,thefollowing<input>tagspecifiestypeattribute’svalueasemail:
<form:inputpath="myProperty"type="email"/>
Whenauserattemptstosubmittheformcontainingafieldoftypeemail,thewebbrowserchecksthatthe
email type field contains a valid email address. If the email type field doesn’t contain a valid email
address,thewebbrowsershowsamessageindicatingthatthefielddoesn’tcontainavalidemailaddress.
Asthewebbrowserperformsthevalidation,youdon’tneedtowritetheJavaScriptcodetovalidatethe
emailaddress.
11-7Summary
WelookedatmanycorefeaturesofSpringWebMVCinthischapter.Welookedat@ModelAttributeand
@SessionAttributesannotationswhicharemostcommonlyusedindevelopingannotatedcontrollers.We
alsotookanin-depthlookathowSpringperformsdatabindingandvalidation.Inthenextchapter,well
lookathowtodevelopRESTfulwebservicesusingSpringWebMVC.
Chapter12–DevelopingRESTfulwebservicesusingSpring
WebMVC
12-1Introduction
Representational State Transfer (also referred to as REST) is an architectural-style in which an
applicationdefinesresourcesthatareuniquelyidentified byURIs (Uniform Resource Identifier). The
clients of a REST-style application interact with a resource by sending HTTP GET, POST, PUT and
DELETE method requests to the URI to which the resource is mapped. The following figure shows a
REST-styleapplicationthatisaccessedbyitsclients:
Figure12-1REST-styleapplicationdefinesxandyresourcesthatareuniquelyidentifiedby/resource2
and/resource1URIs,respectively.
TheabovefigureshowsaREST-styleapplicationthatconsistsoftworesources–xandy.Theresourcex
ismappedto/resource2URIandtheyresourceismappedto/resource1URI.Aclientcaninteractwith
resourcex by sending HTTP requests to /resource2 URI, and can interact with resource y by sending
HTTPrequeststo/resource1URI.
IfawebservicefollowstheRESTarchitectural-style,itisreferredtoasaRESTfulwebservice.Inthe
contextofRESTfulwebservices,youcanthinkofaresourceasthedataexposedbythewebservice.
TheclientcanperformCRUD(CREATE,READ,UPDATEandDELETE)operationsontheexposeddata
bysendingHTTPrequeststotheRESTfulwebservice.TheclientandtheRESTfulwebserviceexchange
representation of the data, which could be in XML, JSON (JavaScript Object Notation) format, or a
simplestring,oranyotherMIMEtypesupportedbytheHTTPprotocol.
RESTfulwebservicesaresimplertoimplementandaremorescalablecomparedtoSOAP-basedweb
services.InSOAP-basedwebservices,requestsandresponsesarealwaysinXMLformat.InRESTful
webservices,youcanuseJSON(JavaScriptObjectNotation),XML,plaintext,andsoon,forrequests
andresponses.Inthischapter,we’lllookathowSpringWebMVCsimplifiesdevelopingandaccessing
RESTfulwebservices.
LetsbeginbylookingattherequirementsofaRESTfulwebservicethatwe’llimplementusingSpring
WebMVC.
12-2Fixeddepositwebservice
We saw earlier that the MyBank web application provides the functionality to display a list of fixed
deposits,andtocreate,editandclosefixeddeposits.Asthefixeddepositrelatedfunctionalitymayalso
beaccessedbyotherapplications,thefixeddepositrelatedfunctionalityneedstobetakenoutfromthe
MyBank web application and deployed as a RESTful web service. Lets call this new RESTful web
serviceasFixedDepositWS.
ThefollowingfigureshowsthattheFixedDepositWSwebserviceisaccessedbyMyBankandSettlement
applications:
Figure12-2MyBankandSettlementapplicationsaccessFixedDepositWSwebservice
The above figure shows that MyBank and Settlement web applications interact with FixedDepositWS
web service by exchanging data in JSON format. Well soon see that JSON represents a simpler
alternativetoXMLforexchangingdatabetweenapplications.
Lets now look at how to implement FixedDepositWS web service as a RESTful web service using
SpringWebMVC.
12-3ImplementingaRESTfulwebserviceusingSpringWebMVC
TodevelopaRESTfulwebservice,youneedtodothefollowing:
·identifyresourcesthatareexposedbythewebservice
·specifyURIscorrespondingtotheidentifiedresources
·identifyoperationsthatcanbeperformedontheresources
·mapHTTPmethodstotheidentifiedoperations
IncaseofFixedDepositWSwebservice,fixeddepositdatarepresentstheresourceexposedbytheweb
service.IftheFixedDepositWSwebservicemapsfixeddepositsinthesystemto/fixedDepositsURI,a
FixedDepositWSwebserviceclientcanperformactionsonfixeddepositsbysendingHTTPrequeststo
/fixedDepositsURI.
InRESTfulwebservice,theHTTPmethodusedbyclientsforinteractingwitharesourceindicatesthe
operation to be performed on the resource. GET retrieves the resource state, POST creates a new
resource, PUT modifies the resource state and DELETE deletes the resource. The following figures
showstheactionsperformedbytheFixedDepositWSwebservicewhenaclientsendsGET,POST,PUT
andDELETEHTTPrequeststothe/fixedDepositsURI:
Figure12-3 HTTPrequestsare sent by the FixedDepositWS’s clientto /fixedDeposits URI to interact
withfixeddepositdata
The above figure shows that the client of FixedDepositWS web service sends GET, POST, PUT and
DELETEHTTPrequeststo/fixedDepositsURItointeractwiththefixeddepositdata.Theidquerystring
parameter uniquelyidentifiesa fixed depositinthesystem.The followingtabledefinesthepurpose of
eachrequestshownintheabovefigure:
HTTPmethod URI Purpose
GET /fixedDeposits Retrieve details of all the fixed deposits in the system. The FixedDepositWS
webservicesendstheresponseinJSONformat.
GET /fixedDeposits?id=123 Retrievedetailsofthefixeddepositwhoseidis123.TheFixedDepositWSweb
servicesendstheresponseinJSONformat.
POST /fixedDeposits Create a new fixed deposit in the system. The web service client sends the
detailsofthefixeddeposittobecreatedinJSONformat.
PUT /fixedDeposits?id=123 M odifies the fixeddeposit whoseid is 123. The web service client sends the
modifieddetailsofthefixeddepositinJSONformat.
DELETE /fixedDeposits?id=123 Removesthefixeddepositwhoseidis123.
The above tableshows that the FixedDepositWS and its clientsexchange informationinJSONformat.
Beforedelving intothedetailsofhowtoimplementFixedDepositWS,letslookathowthedatalooks
likeinJSONformat.
JSON(JavaScriptObjectNotation)
JSONisatext-baseddataformatthatisusedbyapplicationsforexchangingstructureddata.AsJSON
representationofdataismorecompactcomparedtoXML,JSONservesasasimpleralternativetoXML.
To simplify conversion of Java objects to JSON and vice versa, you can use JSON libraries like
FlexJson(http://flexjson.sourceforge.net/)andJackson(https://github.com/FasterXML/jackson).
LetssayaPersonclassdefinesfirstNameandlastName attributes.Ifyoucreateaninstanceof Person
objectand setfirstName to Myfirstname and lastName toMylastname, the representation of the Person
objectinJSONformatwouldlooklikethis:
Examplelisting12-1–PersonobjectrepresentationinJSONformat
{
"firstName":Myfirstname,
"lastName":"Mylastname"
}
TheaboveexamplelistingshowsthateachattributeofPersonobjectisrepresentedas<attribute-name>:
<attribute-value>inJSONformat.
YoucanalsorepresentacollectionofJavaobjectsinJSONformat.Thefollowingexamplelistingshows
howyoucanrepresentacollectionofPersonobjectsinJSONformat:
Examplelisting12-2–CollectionofPersonobjectsrepresentedinJSONformat
[
{
"firstName":Myfirstname,
"lastName":"Mylastname"
},
{
"firstName":Yourfirstname,
"lastName":"Yourlastname"
}
]
Youdon’tneedtowritecodetoconvertanobjectintoJSONrepresentationandviceversa.Instead,the
RESTfulwebserviceanditsclientscanmakeuseofFlexJsonorJacksonlibrarytoperformconversion.
Aswellsoonsee,SpringWebMVCusesJacksonforconvertingJSONtoJavaobjectsandviceversa.
LetsnowlookattheimplementationofFixedDepositWSwebserviceusingSpringWebMVC.
IMPORTchapter 12/ch12-webservice(This project shows the implementation of FixedDepositWS
RESTfulwebserviceusingSpringWebMVC.Laterinthischapter,we’llseehowFixedDepositWSweb
serviceisaccessedbyitsclients.)
FixedDepositWSwebserviceimplementation
Spring Web MVC annotations, like @Controller, @RequestMapping, @RequestParam, @PathVariable
@ResponseBody,@RequestBody, and so on, support building RESTful web services. In this section,
we’lllookatusageofsomeoftheseannotationsindevelopingtheFixedDepositWSwebservice.
In FixedDepositWS web service, the FixedDepositController (a Spring Web MVC controller) is
responsible for handling web service requests. FixedDepositController is like any other Spring Web
MVCcontrollerwiththeexceptionthatits@RequestMappingmethodsdon’trenderviews.Thefollowing
examplelistingshowsthat@Controllerand@RequestMappingannotationsareusedtomapwebrequests
toappropriatemethodsofFixedDepositControllerclass:
Examplelisting12-3–FixedDepositController–webservicerequesthandler
Project–ch12-webservice
Sourcelocation-src/main/java/sample/spring/chapter12/web
packagesample.spring.chapter12.web;
importorg.springframework.http.ResponseEntity;
.....
@Controller
@RequestMapping(value="/fixedDeposits")
publicclassFixedDepositController{
.....
@RequestMapping(method=RequestMethod.GET)
publicResponseEntity<List<FixedDepositDetails>>getFixedDepositList(){.....}
@RequestMapping(method=RequestMethod.GET,params="id")
public ResponseEntity<FixedDepositDetails> getFixedDeposit(@RequestParam("id") int id) {
.....}
.....
}
ThegetFixedDepositListmethodreturnsthelistoffixeddepositsinthesystem,andthegetFixedDeposit
methodreturnsdetailsofthefixeddepositidentifiedbytheidargument.Theaboveexamplelistingshows
that the @RequestMapping annotation is used at the class- and method-level to map requests to
getFixedDepositList and getFixedDeposit methods. The getFixedDepositList method is invoked when a
clientapplicationsendsanHTTPGETrequestto/fixedDepositsURI,andthegetFixedDepositmethodis
invoked when a client application sends an HTTP GET request containing id request parameter to
/fixedDeposits URI. So, if the request URI is /fixedDeposits?id=123, the getFixedDeposit method is
invoked.
ThefollowingtablesummarizesthemappingofrequestURIsandHTTPmethodstothemethodsdefined
intheFixedDepositControllerclass:
HTTPmethod URI FixedDepositControllermethod
GET /fixedDeposits getFixedDepositList
GET /fixedDeposits?id=123 getFixedDeposit
POST /fixedDeposits openFixedDeposit
PUT /fixedDeposits?id=123 editFixedDeposit
DELETE /fixedDeposits?id=123 closeFixedDeposit
Wesawinchapter10and11that@RequestMappingannotatedmethodsreturnviewinformationthatis
used by the DispatcherServlet to render a view (like JSP or servlet). In RESTful web services,
@RequestMappingmethodsreturndata(andnottheviewinformation)totheclientapplications.Forthis
reason,thegetFixedDepositListandgetFixedDepositmethodshavebeendefinedtoreturnobjectsoftype
ResponseEntity. Let’s now look at the usage of ResponseEntity object in the FixedDepositController
class.
SpecifyingHTTPresponseusingResponseEntity
ResponseEntityrepresentsanHTTPresponseconsistingofheaders,bodyandstatuscode.Theobjectthat
yousetasbodyontheResponseEntityobjectiswrittentotheHTTPresponsebodybySpringWebMVC.
The following example listing shows how the ResponseEntity object is created by
FixedDepositController’sgetFixedDepositListmethod:
Examplelisting12-4–FixedDepositController–creatingResponseEntityinstance
Project–ch12-webservice
Sourcelocation-src/main/java/sample/spring/chapter12/web
packagesample.spring.chapter12.web;
importorg.springframework.http.HttpStatus;
importorg.springframework.http.ResponseEntity;
.....
publicclassFixedDepositController{
.....
@RequestMapping(method=RequestMethod.GET)
publicResponseEntity<List<FixedDepositDetails>>getFixedDepositList(){
.....
returnnewResponseEntity<List<FixedDepositDetails>>(
fixedDepositService.getFixedDeposits(),HttpStatus.OK);
}
.....
}
Intheaboveexamplelisting,thefixeddepositlistpassedtotheResponseEntityconstructoriswrittento
theHTTPresponsebody.TheHttpStatusisanenumtypethatdefinesHTTPstatuscodes.TheconstantOK
refers to the HTTP status code 200. Notice that the return type of the getFixedDepositList method is
ResponseEntity<List<FixedDepositDetails>>, which means that an object of type
List<FixedDepositDetails>iswrittentotheHTTPresponsebody.SpringWebMVCusesanappropriate
HttpMessageConverter(explainedinsection12-5)toconverttheList<FixedDepositDetails>objectinto
theformatexpectedbytheclientapplication.
NOTELaterinthischapter,wellseethatclientapplicationscanuseSpringsRestTemplatetoinvoke
methodsdefinedintheFixedDepositControllerandtoretrievetheobjectswrittentotheHTTPresponse
body.
Allthe@RequestMappingannotatedmethodsofFixedDepositControllerclassdefineResponseEntityas
their return type. If youdon’t need to send HTTP status code in the response, you can use Springs
HttpEntity class instead of ResponseEntity. HttpEntity represents an HTTP request or response, and
ResponseEntityisasubclassofHttpEntitythataddsanHTTPstatuscodetotheresponse.
ThefollowingexamplelistingshowsamodifiedversionofgetFixedDepositListmethodthatcreatesand
returnsaninstanceofHttpEntity:
Examplelisting12-5–FixedDepositController–usingHttpEntityinsteadofResponseEntity
importorg.springframework.http.HttpStatus;
importorg.springframework.http.HttpEntity;
.....
publicclassFixedDepositController{
.....
@RequestMapping(method=RequestMethod.GET)
publicHttpEntity<List<FixedDepositDetails>>getFixedDepositList(){
.....
returnnewHttpEntity<List<FixedDepositDetails>>(fixedDepositService.getFixedDeposits());
}
.....
}
TheaboveexamplelistingshowsthatthefixeddepositsfoundinthesystemarepassedtotheHttpEntity
constructor. As in case of ResponseEntity (refer example listing 12-4), fixed deposits passed to the
HttpEntityarewrittentotheHTTPresponsebody.
Both HttpEntity and ResponseEntity objects allow you to set HTTP response headers. The following
examplelistingshowsascenarioinwhichsome-headerheaderissetontheHTTPresponse:
Examplelisting12-6–HttpHeadersusage
importorg.springframework.http.HttpHeaders;
.....
@RequestMapping(method=RequestMethod.GET)
publicHttpEntity<String>doSomething(){
HttpHeadersresponseHeaders=newHttpHeaders();
responseHeaders.set("some-header","some-value");
returnnewHttpEntity<String>("Helloworld!",responseHeaders);
}
.....
SpringsHttpHeadersobjectcontainstheheadersthataresetontheHTTPresponse.Intheaboveexample
listing, HttpHeaders setmethod setssome-header response header (with value some-value). When the
doSomething method is invoked, the ‘Helloworld! string is written to the response body, and some-
headerheaderiswrittentotheHTTPresponse.
As@RequestMappingmethodscanbedefinedtoacceptHttpServletResponseobjectasargument,lets
lookathowyoucandirectlysetresponsebodyandheadersontheHttpServletResponseobject.
SpecifyingHTTPresponseusingHttpServletResponse
The following example listing shows a @RequestMapping method which writes directly to the
HttpServletResponseobject:
Examplelisting12-7–SettingresponseonHttpServletResponse
importjavax.servlet.http.HttpServletResponse;
.....
@RequestMapping(method=RequestMethod.GET)
publicvoiddoSomething(HttpServletResponseresponse)throwsIOException{
response.setHeader("some-header","some-value");
response.setStatus(200);
response.getWriter().write("Helloworld!");
}
.....
Instead of directly writing response to HttpServletResponse, you should use ResponseEntity (or
HttpEntity)objecttoimprovethetestabilityofthecontrollers.
LetsnowlookatSprings@ResponseBodymethod-levelannotationthatwritesthereturnvalueofthe
methodtoHTTPresponsebody.
NOTE As of Spring 4.0, @ResponseBody annotation can also be specified at the class level. If
@ResponseBody annotation is specified at the class level, it is inherited by the @RequestMapping
methodsofthecontroller.
BindingreturnedvalueofamethodtoHTTPresponsebodyusing@ResponseBody
Thefollowingexamplelistingshowsusageof@ResponseBodyannotation:
Examplelisting12-8–@ResponseBodyannotationusage
importorg.springframework.web.bind.annotation.ResponseBody;
.....
@RequestMapping(method=RequestMethod.GET)
@ResponseBody
publicStringdoSomething(){
return"Helloworld!";
}
.....
In the above example listing, the ‘Hello world !’ string value returned by the doSomething method is
writtentotheHTTPresponsebody.Insection10-7ofchapter10,wediscussedthatifthereturntypeofa
@RequestMapping annotatedmethodisString, thereturnedvalueis treatedas thename of theview to
render.Intheaboveexamplelisting,the@ResponseBodyannotationonthedoSomethingmethodinstructs
SpringWebMVCtowritethestringvaluetotheHTTPresponsebodyinsteadoftreatingthestringvalue
astheviewname.YoushouldnotethatSpringusesanappropriateHttpMessageConverter(explainedin
section12-5)implementationtowritethevaluereturnedbythe@ResponseBodyannotatedmethodtothe
HTTPresponsebody.
Now, that we have seen different ways in which a @RequestMapping method can write to the HTTP
response, let’s look at how a @RequestMapping method can read information from the HTTP request
bodyusing@RequestBodyannotation.
BindingHTTPrequestbodytoamethodparameterusing@RequestBody
A @RequestMapping annotated method can use @RequestBody method-parameter level annotation to
bind HTTP request body to the method parameter. Spring Web MVC uses an appropriate
HttpMessageConverter(explainedinsection12-5)implementationtoconverttheHTTPrequestbodyto
themethodparametertype.Thefollowingexamplelistingshowsusageof@RequestBodyannotationin
MyBankapplicationsFixedDepositController:
Examplelisting12-9–@RequestBodyannotationusage
Project–ch12-webservice
Sourcelocation-src/main/java/sample/spring/chapter12/web
packagesample.spring.chapter12.web;
.....
importorg.springframework.web.bind.annotation.RequestBody;
.....
@Controller
@RequestMapping(value="/fixedDeposits")
publicclassFixedDepositController{
.....
@RequestMapping(method=RequestMethod.POST)
publicResponseEntity<FixedDepositDetails>openFixedDeposit(
@RequestBodyFixedDepositDetailsfixedDepositDetails,
BindingResultbindingResult){
newFixedDepositDetailsValidator().validate(fixedDepositDetails,bindingResult);
.....
}
.....
}
In the above example listing, the FixedDepositDetails type method argument is annotated with
@RequestBody annotation. Spring Web MVC is responsible for converting the HTTP request body to
FixedDepositDetailstypeobject.Intheaboveexamplelisting,FixedDepositDetailsValidatorclassisan
implementation of Springs Validator interface that validates the FixedDepositDetails object before
attemptingtocreatethefixeddeposit.
An alternative to using @RequestBody annotation is to directly read HTTP request body from the
HttpServletRequestobjectandconverttherequestbodycontenttotheJavatyperequiredbythemethod.
Springs @RequestBody annotation simplifies the conversion because it uses an appropriate
HttpMessageConverterimplementationtoconvertHTTPrequestbodytotheobjecttypeexpectedbythe
@RequestMappingmethod.
Letsnowlookatthe@ResponseStatusannotationthatallowsyoutosetHTTPresponsestatus.
SettingHTTPresponsestatususing@ResponseStatus
You can use the @ResponseStatus annotation to specify the HTTP response status returned by a
@RequestMappingmethod.Thefollowingexamplelistingshowsusageof@ResponseStatusannotation:
Examplelisting12-10–@ResponseStatusannotationusage
importorg.springframework.web.bind.annotation.ResponseStatus;
publicclassSomeController{
@RequestMapping(method=RequestMethod.GET)
@ResponseStatus(value=HttpStatus.OK)
@ResponseBody
publicSomeObjectdoSomething(){
.....
}
}
AsthedoSomethingmethodisannotatedwith@ResponseBodyannotation,theSomeObjectreturnedby
thedoSomethingmethodiswrittentotheHTTPresponsebody.And,the@ResponseStatusannotationsets
theHTTPresponsestatuscodeto200(representedbyHttpStatus.OKconstant).
Lets now look at how the @ExceptionHandler annotation is used in FixedDepositWS web service to
handleexceptions.
Handlingexceptionsusing@ExceptionHandler
In section 10-9 of chapter 10, we saw that the @ExceptionHandler annotation identifies a controller
method that is responsible for handling exceptions. Like @RequestMapping methods,
@ExceptionHandlermethodsinRESTfulwebservicesareannotatedwith@ResponseBodyannotationor
thereturntypeisdefinedasResponseEntity(orHttpEntity).
Thefollowingexamplelistingshowsusageof@ExceptionHandlerannotationinFixedDepositController
classofch12-webserviceproject:
Examplelisting12-11–@ExceptionHandlerannotationusage
Project–ch12-webservice
Sourcelocation-src/main/java/sample/spring/chapter12/web
packagesample.spring.chapter12.web;
importsample.spring.chapter12.exception.ValidationException;
.....
publicclassFixedDepositController{
.....
@ExceptionHandler(ValidationException.class)
@ResponseBody
@ResponseStatus(value=HttpStatus.BAD_REQUEST)
publicStringhandleException(Exceptionex){
logger.info("handlingValidationException"+ex.getMessage());
returnex.getMessage();
}
}
@ExceptionHandlerannotationonhandleExceptionmethodindicatesthatthehandleExceptionmethodis
invoked when ValidationException is thrown by the FixedDepositController during request processing.
As the handleException method is also annotated with @ResponseBody annotation, the exception
messagereturnedbythehandleExceptionmethodiswrittentotheHTTPresponsebody.@ResponseStatus
onthehandleExceptionmethodresultsinsettingtheHTTPresponsestatuscodeto400(representedby
HttpStatus.BAD_REQUESTconstant).
Inthissection,wesawhowtoimplementFixedDepositWSwebserviceusingSpringWebMVC.Lets
nowlookathowtoaccessFixedDepositWSwebserviceusingSpringsRestTemplate.
12-4AccessingRESTfulwebservicesusingRestTemplate
Springs RestTemplate class simplifies accessing RESTful web services by taking care of managing
HTTPconnectionsandhandlingHTTPerrors.
IMPORTchapter 12/ch12-webservice-client(This project represents a standalone Java application
that accesses FixedDepositWS RESTful web service using Springs RestTemplate (for synchronously
accessing the web service) and AsyncRestTemplate (forasynchronously accessing the web service)
class. The ch12-webservice-client project assumes that the ch12-webservice project representing the
FixedDepositWSRESTfulwebserviceisdeployedathttp://localhost:8080/ch12-webserviceURL.)
RestTemplateconfiguration
ThefollowingexamplelistingshowshowRestTemplateisconfiguredintheapplicationcontextXMLfile
ofch12-webservice-clientproject:
Examplelisting12-12–applicationContext.xml-RestTemplateconfiguration
Project–ch12-webservice-client
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
<beanid="restTemplate"class="org.springframework.web.client.RestTemplate">
<propertyname="errorHandler"ref="errorHandler"/>
</bean>
<beanid="errorHandler"class="sample.spring.chapter12.MyErrorHandler"/>
.....
</beans>
RestTemplate’s errorHandler property refers to an implementation of Springs ResponseErrorHandler
interface that inspects the HTTP response for errors and handles the response in case of errors.
DefaultResponseErrorHandler is the default implementation of ResponseErrorHandler interface that is
provided out-of-the-box by Spring. If you dont specify the errorHandler property, Spring uses the
DefaultResponseErrorHandler implementation. The above example listing shows that the RestTemplate
usesacustomresponseerrorhandler,MyErrorHandler.
ThefollowingexamplelistingshowstheimplementationofMyErrorHandlerclass:
Examplelisting12-13–MyErrorHandlerclass–HTTPresponseerrorhandler
Project–ch12-webservice-client
Sourcelocation-src/main/java/sample/spring/chapter12
packagesample.spring.chapter12;
importorg.apache.commons.io.IOUtils;
importorg.springframework.http.client.ClientHttpResponse;
importorg.springframework.web.client.DefaultResponseErrorHandler;
publicclassMyErrorHandlerextendsDefaultResponseErrorHandler{
privatestaticLoggerlogger=Logger.getLogger(MyErrorHandler.class);

@Override
publicvoidhandleError(ClientHttpResponseresponse)throwsIOException{
logger.info("Statuscodereceivedfromthewebservice:"+response.getStatusCode());
Stringbody=IOUtils.toString(response.getBody());
logger.info("Responsebody:"+body);
super.handleError(response);
}
}
TheaboveexamplelistingshowsthattheMyErrorHandlerclassextendsDefaultResponseErrorHandler
classandoverridesthehandleError method.IftheHTTPresponse’sstatuscodeindicatesan error,the
handleError method is responsible for handling the response. The ClientHttpResponse argument to the
handleErrormethodrepresentstheHTTPresponsereceivedfromcallingtheRESTfulwebservice.The
call to ClientHttpResponse’s getBody method returns the body of HTTP response as an InputStream
object.MyErrorHandlershandleErrormethodlogsinformationaboutthestatuscodeandthebodyofthe
HTTP response, and delegates handling of the error to DefaultResponseErrorHandlers handleError
method. The above example listing shows that the MyErrorHandler class uses Apache Commons IO’s
IOUtilsclasstogetthecontentoftheHTTPresponsebodyasaString.
Now,thatwehaveseenhowaRestTemplateclassisconfigured,letslookathowRestTemplateisused
byclientapplicationstoaccessRESTfulwebservices.
AccessingFixedDepositWSwebserviceusingRestTemplate
ThefollowingexamplelistingshowstheFixedDepositWSClientclassthatusesRestTemplatetoaccess
FixedDepositWSwebservice:
Examplelisting12-14–FixedDepositWSClientclass–RestTemplateusage
Project–ch12-webservice-client
Sourcelocation-src/main/java/sample/spring/chapter12
packagesample.spring.chapter12;
.....
importorg.springframework.web.client.RestTemplate;
publicclassFixedDepositWSClient{
privatestaticApplicationContextcontext;
publicstaticvoidmain(Stringargs[]){
context=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
getFixedDepositList(context.getBean(RestTemplate.class));
getFixedDeposit(context.getBean(RestTemplate.class));
.....
}
privatestaticvoidgetFixedDepositList(RestTemplaterestTemplate){.....}
.....
}
TheaboveexamplelistingshowsthattheFixedDepositWSClient’smainmethodperformsthefollowing
actions:
§bootstrapstheSpringcontainer(representedbytheApplicationContextobject)
§callsgetFixedDepositList,getFixedDeposit,andsoon,methods.Thesemethodsacceptaninstance
ofRestTemplate,andareresponsibleforcallingtheFixedDepositWSwebservice.
ThefollowingexamplelistingshowstheimplementationofFixedDepositWSClient’sgetFixedDepositList
methodthatcallstheFixedDepositWSwebservicedeployedathttp://localhost:8080/ch12-webserviceto
obtainthelistoffixeddepositsinthesystem:
Examplelisting12-15–FixedDepositWSClient’sgetFixedDepositListmethod
Project–ch12-webservice-client
Sourcelocation-src/main/java/sample/spring/chapter12
packagesample.spring.chapter12;
.....
importorg.springframework.core.ParameterizedTypeReference;
importorg.springframework.http.*;
importorg.springframework.web.client.RestTemplate;
publicclassFixedDepositWSClient{
.....
privatestaticvoidgetFixedDepositList(RestTemplaterestTemplate){
HttpHeadersheaders=newHttpHeaders();
headers.add("Accept","application/json");
HttpEntity<String>requestEntity=newHttpEntity<String>(headers);
ParameterizedTypeReference<List<FixedDepositDetails>>typeRef=
newParameterizedTypeReference<List<FixedDepositDetails>>(){
};
ResponseEntity<List<FixedDepositDetails>>responseEntity=restTemplate
.exchange("http://localhost:8080/ch12-webservice/fixedDeposits",
HttpMethod.GET,requestEntity,typeRef);
List<FixedDepositDetails>fixedDepositDetails=responseEntity.getBody();
logger.info("Listoffixeddepositdetails:\n"+fixedDepositDetails);
}
.....
}
Intheaboveexamplelisting,RestTemplatesexchangemethodhasbeenusedtosendHTTPGETrequest
to http://localhost:8080/ch12-webservice/fixedDeposits URL. As the FixedDepositWS web service is
deployed athttp://localhost:8080/ch12-webservice URL, sending HTTP GET request to
http://localhost:8080/ch12-webservice/fixedDeposits URL results in invocation of
FixedDepositController’s getFixedDepositList method. This is because the FixedDepositControllers
getFixedDepositList method is mapped to /fixedDeposits URI (refer example listing 12-3 or
FixedDepositControllerclassofch12-webserviceproject).
In example listing 12-15, the HttpEntity object represents the request sent to the web service, the
HttpHeaders object represents the request headers in the request, and the ParameterizedTypeReference
objectrepresents the generic type of the response received from the web service. The Accept request
headers value has been set to application/json to specify that the response from the FixedDepositWS
webserviceisexpectedinJSONformat.Onthewebservice-side,thevalueofAcceptheaderisusedby
SpringWebMVCtochooseanappropriateHttpMessageConvertertoconvertthevaluereturnedbythe
@ResponseBody annotated method intothe format specified by the Accept header. For instance, if the
Accept header value is application/json, Spring Web MVC uses
MappingJackson2HttpMessageConverter (an implementation of HttpMessageConverter) to convert the
valuereturnedbythe@ResponseBodyannotatedmethodintoJSONformat.TheFixedDepositWSClient
specifies the value of Accept header as application/json; therefore, the value returned by
FixedDepositController’sgetFixedDepositListmethodisconvertedtoJSONformat.
The RestTemplate’s exchange method returns an instance of ResponseEntity which represents the
responsereturnedbythewebservice.Asthegenerictypeoftheresponsereceivedfrominvocationof
FixedDepositController’s getFixedDepositList is List<FixedDepositDetails>, an instance of
ParameterizedTypeReference<List<FixedDepositDetails>>iscreatedandpassedtotheexchangemethod.
YoucancallResponseEntitysgetBodymethodtoretrievetheresponsereturnedbythewebservice.In
example listing 12-15, ResponseEntitys getBody method returns an object of type
List<FixedDepositDetails>thatrepresentsthelistoffixeddepositsreturnedbytheFixedDepositWSweb
service.
The following figure shows the role played by MappingJackson2HttpMessageConverter when
FixedDepositWSClientinvokesFixedDepositControllersgetFixedDepositListmethod:
Figure 12-4 FixedDepositWSClient’s getFixedDepositList method uses RestTemplate to send a web
requesttoFixedDepositWSwebservice
TheabovefigureshowsthatMappingJackson2HttpMessageConverterisusedtoconvertthereturnvalue
of FixedDepositController’s getFixedDepositList method into JSON format. Also,
MappingJackson2HttpMessageConverter is used by the RestTemplate to convert the JSON response
receivedfromtheFixedDepositControllertoaJavaobjectoftypeList<FixedDepositDetails>.
In examplelisting 12-15,RestTemplates exchange method was used to send anHTTP GET request to
FixedDepositWSwebservice.TheexchangemethodistypicallyusediftheHTTPresponsefromtheweb
serviceneedstobeconvertedtoaJavagenerictype,andtosendHTTPrequestheaders.RestTemplate
alsodefinesHTTPmethod-specificmethodsthatsimplifywritingRESTfulclients.Forinstance,youcan
usegetForEntitymethodtosendHTTPGETrequest,postForEntitytosendHTTPPOSTrequest,deleteto
sendHTTPDELETErequest,andsoon.
The following example listing shows FixedDepositWSClient’sopenFixedDeposit method that sends an
HTTPPOSTrequesttoFixedDepositWSwebservicetocreateanewfixeddeposit:
Examplelisting12-16–FixedDepositWSClient’sopenFixedDepositmethod
Project–ch12-webservice-client
Sourcelocation-src/main/java/sample/spring/chapter12
packagesample.spring.chapter12;
importorg.springframework.http.ResponseEntity;
importorg.springframework.web.client.RestTemplate;
.....
publicclassFixedDepositWSClient{
.....
privatestaticvoidopenFixedDeposit(RestTemplaterestTemplate){
FixedDepositDetailsfdd=newFixedDepositDetails();
fdd.setDepositAmount("9999");
.....
ResponseEntity<FixedDepositDetails>responseEntity=restTemplate
.postForEntity("http://localhost:8080/ch12-webservice/fixedDeposits",
fdd,FixedDepositDetails.class);
FixedDepositDetailsfixedDepositDetails=responseEntity.getBody();
.....
}
}
FixedDepositWSClient’sopenFixedDepositmethodsendsdetailsofthefixeddeposittobecreatedtothe
FixedDepositWSweb service.Ifthefixeddepositiscreatedsuccessfully,FixedDepositWSreturnsthe
newly created FixedDepositDetails object containing the unique identifier assigned to it. The above
examplelistingshowsthatRestTemplate’spostForEntitymethodacceptswebserviceURL,objecttobe
POSTed (which is FixedDepositDetails object), and the HTTP response type (which is
FixedDepositDetails.class). Sending HTTP POST request to http://localhost:8080/ch12-
webservice/fixedDeposits URL results in invocation of FixedDepositControllers openFixedDeposit
method(referexamplelisting12-9orFixedDepositControllerclassofch12-webserviceproject).
FixedDepositController’s openFixedDeposit method validates details of the fixed deposit before
attempting to create the fixed deposit. FixedDepositDetailsValidator is responsible for validating the
fixeddepositdetails.Ifthefixeddepositamountislessthan1000ortenureislessthan12monthsorifthe
email id specified is not well-formed, an exception is thrown by the openFixedDeposit method. The
following example listing shows openFixedDeposit and handleException methods of
FixedDepositController:
Examplelisting12-17–openFixedDepositandhandleExceptionmethodsofFixedDepositController
Project–ch12-webservice
Sourcelocation-src/main/java/sample/spring/chapter12/web
packagesample.spring.chapter12.web;
importorg.springframework.validation.BindingResult;
importorg.springframework.web.bind.annotation.ExceptionHandler;
importsample.spring.chapter12.exception.ValidationException;
.....
@Controller
@RequestMapping(value="/fixedDeposits")
publicclassFixedDepositController{
.....
@RequestMapping(method=RequestMethod.POST)
publicResponseEntity<FixedDepositDetails>openFixedDeposit(
@RequestBodyFixedDepositDetailsfixedDepositDetails,BindingResultbindingResult){
newFixedDepositDetailsValidator().validate(fixedDepositDetails,bindingResult);
if(bindingResult.hasErrors()){
thrownewValidationException("Validationerrorsoccurred");
}else{
fixedDepositService.saveFixedDeposit(fixedDepositDetails);
.....
}
@ExceptionHandler(ValidationException.class)
@ResponseBody
@ResponseStatus(value=HttpStatus.BAD_REQUEST)
publicStringhandleException(Exceptionex){
returnex.getMessage();
}
}
.....
}
TheaboveexamplelistingshowsthattheopenFixedDepositmethodthrowsValidationExceptioniffixed
deposit fails validation. As the handleException method is annotated with
@ExceptionHandler(ValidationException.class), the ValidationException thrown by the
openFixedDeposit method is handled by the handleException method. @ResponseBody and
@ResponseStatus(value=HttpStatus.BAD_REQUEST) annotations specify that the exception message
returned by the handleException method is written to the response body and the status code is set to
HttpStatus.BAD_REQUESTconstant(whichcorrespondstoHTTPstatuscode400).
FixedDepositWSClient’sopenInvalidFixedDepositmethodattemptstocreateafixeddepositwithdeposit
amount100,asshownhere:
Examplelisting12-18–FixedDepositWSClient-openInvalidFixedDepositmethod
Project–ch12-webservice-client
Sourcelocation-src/main/java/sample/spring/chapter12
privatestaticvoidopenInvalidFixedDeposit(RestTemplaterestTemplate){
FixedDepositDetailsfdd=newFixedDepositDetails();
fdd.setDepositAmount("100");
fdd.setEmail("99@somedomain.com");
fdd.setTenure("12");
ResponseEntity<FixedDepositDetails>responseEntity=restTemplate
.postForEntity("http://localhost:8080/ch12-webservice/fixedDeposits",
fdd,FixedDepositDetails.class);
FixedDepositDetailsfixedDepositDetails=responseEntity.getBody();
logger.info("Detailsofthenewlycreatedfixeddeposit:"
+fixedDepositDetails);
}
The openInvalidFixedDeposit method uses RestTemplate to send request to FixedDepositControllers
openFixedDeposit method. As the fixed deposit amount is specified as 100, FixedDepositControllers
openFixedDeposit method throws ValidationException (refer example listing 12-17).
FixedDepositController’s handleException method (refer example listing 12-17) handles the
ValidationExceptionandsetstheHTTPresponsestatusto400.Astheresponsestatuscodereceivedby
RestTemplateis400,thehandlingofresponseisdelegatedtotheMyErrorHandlerimplementation(refer
examplelisting12-12and12-13)thatweconfiguredfortheRestTemplate.
RestTemplateallowsclientstosynchronouslyaccessRESTfulwebservices.Letsnowlookathowto
asynchronouslyaccessRESTfulwebservicesusingSpringsAsyncRestTemplate.
AsynchronouslyaccessingRESTfulwebservicesusingAsyncRestTemplate
ToallowclientstoasynchronouslyaccessRESTfulwebservices,SpringprovidesAsyncRestTemplate.
The following example listing shows how AsyncRestTemplate is configured in the application context
XMLfileofch12-webservice-clientproject:
Examplelisting12-19–applicationContext.xml-AsyncRestTemplateconfiguration
Project–ch12-webservice-client
Sourcelocation-src/main/resources/META-INF/spring
<beans.....>
.....
<beanid="errorHandler"class="sample.spring.chapter12.MyErrorHandler"/>
<beanid="asyncRestTemplate"class="org.springframework.web.client.AsyncRestTemplate">
<propertyname="errorHandler"ref="errorHandler"/>
</bean>
</beans>
If you compare the above example listing with the example listing 12-12, youll notice that both
AsyncRestTemplate and RestTemplate classes are configured in the same way; they use the same
MyErrorHandlerinstanceforhandlingHTTPerrors.
AsyncRestTemplate class defines methods that are similar to the methods defined by the RestTemplate
class. The following example listing shows the FixedDepositWSAsyncClient class that uses
AsyncRestTemplatetoaccessFixedDepositWSwebservice:
Examplelisting12-20–FixedDepositWSAsyncClient-openFixedDepositmethod
Project–ch12-webservice-client
Sourcelocation-src/main/java/sample/spring/chapter12
packagesample.spring.chapter12;
importorg.springframework.http.HttpEntity;
importorg.springframework.util.concurrent.ListenableFuture;
importorg.springframework.util.concurrent.ListenableFutureCallback;
importorg.springframework.web.client.AsyncRestTemplate;
publicclassFixedDepositWSAsyncClient{
privatestaticApplicationContextcontext;
publicstaticvoidmain(Stringargs[]){
context=newClassPathXmlApplicationContext(
"classpath:META-INF/spring/applicationContext.xml");
.....
openFixedDeposit(context.getBean(AsyncRestTemplate.class));
}
privatestaticvoidopenFixedDeposit(AsyncRestTemplaterestTemplate){
FixedDepositDetailsfdd=newFixedDepositDetails();
fdd.setDepositAmount("9999");
.....
HttpEntity<FixedDepositDetails>requestEntity=newHttpEntity<FixedDepositDetails>(fdd);
ListenableFuture<ResponseEntity<FixedDepositDetails>>futureResponseEntity=
restTemplate.postForEntity("http://localhost:8080/ch12-webservice/fixedDeposits",
requestEntity,FixedDepositDetails.class);
futureResponseEntity
.addCallback(newListenableFutureCallback<ResponseEntity<FixedDepositDetails>>(){
@Override
publicvoidonSuccess(ResponseEntity<FixedDepositDetails>entity){
FixedDepositDetailsfixedDepositDetails=entity.getBody();
}
@Override
publicvoidonFailure(Throwablet){}
});
}
}
TheaboveexamplelistingshowsthattheopenFixedDepositmethodusesAsyncRestTemplatetosenda
request to FixedDepositWS web service. AsyncRestTemplate’s postForEntity method sends an HTTP
POSTrequesttoFixedDepositWSwebservicethatinvokesFixedDepositControllersopenFixedDeposit
method. If you compare the AsyncRestTemplate’s postForEntity method shown above with that of
RestTemplate’s postForEntity method (refer example listing 12-16), youll notice that the
AsyncRestTemplates postForEntity returns an object of type ListenableFuture (that extends
java.util.concurrent.Future interface). ListenableFutures addCallback method is used to register a
callback that is triggered when the ListenableFuture task completes. ListenableFuture’s addCallback
method accepts an argument of type ListenableFutureCallback that defines onSuccess and onFailure
methods.TheonSuccessmethodiscalledwhentheListenableFuturetaskcompletessuccessfully,andthe
onFailuremethodiscalledwhentheListenableFuturetaskfailstocomplete.
YoushouldnotethatbydefaultAsyncRestTemplateusesaSimpleAsyncTaskExecutortoasynchronously
executeeachrequestinanewthread.YoucanpassaThreadPoolTaskExecutortoAsyncRestTemplate’s
constructor toasynchronously execute tasks using a thread from athreadpool. Refer to section 8-6 of
chapter8tolearnmoreaboutSimpleAsyncTaskExecutorandThreadPoolTaskExecutor.
LetsnowlookatthepurposeservedbyHttpMessageConvertersinSpringWebMVC.
12-5 Converting Java objects to HTTP requests and responses and
viceversausingHttpMessageConverter
HttpMessageConvertersareusedbySpringinthefollowingscenariostoperformconversion:
§ifamethodargumentisannotatedwith@RequestBodyannotation,SpringconvertsHTTPrequest
bodytotheJavatypeofthemethodargument
§ifamethodisannotatedwith@ResponseBodyannotation,SpringconvertsthereturnedJavaobject
fromthemethodtoHTTPresponsebody
§ifthereturntypeofamethodisHttpEntityorResponseEntity,Springconvertstheobjectreturnedby
themethodtotheHTTPresponsebody
§objectspassedtoandreturnedfromthemethodsofRestTemplateandAsyncRestTemplateclasses
likegetForEntity,postForEntity,exchange, and so on, are converted to HTTP requests and from
HTTPresponsesbySpring
ThefollowingtabledescribessomeoftheHttpMessageConverterimplementationsthatareprovidedout-
of-the-boxbySpringWebMVC:
HttpMessageConverterimplementation Description
StringHttpMessageConverter
convertsto/fromstrings
FormHttpM essageConverter
convertsformdatato/fromMultiValueMap<String,String> type.
ThisHttpM essageConverterisusedbySpringwhendealingwith
formdataandfileuploads.
MappingJackson2HttpM essageConverter convertsto/fromJSON
MarshallingHttpMessageConverter convertsto/fromXM L
HttpMessageConverters mentioned in the above table are automatically registered with the Spring
container by the <annotation-driven> element of Springs mvc schema. To view the complete list of
HttpMessageConvertersthatareregisteredbydefaultby<annotation-driven>element,refertotheSpring
Frameworkreferencedocumentation.
Lets now look at @PathVariable and @MatrixVariable annotations that further simplify developing
RESTfulwebservicesusingSpringWebMVC.
12-6@PathVariableand@MatrixVariableannotations
Instead of specifying the actual URI, a @RequestMapping annotation may specify a URI template to
access specific parts of the request URI. A URI template contains variable names (specified within
braces) whose values are derived from the actual request URI. For example, the URI template
http://www.somebank.com/fd/{fixeddeposit} contains the variable name fixeddeposit. If the request
actual request URI is http://www.somebank.com/fd/123, the value of {fixeddeposit} URI template
variablebecomes123.
@PathVariable is a method argument level annotation that is used by @RequestMapping methods to
assignvalueofaURItemplatevariabletothemethodargument.
IMPORTchapter 12/ch12-webservice-uritemplates and chapter 12/ch12-webservice-client-
uritemplates(ch12-webservice-uritemplatesprojectisavariantofch12-webserviceprojectthatshows
the implementation of FixedDepositWS RESTful web service using @PathVariable annotation. ch12-
webservice-client-uritemplatesisavariantofch12-webservice-clientthataccessestheFixedDepositWS
webservicerepresentedbych12-webservice-uritemplatesproject.)
The following example listing shows usage of @PathVariable annotation in FixedDepositController of
ch12-webservice-uritemplatesproject:
Examplelisting12-21–FixedDepositController-@PathVariableusage
Project–ch12-webservice-uritemplates
Sourcelocation-src/main/java/sample/spring/chapter12/web
packagesample.spring.chapter12.web;
importorg.springframework.web.bind.annotation.PathVariable;
.....
@Controller
publicclassFixedDepositController{
.....
@RequestMapping(value="/fixedDeposits/{fixedDepositId}",method=RequestMethod.GET)
publicResponseEntity<FixedDepositDetails>getFixedDeposit(
@PathVariable("fixedDepositId")intid){
returnnewResponseEntity<FixedDepositDetails>(
fixedDepositService.getFixedDeposit(id),HttpStatus.OK);
}
.....
}
InsteadofspecifyingtheactualURI,@RequestMappingannotationintheaboveexamplelistingspecifies
/fixedDeposits/{fixedDepositId}URItemplate.Now,iftheincomingrequestURIis/fixedDeposits/1,the
value of fixedDepositId URI template variable is set to 1. As the @PathVariable annotation specifies
fixedDepositIdasthename of the URI templatevariable,value1 is assigned totheidargument ofthe
getFixedDepositmethod.
If a URI template defines multiple variables, the @RequestMapping method can define multiple
@PathVariableannotatedarguments,asshowninthefollowingexamplelisting:
Examplelisting12-22–MultipleURItemplatevariables
@Controller
publicclassSomeController{
.....
@RequestMapping(value="/users/{userId}/bankstatements/{statementId}",.....)
publicvoidgetBankStatementForUser(
@PathVariable("userId")Stringuser,
@PathVariable("statementId")Stringstatement){
.....
}
}
Intheaboveexamplelisting,theURItemplatedefinesuserIdandstatementIdvariables.Iftheincoming
requestURIis/users/me/bankstatements/123,valuemeisassignedtotheuserargumentandvalue123is
assignedtothestatementargument.
IfyouwanttoassignalltheURItemplatevariablesandtheirvaluestoamethodargument,youcanuse
@PathVariableannotationonaMap<String,String>argument type,as shown inthefollowing example
listing:
Examplelisting12-23–AccessingallURItemplatevariablesandtheirvalues
@Controller
publicclassSomeController{
.....
@RequestMapping(value="/users/{userId}/bankstatements/{statementId}",.....)
publicvoidgetBankStatementForUser(
@PathVariableMap<String,String>allVariables){
.....
}
}
Intheaboveexamplelisting,URItemplatevariables(userIdandstatementId)andtheirvalues(meand
123)areassignedtotheallVariablesmethodargument.
YoushouldnotethatURItemplatecanalsobespecifiedbyclasslevel@RequestMappingannotation,as
shownhere:
Example listing 12-24 – URI template specified at both class and method level @RequestMapping
annotations
@Controller
@RequestMapping(value="/service/{serviceId}",.....)
publicclassSomeController{
.....
@RequestMapping(value="/users/{userId}/bankstatements/{statementId}",.....)
publicvoidgetBankStatementForUser(@PathVariableMap<String,String>allVariables){
.....
}
}
In the above example listing, URI template /service/{serviceId} is specified by the class level
@RequestMapping annotation, and /users/{userId}/bankstatements/{statementId} is specified by the
method level @RequestMapping annotation. If the request URI is
/service/bankingService/users/me/bankstatements/123, the allVariables argument contains details of
serviceId,userIdandstatementIdURItemplatevariables.
Thescenariosinwhichyoumaywanttohavefine-grainedcontroloverwhattoextractfromtherequest
URI,you canuse regular expressions in URItemplates. The following example listingshows usageof
regularexpressionstoextract123.jsonvaluefrom/statements/123.jsonrequestURI:
Examplelisting12-25–URItemplates–regularexpressionsusage
@Controller
publicclassSomeController{
.....
@RequestMapping(value="/bankestatement/{statementId:[\\d\\d\\d]}.{responseType:[a-z]}",..)
publicvoidgetBankStatementForUser(@PathVariable("statementId")Stringstatement,
@PathVariable("responseType")StringresponseTypeExtension){
.....
}
}
Regular expressions in URI templates are specified in the following format: {variable-name:regular-
expression}.IftherequestURIis/statements/123.json,statementIdvariableisassignedthevalue123and
responseTypeisassignedthevaluejson.
NOTEYoucanalsouseAnt-stylepatternsinURItemplates.Forinstance,youcanspecifypatterns,like
/myUrl/*/{myId}and/myUrl/**/{myId}asURItemplates.
So far in this section we have seen examples of how to use @PathVariable to selectively extract
information from the request URI path. Lets now look at @MatrixVariable annotation that is used to
extractname-valuepairsfrompathsegments.
Matrix variables appear as name-value pairs in the request URI, and you can assign value of these
variablestomethodarguments.Forinstance,intherequestURI/bankstatement/123;responseType=json,
theresponseTypevariablerepresentsamatrixvariablewhosevalueisjson.
NOTE You should note that by default Springremoves matrix variables from the URL. To ensure that
matrix variables are not removed, set the enable-matrix-variables attribute of <annotation-driven>
elementofSpringmvcschematotrue.Whenusingmatrixvariables,thepathsegmentsthatcontainmatrix
variablesmustberepresentedbyURItemplatevariables.
Thefollowingexamplelistingshowsusageof@MatrixVariableannotation:
Examplelisting12-26–@MatrixVariableannotation
@Controller
publicclassSomeController{
.....
@RequestMapping(value="/bankestatement/{statementId}",..)
publicvoidgetBankStatementForUser(@PathVariable("statementId")Stringstatement,
@MatrixVariable("responseType")StringresponseTypeExtension){
.....
}
}
Intheaboveexamplelisting,iftherequestURIis/bankstatement/123;responseType=json,thevaluejson
is assigned to responseTypeExtension argument. The above example listing also shows a scenario in
which both @PathVariable and @MatrixVariable annotations are used to retrieve information from the
requestURI.
As matrix variables can appear in any path segment of the request URI, you should specify the path
segment from which the matrix variable should be retrieved. The following example listing shows a
scenarioinwhichtwomatrixvariableswiththesamenamearepresentindifferentpathsegments:
Examplelisting12-27–@MatrixVariableannotation–multiplematrixvariableswiththesamename
@Controller
publicclassSomeController{
.....
@RequestMapping(value="/bankestatement/{statementId}/user/{userId}",..)
publicvoidgetBankStatementForUser(
@MatrixVariable(value="id",pathVar="statementId")intsomeId,
@MatrixVariable(value="id",pathVar="userId")intsomeOtherId){
.....
}
}
ThepathVarattributeof@MatrixVariableannotationspecifiesthenameoftheURItemplatevariablethat
contains the matrix variable. So, if the request URI is /bankstatement/123;id=555/user/me;id=777, the
value555isassignedtosomeId,andthevalue777isassignedtosomeOtherIdargument.
Asincaseof@PathVariableannotation,youcanannotateamethodargumenttypeofMap<String,String>
with@MatrixVariabletoassignallthematrixvariablestothemethodargument.Unlike@PathVariable
annotation, @MatrixVariable annotation allows you to specify a default value for the matrix variable
usingdefaultValueattribute.Also,youcansetrequiredattributeof@MatrixVariableannotationtofalseto
indicatethatthematrixvariableisoptional.Bydefault,thevalueofrequiredattributeissettotrue.Ifthe
requiredattributeissettotrue,andthematrixvariableisnotfoundintherequest,thenanexceptionis
thrown.
12-7Summary
Inthischapter,welookedathowtodevelopRESTfulwebservicesandaccessthem.Welookedathow
touseURItemplatesalongwith@PathVariableand@MatrixVariableannotationstoaccessinformation
from the request URI. We also looked at how to access RESTful web services synchronously using
RestTemplateandasynchronouslyusingAsyncRestTemplate.
Chapter13–MoreSpringWebMVC–internationalization,
fileuploadandasynchronousrequestprocessing
13-1Introduction
Inearlierchapters,wesawthatSpringWebMVCsimplifiescreatingwebapplicationsandRESTfulweb
services.Inthischapter,welllookatsomemorefeaturesofferedbySpringWebMVCframeworkthat
youmayrequireinyourwebapplications.Wellparticularlylookat:
§pre-andpost-processingrequestsusinghandlerinterceptors
§internationalizingSpringWebMVCapplications
§asynchronouslyprocessingrequests
§performingtypeconversionandformatting,and
§uploadingfiles
IMPORTchapter13/ch13-bankapp(Thisprojectisavariantofch10-bankappprojectthatdemonstrates
howtoincorporateinternationalizationinMyBankwebapplication,andhowtousehandlerinterceptors.)
Letsbeginbylookingathowtopre-andpost-processrequestsusinghandlerinterceptors.
13-2Pre-andpost-processingrequestsusinghandlerinterceptors
Handlerinterceptorsallowyoutopre-andpost-processrequests.Theconceptofhandlerinterceptorsis
similartothatofservletfilters.HandlerinterceptorsimplementSpringsHandlerInterceptorinterface.A
handlerinterceptor containsthepre- and post-processing logicthatisrequired bymultiplecontrollers.
Forinstance,youcanusehandlerinterceptorsforlogging,securitychecks,changinglocale,andsoon.
Letsnowlookathowtoimplementandconfigurehandlerinterceptors.
Implementingandconfiguringahandlerinterceptor
You can create handler interceptors by implementing HandlerInterceptor interface. HandlerInterceptor
interfacedefinesthefollowingmethods:
§preHandle–thismethodisexecutedbeforethecontrollerprocessestherequest.IfthepreHandle
method returns true, the controller is invoked by Spring to process the request. If the preHandle
methodreturnsfalse,thecontrollerisnotinvoked.
§postHandle–thismethodisexecutedafterthecontrollerprocessestherequest,butbeforetheview
isrenderedbytheDispatcherServlet.
§afterCompletion–thismethodisinvokedafterthecompletionofrequestprocessing(thatis,after
theviewisrenderedbytheDispatcherServlet)todoanycleanup,ifrequired.
The following example listing shows MyRequestHandlerInterceptor class of ch13-bankapp that
implementsHandlerInterceptorinterface:
Examplelisting13-1–MyRequestHandlerInterceptor
Project–ch13-bankapp
Sourcelocation-src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
importorg.springframework.web.servlet.HandlerInterceptor;
.....
publicclassMyRequestHandlerInterceptorimplementsHandlerInterceptor{
.....
publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,
Objecthandler)throwsException{
logger.info("HTTPmethod-->"+request.getMethod());
Enumeration<String>requestNames=request.getParameterNames();
.....
returntrue;
}
publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,
Objecthandler,ModelAndViewmodelAndView)throwsException{
logger.info("Statuscode-->"+response.getStatus());
}
publicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,
Objecthandler,Exceptionex)throwsException{
logger.info("Requestprocessingcomplete");
}
}
Intheaboveexamplelisting,thepreHandlemethodinspectseachincomingrequestandlogstheHTTP
methodassociatedwiththerequestandtherequestparameterscontainedintherequest.ThepreHandle
methodreturnstrue,which means thatthe requestwill be processed by thecontroller.The postHandle
method logs the HTTP response status code. The afterCompletion method logs the message that the
requestwassuccessfullyprocessed.
NOTE Instead of directly implementing the HandlerInterceptor interface, you can extend theabstract
HandlerInterceptorAdapter class that provides empty implementations for postHandle and
afterCompletionmethods,andthepreHandlemethodisdefinedtosimplyreturntrue.
The following example listing shows how handler interceptors are configured in the web application
contextXMLfile:
Examplelisting13-2–MyRequestHandlerInterceptor
Project–ch13-bankapp
Sourcelocation-src/main/webapp/WEB-INF/spring/bankapp-config.xml
<beans.....xmlns:mvc="http://www.springframework.org/schema/mvc".....>
<mvc:annotation-driven/>
<mvc:interceptors>
.....
<beanclass="sample.spring.chapter13.web.MyRequestHandlerInterceptor"/>
</mvc:interceptors>
</beans>
The above example listing shows that the <interceptors> element of Springs mvc schema is used for
configuringhandlerinterceptors.The<interceptors>elementcanhavethefollowingsub-elements:
§  <bean> element of Springs beans schema - specifies a Spring bean that implements the
HandlerInterceptor interface. A handler interceptor defined using <bean> element applies to all
requests.
§  <ref> element of Springs beans schema - refers to a Spring bean that implements the
HandlerInterceptor interface. A handler interceptor defined using <ref> element applies to all
requests.
§ <interceptor> element of Springs mvc schema – specifies a Spring bean that implements the
HandlerInterceptorinterface,andtherequestURIstowhichtheHandlerInterceptorapplies.
The following example listing shows a scenario in which MyRequestHandlerInterceptor is mapped to
/audit/**requestURI:
Examplelisting13-3–<mvc:interceptor>usage
<beans.....xmlns:mvc="http://www.springframework.org/schema/mvc".....>
<mvc:annotation-driven/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mappingpath="/audit/**"/>
<beanclass="sample.spring.chapter13.web.MyRequestHandlerInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
In the above example listing, <interceptor> element of Springs mvc schema is used for mapping
MyRequestHandlerInterceptorto/audit/**URIpattern.The<mapping>elementofSpringsmvcschema
specifies the request URI pattern to which the handler interceptor specified by the <bean> element
applies.
LetsnowlookathowtointernationalizeaSpringWebMVCapplication.
13-3Internationalizingusingresourcebundles
BeforedelvingintothedetailsofhowtointernationalizeSpringWebMVCapplications,letslookatthe
internationalizationandlocalizationrequirementsoftheMyBankwebapplication.
MyBankwebapplication’srequirements
It is required that the MyBank web application supports English (en_US locale) and German (de_DE
locale) languages. The following figure shows one of the web pages of MyBank web application in
de_DElocale:
Figure13-1Webpagethatshowsthelistoffixeddepositsinde_DElocale.Ausercanselectalocale
fromthegivenoptions.
Theabovefigureshowsthatausercanchooseoneofthefollowinglanguages:English(US),German,or
English(Canada). If a user chooses German language option, the web pages are displayed in de_DE
locale.IfauserchoosesEnglish(US)languageoption,thewebpagesaredisplayedinen_USlocale.Ifa
userchoosesEnglish(Canada)languageoption,thewebpagesaredisplayedinen_CAlocale.
Lets now look at how to address internationalization and localization requirements of MyBank web
application.
InternationalizingandlocalizingMyBankwebapplication
InSpringWebMVC,theDispatcherServletusesaLocaleResolverforautomaticallyresolvingmessages
basedontheuserslocale.Tosupportinternationalization,youneedtoconfigurethefollowingbeansin
yourwebapplicationcontextXMLfile:
·LocaleResolver–resolvesthecurrentlocaleoftheuser
·MessageSource–resolvesmessagesfromresourcebundlesbasedonthecurrentlocaleofthe
user
·        LocaleChangeInterceptor – allows changing current locale on every request based on a
configurablerequestparameter
The following example listing shows configuration of LocaleResolver, LocaleChangeInterceptor and
MessageSourcebeansinthewebapplicationcontextXMLfileofch13-bankappproject:
Examplelisting13-4–bankapp-config.xml
Project–ch13-bankapp
Sourcelocation-src/main/webapp/WEB-INF/spring
<beans.....>
<beanclass="org.springframework.web.servlet.i18n.CookieLocaleResolver"id="localeResolver">
<propertyname="cookieName"value="mylocale"/>
</bean>
<bean
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
id="messageSource">
<propertyname="basenames"value="WEB-INF/i18n/messages"/>
</bean>
<mvc:interceptors>
.....
<beanclass="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<propertyname="paramName"value="lang"/>
</bean>
</mvc:interceptors>
.....
</beans>
Intheaboveexamplelisting,CookieLocaleResolver(animplementationofLocaleResolverinterface)has
been configured for locale resolution. If the locale information is stored in a cookie by the web
application,CookieLocaleResolverisusedforlocaleresolution.CookieLocaleResolvers cookieName
propertyspecifiesthenameofthecookiethatcontainsthelocaleinformation.Ifthecookieisnotfoundin
the request, CookieLocaleResolver determines the locale either by looking at the default locale
(configured using defaultLocale property of CookieLocaleResolver) or by inspecting the Accept-
Language request header. Spring additionally provides the following built-in LocaleResolver
implementations that you can use: AcceptHeaderLocaleResolver (returns the locale specified by the
Accept-Language requestheader), SessionLocaleResolver (returns the locale information stored in the
HttpSessionoftheuser)andFixedLocaleResolver(alwaysreturnsafixeddefaultlocale).
Inadditiontoknowinguserslocale,youmayalsowanttoknowuserstimezonetoconvertdateandtime
in users time zone. LocaleContextResolver (introduced in Spring 4.0) not only provides the locale
information but also the time zone information of the user. CookieLocaleResolver,
SessionLocaleResolver and FixedLocaleResolver implement the LocaleContextResolver interface;
therefore,ifyouareusinganyoftheseresolversyoucanobtainuserstimezoneinyourcontrollersusing
getTimeZonemethodofLocaleContextHolder(orRequestContextUtils)class.Ifyouonlywanttoobtain
the locale information in your controllers, you can use getLocale method of LocaleContextHolder (or
RequestContextUtils)class.
Spring provides a LocaleChangeInterceptor (a HandlerInterceptor) that uses a configurable request
parameter(specifiedbyparamNameproperty)tochangethecurrentlocaleoneveryrequest.Inexample
listing13-4,theparamNamepropertyissettolang.LocaleResolverdefinesasetLocalemethodthatis
used by the LocaleChangeInterceptor to change the current locale. If you dont want to use
LocaleChangeInterceptor, thenyou can changetheusers localein your controller bycalling setLocale
methodofLocaleContextHolder(orRequestContextUtils)class.
Oncetheuserslocaleisresolved,SpringusestheconfiguredMessageSourceimplementationtoresolve
messages.Springprovidesthefollowingbuilt-inimplementationsofMessageSourceinterface:
§ResourceBundleMessageSource–aMessageSourceimplementationthataccessesresourcebundles
usingthespecifiedbasenames
§  ReloadableResourceBundleMessageSource – similar to ResourceBundleMessageSource
implementation.Thisimplementationsupportsreloadingofresourcebundles.
Example listing 13-4 shows that the MyBank web application uses
ReloadableResourceBundleMessageSource.ThebasenamespropertyissettoWEB-INF/i18n/messages,
which means that the ReloadableResourceBundleMessageSource looks for resource bundles named
messages inside WEB-INF/i18n folder. So, if the users locale is resolved to en_US, the
ReloadableResourceBundleMessageSource willresolve messages from the messages_en_US.properties
file.
Ifyoulookat/src/main/webapp/WEB-INF/i18nfolderofch13-bankappproject,youllfindthefollowing
propertiesfiles:messages.properties,messages_en_US.propertiesandmessages_de_DE.properties.The
messages_de_DE.properties file contains messages and labels for de_DE locale,
messages_en_US.properties contains messages and labels for en_US locale, and messages.properties
contains messages and labels that are shown whenno locale-specific resource bundles are found. As
there is no messages_en_CA.properties file corresponding to en_CA locale, selecting the
English(Canada)option(referfigure13-1)showsmessagesfromthemessages.propertiesfile.
In figure 13-1, we saw that we can change the language of the MyBank web application by selecting
English(US), English(Canada) and German language options. We saw earlier that the
LocaleChangeInterceptorcanchangethelocaleoftheMyBankwebapplicationifthelocaleinformation
iscontainedinarequestparameternamedlang.Tosimplifychangingthelocale,langrequestparameteris
appended to the hyperlinks shown by English(US), English(Canada) and German language options, as
shownhere:
Examplelisting13-5–fixedDepositList.jsp
Project–ch13-bankapp
Sourcelocation-src/main/webapp/WEB-INF/jsp
<b>Language:</b>
<ahref="${pageContext.request.contextPath}/fixedDeposit/list?lang=en_US">English(US)</a>|
<ahref="${pageContext.request.contextPath}/fixedDeposit/list?lang=de_DE">German</a>|
<ahref="${pageContext.request.contextPath}/fixedDeposit/list?lang=en_CA">English(Canada)</a>
LetsnowlookathowyoucanasynchronouslyprocessrequestsinSpringWebMVCapplications.
13-4Asynchronouslyprocessingrequests
A @RequestMapping annotated method that returns a java.util.concurrent.Callable or Springs
DeferredResult object processes web requests asynchronously. If a @RequestMapping method returns
Callable,SpringWebMVCtakescareofprocessingtheCallableinanapplicationthread(andnot the
Servletcontainerthread)toproducetheresult.Ifa@RequestMappingmethodreturnsDeferredResult,it
isapplicationsresponsibilitytoprocesstheDeferredResultinanapplicationthread(andnottheServlet
containerthread)toproducetheresult.BeforedelvingintothedetailofhowCallableandDeferredResult
return values are processed, lets look at how to configure a Spring Web MVC application to support
asynchronousrequestprocessing.
IMPORTchapter 13/ch13-async-bankapp(This project is a variant of ch10-bankapp project that
asynchronouslyprocessesrequests.@RequestMappingmethodsdefinedintheFixedDepositControllerof
this project return Callable. You should deploy and run the ch13-async-bankapp project to see
asynchronousrequestprocessinginaction.)
Asynchronousrequestprocessingconfiguration
AsasynchronousrequestprocessinginSpringWebMVCisbasedonServlet3,web.xml mustrefer to
Servlet 3 XML schema. Also, <async-supported> element must be added to the DispatcherServlet
definition in web.xml file to indicate that it supports asynchronous request processing. The following
examplelistingshowstheweb.xmlfileofch13-async-bankappproject:
Examplelisting13-6–web.xml–asynchronousrequestprocessingconfiguration
Project–ch13-async-bankapp
Sourcelocation-src/main/webapp/WEB-INF
<web-app.....
xsi:schemaLocation="java.sun.com/xml/ns/javaeejava.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
.....
<servlet>
<servlet-name>bankapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
.....
<async-supported>true</async-supported>
</servlet>
.....
</web-app>
Theaboveexamplelistingshowsthatthebankappservletisconfiguredtosupportasynchronousrequest
processing.Now,thebankappservletcanasynchronouslyprocesswebrequests.
ReturningCallablefrom@RequestMappingmethods
The following example listing shows the FixedDepositController whose @RequestMapping methods
returnCallable:
Examplelisting13-7–FixedDepositController–returningCallablefrom@RequestMappingmethods
Project–ch13-async-bankapp
Sourcelocation-src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
importjava.util.concurrent.Callable;
.....
publicclassFixedDepositController{
.....
@RequestMapping(value="/list",method=RequestMethod.GET)
publicCallable<ModelAndView>listFixedDeposits(){
returnnewCallable<ModelAndView>(){
@Override
publicModelAndViewcall()throwsException{
Thread.sleep(5000);
Map<String,List<FixedDepositDetails>>modelData=
newHashMap<String,List<FixedDepositDetails>>();
modelData.put("fdList",fixedDepositService.getFixedDeposits());
returnnewModelAndView("fixedDepositList",modelData);
}
};
}
.....
}
TheaboveexamplelistingshowsthatthelistFixedDepositsmethodreturnsaCallable<T>object,where
Tisthetypeoftheresultthatisasynchronouslycomputed.TheCallable’scallmethodcontainsthelogic
that needs to be executed asynchronously to produce the result. The call method shown in the above
examplelistinginvokesFixedDepositServicesgetFixedDepositsmethod,andreturnsaModelAndView
objectcontainingthemodelandviewinformation.TheThread.sleepmethodisinvokedinthebeginning
ofcallmethodtosimulateascenarioinwhichtherequestprocessingtakestime.
If an exception is thrown during the execution of the Callable returned from the controller, the
@ExceptionHandler method (or the configured HandlerExceptionResolver bean) of the controller is
responsibleforhandlingtheexception.Formoreinformationon@ExceptionHandlerannotation,referto
section10-9ofchapter10.
Examplelisting13-7showsthatifyouwanttoswitchfromsynchronousrequestprocessingapproachto
asynchronousrequestprocessing,youneedtomovethelogicfromthe@RequestMappingmethodtothe
callmethodofCallable,andchangethereturntypeofthe@RequestMappingmethodtoCallable<T>.
Letsnowlookathowrequestsareasynchronouslyprocessedwhena@RequestMappingmethodreturns
aDeferredResultobject.
IMPORTchapter 13/ch13-async-webserviceand ch13-async-webservice-client(The ch13-async-
webservice project is a variant of FixedDepositWS web service (refer ch12-webservice project of
chapter12)thatasynchronouslyprocesseswebservicerequests.@RequestMappingmethodsdefinedin
theFixedDepositControllerofthisprojectreturnaninstanceofDeferredResultobject.Thech13-async-
webservice-client project is same as the FixedDepositWS web service client (refer ch12-webservice-
clientprojectofchapter12)thatassumesthatthewebserviceisdeployedathttp://localhost:8080/ch13-
async-webservice.)
ReturningDeferredResultfrom@RequestMappingmethods
ADeferredResultinstancerepresentsaresultthatisasynchronouslycomputed.Yousettheresultonthe
DeferredResultinstancebycallingitssetResultmethod.Typically,a@RequestMappingmethodstoresa
DeferredResult instance in a Queue or a Map or any other data structure, and a separate thread is
responsibleforcomputingtheresultandsettingtheresultontheDeferredResultinstance.
Letsfirstlookat@RequestMappingmethodsthatreturnDeferredResulttype.
@RequestMappingmethodimplementation
The following example listing shows the FixedDepositController whose @RequestMapping methods
returnDeferredResultobjects:
Example listing 13-8 – FixedDepositController – returning DeferredResult from @RequestMapping
methods
Project–ch13-async-webservice
Sourcelocation-src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
importjava.util.Queue;
importjava.util.concurrent.ConcurrentLinkedQueue;
importorg.springframework.web.context.request.async.DeferredResult;
.....
@Controller
@RequestMapping(value="/fixedDeposits")
publicclassFixedDepositController{
privatestaticfinalStringLIST_METHOD="getFixedDepositList";
privatestaticfinalStringGET_FD_METHOD="getFixedDeposit";
.....
privatefinalQueue<ResultContext>deferredResultQueue=
newConcurrentLinkedQueue<ResultContext>();
.....
@RequestMapping(method=RequestMethod.GET)
publicDeferredResult<ResponseEntity<List<FixedDepositDetails>>>getFixedDepositList(){
DeferredResult<ResponseEntity<List<FixedDepositDetails>>>dr=
newDeferredResult<ResponseEntity<List<FixedDepositDetails>>>();
ResultContext<ResponseEntity<List<FixedDepositDetails>>>resultContext=
newResultContext<ResponseEntity<List<FixedDepositDetails>>>();
resultContext.setDeferredResult(dr);
resultContext.setMethodToInvoke(LIST_METHOD);
resultContext.setArgs(newHashMap<String,Object>());
deferredResultQueue.add(resultContext);
returndr;
}
.....
}
Each@RequestMappingmethodofFixedDepositControllerperformsthesesteps:
Step1-createsaninstanceofDeferredResult<T>object,whereTrepresentsthetypeoftheresultthatis
asynchronously computed. As the type of the result computed for the getFixedDepositList method is
ResponseEntity<List<FixedDepositDetails>>, an instance of
DeferredResult<ResponseEntity<List<FixedDepositDetails>>>iscreated.
Step2-createsaninstanceofResultContextobject.ResultContextobjectholdsDeferredResultinstance
thatwecreatedinStep1,andotherdetailsthatarerequiredtoasynchronouslycomputetheresultforthe
DeferredResult object. In case of FixedDepositController’s getFixedDepositList method, result is
representedbythelist offixeddeposits obtainedbyinvokingFixedDepositServices getFixedDeposits
method.
ThefollowingexamplelistingshowstheResultContextclass:
Examplelisting13-9–ResultContextclassforstoringDeferredResultandotherinformation
Project–ch13-async-webservice
Sourcelocation-src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
importjava.util.Map;
importorg.springframework.web.context.request.async.DeferredResult;
publicclassResultContext<T>{
privateStringmethodToInvoke;
privateDeferredResult<T>deferredResult;
privateMap<String,Object>args;

publicvoidsetDeferredResult(DeferredResult<T>deferredResult){
this.deferredResult=deferredResult;
}
.....
}
The deferredResult property refers to an instance of DeferredResult, the methodToInvoke property
specifies the name of the FixedDepositService method that is invoked to compute the result for the
DeferredResultobject,andargsproperty(oftypejava.util.Map)specifiestheargumentstobepassedto
the FixedDepositService method. A separate thread (as explained later in this section) uses the
methodToInvokeand args properties to invoke the specified FixedDepositService method, and sets the
returnedresultontheDeferredResultinstance.
AstheLIST_METHOD,GET_FD_METHOD,andsoon,constantsintheFixedDepositControllerclass
refertothenamesoftheFixedDepositServicemethods(referexamplelisting13-8),themethodToInvoke
property is set to the one of these constants. In example listing 13-8, FixedDepositController’s
getFixedDepositListmethodsetsthemethodToInvokepropertytoLIST_METHODconstant(whosevalue
is getFixedDeposits) because FixedDepositService’s getFixedDeposits method needs to be invoked to
obtaintheresultfortheDeferredResultobjectreturnedbyFixedDepositControllersgetFixedDepositList
method.
Step3-storestheResultContextinstancecreatedinStep2intoaQueue(refertodeferredResultQueue
instancevariableinexamplelisting13-8)
Step4-returnstheDeferredResultobjectcreatedinStep1
TheabovesequenceofstepssuggeststhatforeachwebrequestaninstanceofResultContextisstoredin
the deferredResultQueue. The following figure summarizes the actions that are performed by
FixedDepositController’sgetFixedDepositListmethod.
Figure 13-2 FixedDepositControllers getFixedDepositList method adds a ResultContext object to the
queueandreturnsaDeferredResultobject
Lets now look at how the result is computed for the DeferredResult instance contained inside the
ResultContextobject.
ComputingresultforaDeferredResultinstance
FixedDepositController’s processResults method is responsible for iterating over the ResultContext
objects stored in the deferredResultQueue (refer example listing 13-8), computing the result for each
DeferredResultobject,andsettingtheresultontheDeferredResultobject.Thefollowingexamplelisting
showstheprocessResultsmethod:
Example listing 13-10 – processResults method – computing and setting results on DeferredResult
objects
Project–ch13-async-webservice
Sourcelocation-src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
importorg.springframework.scheduling.annotation.Scheduled;
importorg.springframework.web.context.request.async.DeferredResult;
@Controller
@RequestMapping(value="/fixedDeposits")
publicclassFixedDepositController{
privatestaticfinalStringLIST_METHOD="getFixedDepositList";
.....
privatefinalQueue<ResultContext>deferredResultQueue=
newConcurrentLinkedQueue<ResultContext>();
@Autowired
privateFixedDepositServicefixedDepositService;
.....
@Scheduled(fixedRate=10000)
publicvoidprocessResults(){
for(ResultContextresultContext:deferredResultQueue){
if(resultContext.getMethodToInvoke()==LIST_METHOD){
resultContext.getDeferredResult().setResult(
newResponseEntity<List<FixedDepositDetails>>(
fixedDepositService.getFixedDeposits(),HttpStatus.OK));
}
.....
deferredResultQueue.remove(resultContext);
}
}
}
@Scheduled annotation (refer section 8-6 of chapter 8 for more details) on processResults method
specifies that every 10 seconds an application thread is responsible for executing the processResults
method. The processResults method uses the method name and argument information stored in the
ResultContext instance to invoke the appropriate FixedDepositServices method. The processResults
methodthensetstheresultontheDeferredResultinstancebycallingitssetResultmethod.Intheend,the
processResults method removes the ResultContext instance from the Queue. After processing a
ResultContextinstance,theprocessResultsmethodremovestheResultContextinstancefromtheQueueso
thatitisnotre-processedbytheprocessResultsmethodwhenitexecutesagainafter10seconds.
Figure 13-3 summarizes the actions performed by FixedDepositControllers processResults method to
computetheresultandsetitontheDeferredResultinstance.
Figure 13-3 The processResults method reads method name and argument information from the
ResultContextobjecttocomputetheresultfortheDeferredResultinstance
Lets now look at how exceptions are handled when a @RequestMapping method returns a
DeferredResultinstance.
ExceptionHandling
Ifyousetanobjectoftypejava.lang.ExceptionusingDeferredResult’ssetErrorResultmethod,theresult
is handled by @ExceptionHandler annotated method of the controller (or by the configured
HandlerExceptionResolver bean). For more information on @ExceptionHandler annotation, refer to
section10-9ofchapter10.
The following example listing shows FixedDepositControllersopenFixedDeposit method that opens a
newfixeddeposit:
Examplelisting13-11–FixedDepositController’sopenFixedDepositmethod
Project–ch13-async-webservice
Sourcelocation-src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
@Controller
@RequestMapping(value="/fixedDeposits")
publicclassFixedDepositController{
privatestaticfinalStringOPEN_FD_METHOD="openFixedDeposit";
.....
privatefinalQueue<ResultContext>deferredResultQueue=
newConcurrentLinkedQueue<ResultContext>();
@RequestMapping(method=RequestMethod.POST)
publicDeferredResult<ResponseEntity<FixedDepositDetails>>openFixedDeposit(
@RequestBodyFixedDepositDetailsfixedDepositDetails,BindingResultbindingResult){
DeferredResult<ResponseEntity<FixedDepositDetails>>dr=
newDeferredResult<ResponseEntity<FixedDepositDetails>>();
ResultContext<ResponseEntity<FixedDepositDetails>>resultContext=
newResultContext<ResponseEntity<FixedDepositDetails>>();
resultContext.setDeferredResult(dr);
resultContext.setMethodToInvoke(OPEN_FD_METHOD);
Map<String,Object>args=newHashMap<String,Object>();
args.put("fixedDepositDetails",fixedDepositDetails);
args.put("bindingResult",bindingResult);
resultContext.setArgs(args);
deferredResultQueue.add(resultContext);
returndr;
}
.....
}
Theaboveexamplelistingshowsthatthearguments(fixedDepositDetailsandbindingResult)passedto
theopenFixedDepositmethodaresetontheResultContextinstancesothattheseargumentsareavailable
when the processResults method executes the logic for opening a new fixed deposit. The
fixedDepositDetailsargumentcontainsthedetailsofthefixeddeposittobeopenedandthebindingResult
argumentcontainstheresultsofdatabinding.
The following example listing shows how the processResults method executes the logic for opening a
newfixeddeposit:
Examplelisting13-12–FixedDepositControllersprocessResultsmethod
Project–ch13-async-webservice
Sourcelocation-src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
@Controller
@RequestMapping(value="/fixedDeposits")
publicclassFixedDepositController{
privatestaticfinalStringOPEN_FD_METHOD="openFixedDeposit";
.....
privatefinalQueue<ResultContext>deferredResultQueue=
newConcurrentLinkedQueue<ResultContext>();
@Autowired
privateFixedDepositServicefixedDepositService;
.....
@ExceptionHandler(ValidationException.class)
@ResponseBody
@ResponseStatus(value=HttpStatus.BAD_REQUEST)
publicStringhandleException(Exceptionex){
logger.info("handlingValidationException"+ex.getMessage());
returnex.getMessage();
}
@Scheduled(fixedRate=10000)
publicvoidprocessResults(){
for(ResultContextresultContext:deferredResultQueue){
.....
if(resultContext.getMethodToInvoke()==OPEN_FD_METHOD){
FixedDepositDetailsfixedDepositDetails=(FixedDepositDetails)resultContext
.getArgs().get("fixedDepositDetails");
BindingResultbindingResult=(BindingResult)resultContext.getArgs().get("bindingResult");
newFixedDepositDetailsValidator().validate(fixedDepositDetails,bindingResult);
if(bindingResult.hasErrors()){
logger.info("openFixedDeposit()method:Validationerrorsoccurred");
resultContext.getDeferredResult().setErrorResult(newValidationException(
"Validationerrorsoccurred"));
}else{
fixedDepositService.saveFixedDeposit(fixedDepositDetails);
resultContext.getDeferredResult().setResult(newResponseEntity<FixedDepositDetails>(
fixedDepositDetails,HttpStatus.CREATED));
}
}
.....
}
}
}
Theaboveexamplelistingshowsthe@ExceptionHandlerannotatedhandleExceptionmethodthathandles
exceptionsoftypeValidationException.ThehandleExceptionmethodlogsthatavalidationexceptionhas
occurredandreturnstheexceptionmessage.
To open a new fixed deposit, the processResults method retrieves the fixedDepositDetails (of type
FixedDepositDetails) and bindingResult (of type BindingResult) arguments from the ResultContext and
validates the fixedDepositDetails object by calling FixedDepositValidators validate method. If
validation errors are reported, the processResults method invokes DeferredResult’s setErrorResult
method to set ValidationException (of type java.lang.Exception) as the result. Setting the
ValidationExceptionusingDeferredResultssetErrorResult method will cause handling of the result by
FixedDepositControllershandleExceptionmethod.
It is recommended that you deploy the ch13-async-webservice project (which represents the
FixedDepositWS RESTful web service) and access it by running the main method of
FixedDepositWSClient of ch13-async-webservice-client project (which represents a client of
FixedDepositWSRESTfulwebservice).TheFixedDepositWSClient’sopenInvalidFixedDepositmethod
invokes FixedDepositControllers openFixedDeposit web service method such that it results in
ValidationException.YoucancheckthelogstoverifythattheFixedDepositController’shandleException
methodhandles the resultwhen processResultsmethodsets ValidationException on the DeferredResult
objectbycallingDeferredResultssetErrorResultmethod.
Letsnowlookathowtosetdefaulttimeoutvalueforasynchronousrequests.
Settingdefaulttimeoutvalue
You can set the default timeout value of asynchronous requests by using default-timeout attribute of
<async-support>element,asshownhere:
Examplelisting13-13–Settingdefaulttimeoutforasynchronousrequests
Project–ch13-async-webservice
Sourcelocation–src/main/webapp/WEB-INF/spring/webservice-config.xml
<mvc:annotation-driven>
<mvc:async-supportdefault-timeout="10000">
.....
</mvc:async-support>
</mvc:annotation-driven>
Intheaboveexamplelisting,defaulttimeoutforasynchronousrequestsissetto10seconds.Ifyoudont
specify the default timeout, the timeout for asynchronous requests depends on the Servlet container on
whichyoudeployedyourwebapplication.
LetsnowlookathowyoucaninterceptasynchronousrequestsusingCallableProcessingInterceptorand
DeferredResultProcessingInterceptor.
Interceptingasynchronousrequests
IfyouareusingCallabletoasynchronouslyprocessrequests,youcanuseCallableProcessingInterceptor
callbackinterfacetointerceptrequestsbeforeandaftertheCallable taskisexecuted.For instance,the
postProcessmethodisexecutedaftertheCallablehasproducedtheresult,andthepreProcessmethodis
called before the Callable task is executed. Similarly, if you are using DeferredResult, you can use
DeferredResultProcessingInterceptorcallbackinterfacetointerceptprocessingofasynchronousrequests.
YoucanconfigureaCallableProcessingInterceptorusing<callable-interceptors>elementofSpringsmvc
schema. And, you can configure a DeferredResultProcessingInterceptor using <deferred-result-
interceptors> element of Springs mvc schema. The following example listing shows configuration of
MyDeferredResultInterceptor(aDeferredResultProcessingInterceptorimplementation):
Examplelisting13-14–ConfiguringaDeferredResultProcessingInterceptorimplementation
Project–ch13-async-webservice
Sourcelocation–src/main/webapp/WEB-INF/spring/webservice-config.xml
<mvc:annotation-driven>
<mvc:async-supportdefault-timeout="30000">
<mvc:deferred-result-interceptors>
<beanclass="sample.spring.chapter13.web.MyDeferredResultInterceptor"/>
</mvc:deferred-result-interceptors>
</mvc:async-support>
</mvc:annotation-driven>
LetsnowlookatSpringssupportfortypeconversionandformatting.
13-5TypeconversionandformattingsupportinSpring
SpringsConverter interface simplifies converting an object type to another object type. And, Springs
Formatter interface is useful when converting an object type to its localizedString representation, and
vice versa. You can find a number of built-in Converter implementations in the
org.springframework.core.convert.supportpackageofspring-coreJARfile.Springalsoprovidesbuilt-in
Formatters for java.lang.Number and java.util.Date types that you can find in
org.springframework.format.numberandorg.springframework.format.datetimepackages,respectively.
IMPORTchapter 13/ch13-converter-formatter-bankapp(This project is a variant of ch13-bankapp
projectthatshowshowtocreatecustomConvertersandFormatters)
LetsfirstlookathowtocreateacustomConverter.
CreatingacustomConverter
AconverterimplementsSpringsConverter<S,T>interface,whereS(referredtoasthesourcetype)is
thetypeoftheobjectgiventotheconverter,andT(referredtoasthetargettype)isthetypeoftheobject
towhichSisconvertedbytheconverter.Converterinterfacedefinesaconvertmethodthatprovidesthe
conversionlogic.
The following example listing shows the IdToFixedDepositDetailsConverter that converts an object of
typeString(representingthefixeddepositID)toanobjectoftypeFixedDepositDetails(representingthe
fixeddepositcorrespondingtothefixeddepositID):
Examplelisting13-15–Converterimplementation
Project–ch13-converter-formatter-bankapp
Sourcelocation–src/main/java/sample/spring/chapter13/converter
packagesample.spring.chapter13.converter;
importorg.springframework.core.convert.converter.Converter;
.....
publicclassIdToFixedDepositDetailsConverterimplementsConverter<String,FixedDepositDetails>{
@Autowired
privateFixedDepositServicefixedDepositService;
@Override
publicFixedDepositDetailsconvert(Stringsource){
returnfixedDepositService.getFixedDeposit(Integer.parseInt(source));
}
}
IdToFixedDepositDetailsConverterimplementsConverter<String,FixedDepositDetails>interface,where
StringisthesourcetypeandFixedDepositDetailsisthetargettype.IdToFixedDepositDetailsConverter’s
convertmethodusesFixedDepositServicesgetFixedDepositmethodtoretrievetheFixedDepositDetails
objectcorrespondingtothefixeddepositID.
Letsnowlookathowtoconfigureanduseacustomconverter.
ConfiguringandusingacustomConverter
Touseacustomconverter,youneedtoregisterthecustomconverterwithSpringsConversionService.A
ConversionServiceactsasaregistryofConvertersandFormatters,andSpringdelegatestypeconversion
responsibility to the registered ConversionService. By default, the <annotation-driven> element of
SpringsmvcschemaautomaticallyregistersSpringsFormattingConversionService(animplementation
ofConversionService)withtheSpringcontainer.Springcomeswithacoupleofbuilt-inconvertersand
formatters that are automatically registered with the FormattingConversionService. If you want to
substitute adifferentimplementation ofConversionService, you can doso byusing conversion-service
attributeof<annotation-driven>element.
To register custom converters with the FormattingConversionService instance, configure Springs
FormattingConversionServiceFactoryBean(a FactoryBean implementation that creates and configures a
FormattingConversionService instance) and specify custom converters as part of the configuration, as
showninthefollowingexamplelisting:
Examplelisting13-16–RegisteringacustomConverterwithFormattingConversionService
Project–ch13-converter-formatter-bankapp
Sourcelocation–src/main/webapp/WEB-INF/spring
<mvc:annotation-drivenconversion-service="myConversionService"/>
<beanid="myConversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<propertyname="converters">
<set>
<beanclass="sample.spring.chapter13.converter.IdToFixedDepositDetailsConverter"/>
</set>
</property>
.....
</bean>
By default, FormattingConversionServiceFactoryBean registers only the built-in converters and
formatterswiththeFormattingConversionServiceinstance.Youregistercustomconvertersandformatters
usingFormattingConversionServiceFactoryBeansconvertersandformattersproperties.Aswewantour
Spring application to use FormattingConversionService instance created by the
FormattingConversionServiceFactoryBean, the conversion-service attribute of <annotation-driven>
elementreferstotheFormattingConversionServiceFactoryBean.
Theconvertersand formatters registered withtheFormattingConversionServiceareused bytheSpring
container to perform type conversion duringdata binding. In the following example listing,
FixedDepositController’s viewFixedDepositDetails method shows a scenario in which the Spring
containerusesIdToFixedDepositDetailsConverter<String,FixedDepositDetails>toconvertfixeddeposit
ID(oftypeString)toFixedDepositDetailsinstance:
Examplelisting13-17–FixedDepositControllersviewFixedDepositDetailsmethod
Project–ch13-converter-formatter-bankapp
Sourcelocation–src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
.....
publicclassFixedDepositController{
.....
@RequestMapping(params="fdAction=view",method=RequestMethod.GET)
publicModelAndViewviewFixedDepositDetails(
@RequestParam(value="fixedDepositId")FixedDepositDetailsfixedDepositDetails){
.....
}
}
@RequestParamannotationspecifiesthatthevalueoffixedDepositIdrequestparameterisassignedtothe
fixedDepositDetailsmethodargument.ThefixedDepositIdrequestparameteruniquelyidentifiesafixed
deposit. As the fixedDepositId request parameter is of type String and method argument type is
FixedDepositDetails, Spring uses IdToFixedDepositDetailsConverter<String, FixedDepositDetails> to
performthetypeconversion.
The use of ConversionService is not limited to the web layer. You can use ConversionService to
programmaticallyperformtypeconversioninanylayerofyourapplication.Thefollowingexamplelisting
shows a variant of FixedDepositControllers viewFixedDepositDetails method that uses
ConversionServicedirectlyforperformingtypeconversion:
Examplelisting13-18–Performingtypeconversionprogrammatically
importorg.springframework.core.convert.ConversionService;
.....
publicclassFixedDepositController{
@Autowired
privateConversionServiceconversionService;
.....
@RequestMapping(params="fdAction=view",method=RequestMethod.GET)
publicModelAndViewviewFixedDepositDetails(HttpServletRequestrequest){
StringfixedDepositId=request.getParameter("fixedDepositId");
FixedDepositDetailsfixedDepositDetails=
conversionService.convert(fixedDepositId,FixedDepositDetails.class);
.....
}
}
Intheaboveexamplelisting,ConversionServiceinstancethatisregisteredwiththeSpringcontaineris
autowired into the FixedDepositController. The viewFixedDepositDetails method uses
ConversionServicesconvertmethodtoconvertfixedDepositId(oftypeString)toFixedDepositDetails.
Behind the scenes, ConversionService makes use of the IdToFixedDepositDetailsConverter<String,
FixedDepositDetails>converterregisteredwithittoperformthetypeconversion.
NowthatwehaveseenhowtocreateanduseacustomConverter,let’snowlookathowtocreateanduse
acustomFormatter.
CreatingacustomFormatter
AformatterconvertsanobjectoftypeTtoaStringvaluefordisplaypurposes,andparsesaStringvalue
totheobjecttypeT.AformatterimplementsSpringsFormatter<T>interface,whereTisthetypeofthe
objectthattheformatterformats.ThismaysoundsimilartowhatPropertyEditorsdoinwebapplications.
Aswellseeinthischapter,FormattersofferamorerobustalternativetoPropertyEditors.
NOTESpringstaglibrarytagsusetheformattersregisteredwiththeFormattingConversionServiceto
performtypeconversionduringdatabindingandrendering.
The following example listing shows the AmountFormatter that is used by the MyBank application to
display fixed deposit amount in the currency that applies to the users locale, and to parse the fixed
depositamountenteredbytheuser.Forsimplicity,currencyconversionisnotappliedonthefixeddeposit
amount; the currency symbol that applies to the users locale is simply appended to the fixed deposit
amount.
Examplelisting13-19–AmountFormatter-aFormatterimplementation
Project–ch13-converter-formatter-bankapp
Sourcelocation–src/main/java/sample/spring/chapter13/formatter
packagesample.spring.chapter13.formatter;
importjava.text.ParseException;
importjava.util.Locale;
importorg.springframework.format.Formatter;
publicclassAmountFormatterimplementsFormatter<Long>{
@Override
publicStringprint(Longobject,Localelocale){
StringreturnStr=object.toString()+"USD";
if(locale.getLanguage().equals(newLocale("de").getLanguage())){
returnStr=object.toString()+"EURO";
}
returnreturnStr;
}
@Override
publicLongparse(Stringtext,Localelocale)throwsParseException{
Stringstr[]=text.split("");
returnLong.parseLong(str[0]);
}
}
AmountFormatterimplementsFormatter<Long>interface,whichmeansthattheAmountFormatterapplies
to Long type objects. The print method converts the Long type object (representing the fixed deposit
amount) to a String value that is displayed to the user. Based on the language code obtained from the
locale,theprintmethodsimplyappendsUSD(forenlanguagecode)orEURO(fordelanguagecode)to
thefixeddepositamount.Forinstance,ifthefixeddepositamountis1000andthelanguagecodeisde,the
printmethodreturns1000EURO.Theparsemethodtakesthefixeddepositamountenteredbytheuser
(like,‘1000EURO)andconvertsitintoaLongtypeobjectbysimplyextractingthefixeddepositamount
fromtheuserenteredvalue.
Letsnowlookathowtoconfigureacustomformatter.
ConfiguringacustomFormatter
YoucanregistercustomformatterswiththeFormattingConversionServiceusingtheformatterspropertyof
FormattingConversionServiceFactoryBean,asshownhere:
Examplelisting13-20–RegisteringacustomFormatterwithFormattingConversionService
<beans.....>
.....
<mvc:annotation-drivenconversion-service="myConversionService"/>
.....
<beanid="myConversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<propertyname="formatters">
<set>
<beanclass="sample.spring.chapter13.formatter.AmountFormatter"/>
</set>
</property>
</bean>
</beans>
AmountFormatterregisteredwiththeFormattingConversionServiceisappliedtoalltheLongtypefields
duringdatabindingandrendering.
YoucancontrolthefieldsonwhichaFormatterappliesbyusingSpringsAnnotationFormatterFactory.
An AnnotationFormatterFactory implementation creates formatters for fields that are annotated with a
particularannotation.LetsseehowwecanuseAnnotationFormatterFactorytoformatonlytheLongtype
fieldsannotatedwith@AmountFormatannotation.
CreatingAnnotationFormatterFactorytoformatonly@AmountFormatannotated
fields
Thefollowingexamplelistingshowsthedefinitionof@AmountFormatannotation:
Examplelisting13-21–AmountFormatannotation
Project–ch13-converter-formatter-bankapp
Sourcelocation–src/main/java/sample/spring/chapter13/formatter
packagesample.spring.chapter13.formatter;
.....
@Target(value={ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public@interfaceAmountFormat{}
In theabove examplelisting, the@Target annotation specifies that the @AmountFormat annotation can
onlyappearonfields.
The following example listing shows the implementation of AnnotationFormatterFactory that creates
formattersforfieldsannotatedwith@AmountFormatannotation:
Examplelisting13-22–AmountFormatAnnotationFormatterFactoryclass
Project–ch13-converter-formatter-bankapp
Sourcelocation–src/main/java/sample/spring/chapter13/formatter
packagesample.spring.chapter13.formatter;
importorg.springframework.format.AnnotationFormatterFactory;
importorg.springframework.format.Parser;
importorg.springframework.format.Printer;
publicclassAmountFormatAnnotationFormatterFactoryimplements
AnnotationFormatterFactory<AmountFormat>{
publicSet<Class<?>>getFieldTypes(){
Set<Class<?>>fieldTypes=newHashSet<Class<?>>(1,1);
fieldTypes.add(Long.class);
returnfieldTypes;
}
publicParser<?>getParser(AmountFormatannotation,Class<?>fieldType){
returnnewAmountFormatter();
}
publicPrinter<?>getPrinter(AmountFormatannotation,Class<?>fieldType){
returnnewAmountFormatter();
}
}
In the above example listing, AmountFormatAnnotationFormatterFactory implements
AnnotationFormatterFactory<AmountFormat> interface, which means that the
AmountFormatAnnotationFormatterFactorycreatesformattersforfieldsannotatedwith@AmountFormat
annotation.
ThegetFieldTypesmethodreturnsthefieldtypesthatmaybeannotatedwith@AmountFormatannotation.
ThegetFieldTypesmethodintheaboveexamplelistingreturnsasingletype,Longtype,whichmeansthat
onlyaLongtypefieldthatisannotatedwith@AmountFormatannotationisconsideredforformattingby
the formatters created by the AmountFormatAnnotationFormatterFactory. The getParser and getPrinter
methodsreturnformattersforfieldsthatareannotatedwith@AmountFormatannotation.Youshouldnote
thattheFormatterinterfaceisasub-interfaceofParserandPrinterinterfaces.
ConfiguringAnnotationFormatterFactoryimplementation
AsincaseofFormattersconfiguration,anAnnotationFormatterFactoryimplementationisregisteredwith
FormattingConversionServiceviaformatterspropertyofFormattingConversionServiceFactoryBean:
Examplelisting13-23–AmountFormatAnnotationFormatterFactoryconfiguration
Project–ch13-converter-formatter-bankapp
Sourcelocation–src/main/webapp/WEB-INF/spring
<beans.....>
.....
<mvc:annotation-drivenconversion-service="myConversionService"/>
.....
<beanid="myConversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<propertyname="formatters">
<set>
<bean
class="sample.spring.chapter13.formatter.AmountFormatAnnotationFormatterFactory"/>
</set>
</property>
</bean>
</beans>
Now that we have seen how to use AnnotationFormatterFactory to enable formatting of fields that are
annotated with a specific annotation, lets look at how it is used in ch13-converter-formatter-bankapp
project.
The following figure shows the web page of ch13-converter-formatter-bankapp project that shows the
listsoffixeddeposits:
Figure13-4 - The ‘Deposit amount column shows USD or EURO depending upon the language code
obtainedfromtheuserscurrentlocale
TheabovefigureshowsthatUSDisappendedtothefixeddepositamountifthelanguagechosenbythe
userisEnglish.IfyouswitchthelanguagetoGerman,theUSDwillbereplacedbyEURO.Inexample
listing13-19,wesawthattheAmountFormattercontainedthelogicto showUSD orEUROdepending
uponthelanguagecodeobtainedfromtheuserscurrentlocale.
ToensurethattheformattersconfiguredwiththeFormattingConversionServiceareinvokedduringpage
renderingandformsubmission,Springstaglibrarytags(like,<eval>and<input>)havebeenusedinthe
JSPpagesofch13-converter-formatter-bankappproject.
LetsnowlookathowSpringWebMVCsimplifiesuploadingfiles.
13-6FileuploadsupportinSpringWebMVC
You can handle multipart requests in your Spring Web MVC applications by configuring a
MultipartResolver. Spring provides the following out-of-the-box implementations of MultipartResolver
interfacethatyoucanuseinyourwebapplications:
§CommonsMultipartResolver–basedonApacheCommonsFileUploadlibrary
§StandardServletMultipartResolver–basedonServlet3.0PartAPI
Whenamultipartrequestisreceived,DispatcherServletusestheconfiguredMultipartResolvertowrap
theHttpServletRequest intoa MultipartHttpServletRequest instance. In Spring Web MVC, an uploaded
file is represented by the MultipartFile object. The controller responsible for handling file uploads
accesses the uploaded file using methods defined by the MultipartHttpServletRequest or by directly
accessingtheMultipartFileobject.
LetsfirstlookatasamplewebapplicationthatusesCommonsMultipartResolverforuploadingfiles.
IMPORTchapter 13/ch13-commons-file-upload(This project shows how to use
CommonsMultipartResolver to upload files. As CommonsMultipartResolver uses Apache Commons
FileUploadlibrary,theprojectisdependentoncommons-fileuploadJARfile.)
UploadingfilesusingCommonsMultipartResolver
Thefollowingexamplelistingshowsthefileuploadformthatisdisplayedbych13-commons-file-upload
project:
Examplelisting13-24–uploadForm.jsp–showstheuploadform
Project–ch13-commons-file-upload
Sourcelocation–src/main/webapp/WEB-INF/jsp
.....
<formmethod="post"action="/ch13-commons-file-upload/uploadFile"
enctype="multipart/form-data">
<tablestyle="padding-left:200px;">
<tr>
<tdcolspan="2"><c:outvalue="${uploadMessage}"/></td>
</tr>
<tr>
<td><b>Selectthefiletobeuploaded:&nbsp;</b></td>
<td><inputtype="file"name="myFileField"/></td>
</tr>
<tr>
<tdcolspan="2"align="center"><inputtype="button"
value="Uploadfile"onclick="document.forms[0].submit();"/></td>
</tr>
</table>
</form>
.....
The above example listing shows that the enctype attribute of <form> element is set to multipart/form-
data, which means that the form submission results in sending multipart request to the server. The
uploadMessage request attribute shows the success or failure message after the user selects a file and
clicksthe‘Uploadfilebutton.
The following example listing shows the configuration of CommonsMultipartResolver that resolves
multipartrequests:
Examplelisting13-25–fileupload-config.xml–CommonsMultipartResolverconfiguration
Project–ch13-commons-file-upload
Sourcelocation–src/main/webapp/WEB-INF/spring
<beanid="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<propertyname="maxUploadSize"value="100000"/>
<propertyname="resolveLazily"value="true"/>
</bean>
It is important to note that the MultipartResolver implementation must be configured with id as
multipartResolverin the webapplication context XML file.The maxUploadSize propertyspecifies the
maximum size(inbytes)of the file thatcan beuploaded. Ifyouattempttouploadafilewhose size is
greaterthan100KB,theCommonsMultipartResolvershownintheaboveexamplelistingwillthrowan
exception. If an exception is thrown by the CommonsMultipartResolver instance, the controller
responsible for handling the file upload doesnt get the opportunity to handle the exception. For this
reason,theresolveLazilypropertyissettotrue.IftheresolveLazilypropertyissettotrue,themultipart
requestisresolvedonlywhentheuploadedfileisaccessedbythecontroller.Thisgivestheopportunity
tothecontrollertohandleexceptionsthatoccurduringmultipartrequestresolution.
ThefollowingexamplelistingshowstheFileUploadControllerthathandlesfileuploads:
Examplelisting13-26–FileUploadController
Project–ch13-commons-file-upload
Sourcelocation–src/main/java/sample/spring/chapter13/web
packagesample.spring.chapter13.web;
importorg.springframework.web.multipart.MultipartFile;
.....
publicclassFileUploadController{
.....
@RequestMapping(value="/uploadFile",method=RequestMethod.POST)
publicModelAndViewhandleFileUpload(
@RequestParam("myFileField")MultipartFilefile)throwsIOException{
ModelMapmodelData=newModelMap();
if(!file.isEmpty()){
//--savetheuploadedfileonthefilesystem
StringsuccessMessage="Filesuccessfullyuploaded";
modelData.put("uploadMessage",successMessage);
returnnewModelAndView("uploadForm",modelData);
}
.....
}
@ExceptionHandler(value=Exception.class)
publicModelAndViewhandleException(){
.....
}
}
FileUploadControllers handleFileUpload method accepts an argument of type MultipartFile which
identifies the uploaded file. Notice that the @RequestParam annotation specifies name of the <input
type=”file”.....>fieldintheuploadForm.jsppage(referexamplelisting13-24).Ifthefileissuccessfully
uploaded, the handleFileUpload method sets a success message which is shown to the user.
@ExceptionHandler method shows an error message in case an exception occurs during file upload
process.Forinstance,ifthefilesizeisgreaterthan100KB,anerrormessageisshowntotheuser.
Now that we have seen how to use CommonsMultipartResolver to upload files, let’s look at how to
uploadfilesusingStandardServletMultipartResolver.
IMPORTchapter 13/ch13-servlet3-file-upload(This project shows how to use
StandardServletMultipartResolvertouploadfiles.)
UploadingfilesusingStandardServletMultipartResolver
Thesupportforhandlingmultipartrequestisprovidedout-of-the-boxinServlet3.Ifyouwanttousethe
multipart support provided by Servlet 3, enable multipart request handling by specifying <multipart-
config>elementintheDispatcherServletconfiguration,andconfigureStandardServletMultipartResolver
in the web application context XML file. Unlike, CommonsMultipartResolver,
StandardMultipartResolverdoesn’tdefineanyproperties.
ThefollowingexamplelistingshowstheDispatcherServletconfigurationinweb.xmlfile:
Examplelisting13-27–web.xml
Project–ch13-servlet3-file-upload
Sourcelocation–src/main/webapp
<servlet>
<servlet-name>fileupload</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
.....
<multipart-config>
<max-file-size>10000</max-file-size>
</multipart-config>
</servlet>
Asthe<multipart-config>elementisspecified,thefileuploadservletcanhandlemultipartrequests.The
<max-file-size>elementspecifiesthemaximumfilesizethatcanbeuploaded.Noticethatthemaximum
filesizeisnowspecifiedaspartof<multipart-config>element.
13-7Summary
Inthischapter,welookedatsomeoftheimportantfeaturesofSpringWebMVCframeworkthatsimplify
developingwebapplications.Inthenextchapter,we’lllookathowtosecureSpringapplicationsusing
SpringSecurityframework.
Chapter14–SecuringapplicationsusingSpringSecurity
14-1Introduction
Securityisanimportantaspectofanyapplication.SpringSecurityisbuiltontopofSpringFramework,
andprovidesacomprehensiveframeworkforsecuringSpring-basedapplications.Inthischapter,we’ll
lookathowtouseSpringSecurityframeworkto:
§authenticateusers
§implementwebrequestsecurity,
§implementmethod-levelsecurity
§securedomainobjectsusingACL(AccessControlList)basedsecurity
LetsbeginbylookingattheMyBankwebapplicationssecurityrequirementsthatwe’ll address using
SpringSecurity.
14-2SecurityrequirementsoftheMyBankwebapplication
TheusersoftheMyBankwebapplicationarecustomersandadministratorsthatmanagefixeddeposits
inthesystem.Acustomercanopenandeditfixeddepositsbutcan’tclosethem.Anadministratorcan’t
createoreditfixeddepositsbutcanclosefixeddepositsofcustomers.
As only authenticated users can access the MyBank web application, a login form is displayed to
unauthenticatedusers:
Figure14-1-Loginformthatisdisplayedtounauthenticatedusers
Theabovefigureshowstheloginformthatisdisplayedtounauthenticatedusers.Iftheuserselectsthe
‘Remember me on this computer checkbox, the MyBank web application remembers the credentials
enteredbytheuserandusesitforautomaticauthenticationoftheuserinfuturevisits.
When acustomer logs in, details ofthe fixed deposits associated with the customer are displayed, as
shownhere:
Figure14-2-Fixeddepositsofthecustomeraredisplayedafterauthentication
TheabovefigureshowsaLogouthyperlinkthatthecustomercanclicktologoutfromtheMyBankweb
application.AcustomercaneditdetailsofafixeddepositbyclickingtheEdithyperlinkcorrespondingto
thatfixeddeposit.AcustomercanviewtheformforopeninganewfixeddepositbyclickingtheCreate
new Fixed Deposit button. Notice that the username of the authenticated user is displayed below the
Logouthyperlink.
Whenanadministratorlogsin,detailsofallthefixeddepositsinthesystemaredisplayedbytheMyBank
webapplication,asshownhere:
Figure14-3-Fixeddepositsofallthecustomeraredisplayedtoanadministrator
Intheabovefigure,anadministratorcanchoosetocloseafixeddepositbyclickingtheClosehyperlink
corresponding to that fixed deposit. As in case of customers, the Create new Fixed Deposit button is
visibletoanadministratoralso,butanattempttosavedetailsofthenewfixeddepositwillresultina
securityexceptionthrownbytheapplication.
Lets now look at how to address the security requirements of MyBank web application using Spring
Security.
IMPORTchapter 14/ch14-bankapp-simple-security (This project represents the MyBank web
applicationthatusesSpringSecurityframeworkforaddressingsecurityrequirementsdescribedinsection
14-2.)
14-3SecuringMyBankwebapplicationusingSpringSecurity
Spring Security framework consists of multiple modules that address various security aspects of
applications.ThefollowingtabledescribessomeoftheimportantmodulesofSpringSecurity:
Module Description
spring-security-core DefinesthecoreclassesandinterfacesofSpringSecurityframework.Thismoduleis
requiredbyanyapplicationthatusesSpringSecurity.
spring-security-web Providessupportforsecuringwebapplications
spring-security-config
Like Springs tx and mvc schemas, Spring Security defines a security schema that
simplifiesconfiguring Spring Security  features. The sp ring-security-config module is
responsibleforparsingtheelementsofthesecuritynamespace.
spring-security-taglibs Definestagsthatyoucanusetoaccesssecurityinformationandtosecurethecontent
displayedbyJSPpages
spring-security-acl Enables useof ACLs (Access ControlList) to secureinstances ofdomain objects in
applications
In this section, we’ll look at usage of spring-security-core, spring-security-web, spring-security-config
andspring-security-taglibsmodules tosecuretheMyBank webapplication. Laterinthischapter, we’ll
lookathowtousespring-security-aclmoduletosecuredomainobjectinstances.
Letsbeginbylookingathowwebrequestsecurityisconfigured.
Webrequestsecurityconfiguration
Youcanaddwebrequestsecuritytoanapplicationby:
§configuringSpringsDelegatingFilterProxyfilterintheweb.xmlfile,and
§enablingwebrequestsecurityprovidedbytheSpringSecurityframework
LetsfirstlookathowtoconfigureDelegatingFilterProxyfilter.
DelegatingFilterProxyfilterconfiguration
Spring Frameworks web module (represented by spring-web-4.0.0.RELEASE.jar file) defines the
DelegatingFilterProxyclassthatimplementsServletAPIsFilterinterface.Thefollowingexamplelisting
showstheconfigurationofDelegatingFilterProxyfilterintheweb.xmlfile:
Examplelisting14-1–web.xml-DelegatingFilterProxyfilterconfiguration
Project–ch14-bankapp-simple-security
Sourcelocation-src/main/webapp/WEB-INF
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The<filter-mapping>element specifies that the DelegatingFilterProxy filter is mapped to all incoming
webrequests.Thefilternamespecifiedbythe<filter-name>elementcarriesaspecialsignificanceinthe
context of DelegatingFilterProxy filter. DelegatingFilterProxy filter delegates request processing to the
Springbeanwhosenamematchesthevalueof<filter-name>element.Intheaboveexamplelisting,web
requests received by the DelegatingFilterProxy filter are delegated to the Spring bean named
springSecurityFilterChain in the root application context. Well soon see that the
springSecurityFilterChainbeaniscreatedbytheSpringSecurityframework.
Now,thatwehaveconfiguredtheDelegatingFilterProxyfilter,let’slookathowtoconfigurewebrequest
security.
Configuringwebrequestsecurity
The following example listing shows the application context file that uses <http> element of security
schematoconfigurewebrequestsecurity:
Examplelisting14-2–applicationContext-security.xml–websecurityconfiguration
Project–ch14-bankapp-simple-security
Sourcelocation-src/main/resources/META-INF/spring
<beans:beansxmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation=".....
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">

<httpuse-expressions="true">
<intercept-urlpattern="/**"access="hasAnyRole('ROLE_CUSTOMER','ROLE_ADMIN')"/>
<form-login/>
<logout/>
<remember-me/>
<headers>
<cache-control/>
<xss-protection/>
</headers>
</http>
.....
</beans:beans>
Theaboveexamplelistingshowsthatthespring-security-3.2.xsdschemaisreferencedbytheapplication
context XML file. The spring-security-3.2.xsd schema is contained in the
org.springframework.security.configpackageofspring-security-config-3.2.0.RELEASE.jarfile.
The<http>elementcontainsthewebrequest securityconfigurationfor theapplication.SpringSecurity
framework parses the <http> element and registers a bean named springSecurityFilterChain with the
Spring container. The springSecurityFilterChain bean is responsible for handling web request security.
TheDelegatingFilterProxy filter that we configured earlier (refer example listing 14-1) delegates web
requesthandlingtothespringSecurityFilterChainbean.ThespringSecurityFilterChainbeanrepresentsan
instanceofFilterChainProxybean(referSpringSecuritydocsformoreinformation)thatcontainsachain
ofServletfiltersthatareaddedtothechainbythesub-elementsof<http>element.
The <intercept-url> element’s access attribute specifies a Spring EL expression that evaluates to a
boolean value. If the Spring EL expression returns true, the URLs matched by the pattern attribute are
accessibletotheuser.IftheSpringELexpressionreturnsfalse,accessisdeniedtotheURLsmatchedby
thepatternattribute.SpringSecurityframeworkprovidesacoupleofbuilt-inexpressions,likehasRole,
hasAnyRole,isAnonymous,andsoon.
Inexamplelisting14-2,thehasAnyRole('ROLE_CUSTOMER','ROLE_ADMIN')expressionreturnstrue
if the authenticated user has ROLE_CUSTOMERor ROLE_ADMIN role. In MyBank web application,
theROLE_CUSTOMER role is assigned to a customer and the ROLE_ADMIN role is assigned to an
administrator. As the pattern /* matches all URLs, the <intercept-url> element in example listing 14-2
specifiesthatonlyauserwithroleROLE_CUSTOMERorROLE_ADMINcanaccesstheMyBankweb
application.YoushouldnotethattheuseofSpringELexpressionintheaccessattributeisallowedonlyif
yousetthevalueofuse-expressionsattributeof<http>elementtotrue.
The<form-login>elementconfiguresaloginpagethatisusedtoauthenticateusers.Youcanusevarious
attributesof<form-login>element,likelogin-page,default-target-url,andsoon,tocustomizethelogin
page.Thelogin-pageattributespecifiestheURLthatisusedtorendertheloginpage.Ifthelogin-page
attributeisnotspecified,aloginpageisautomaticallyrenderedatthe/spring_security_loginURL.
The<logout>elementconfiguresthelogoutprocessingfeatureofSpringSecurityframework.Youcanuse
variousattributesof<logout>element,likelogout-url,delete-cookies,invalidate-session,andsoon,to
configurethelogoutfunctionality.Forinstance,youcanusethedelete-cookiesattributetospecifycomma-
separatednamesofcookiesthatshouldbedeletedwhentheuserlogsoutoftheapplication.Thelogout-
urlattributeallowsyoutoconfiguretheURLthatperformsthelogoutprocessing.Ifyoudontspecifythe
logout-urlattribute,thelogout-urlattributevalueissetto/j_spring_security_logoutbydefault.
The<remember-me>elementconfiguresthe‘remember-me’authenticationinwhichthewebapplication
remembers the identity of the authenticated user between sessions. When a user is successfully
authenticated,SpringSecurityframeworkgeneratesauniquetokenthatcaneitherbestoredinapersistent
store or sent to the user in a cookie. In example listing 14-2, <remember-me> element configures a
cookie-basedremember-meauthenticationservice.Whentheuserrevisitsthewebapplication,thetoken
isretrievedfromthecookieandisautomaticallyauthenticated.
The<headers>elementspecifiesthesecurityheadersthatareaddedtotheHTTPresponsebytheSpring
Security framework. For instance, in example listing 14-2, the <cache-control> element adds Cache-
Control,PragmaandExpiresresponseheaders,andthe<xss-protection>elementaddsX-XSS-Protection
header.
WhenanunauthenticateduseraccessestheMyBankwebapplication,SpringSecuritydisplaysthelogin
page (refer figure 14-1) configured by the <form-login> element to the user. Let’s now look at how
authenticationisperformedwhentheuserentershiscredentialsandclickstheLoginbutton.
Authenticationconfiguration
Whenauserentershiscredentialsandsubmitstheloginpage,SpringSecuritysAuthenticationManageris
responsibleforprocessingtheauthenticationrequest.AnAuthenticationManagerisconfiguredwithone
ormoreAuthenticationProvidersagainstwhichtheAuthenticationManagerattemptstoauthenticateusers.
For instance, if you want to authenticate users against an LDAP server, you can configure an
LdapAuthenticationProvider (an implementation of AuthenticationProvider) that authenticates users
againstanLDAPserver.
The security schema simplifies configuration of AuthenticationManager and AuthenticationProvider
objects,asshowninthefollowingexamplelisting:
Examplelisting14-3–applicationContext-security.xml
Project–ch14-bankapp-simple-security
Sourcelocation-src/main/resources/META-INF/spring
<authentication-manager>
<authentication-provider>
<user-service>
<username="admin"password="admin"authorities="ROLE_ADMIN"/>
<username="cust1"password="cust1"authorities="ROLE_CUSTOMER"/>
<username="cust2"password="cust2"authorities="ROLE_CUSTOMER"/>
</user-service>
</authentication-provider>
</authentication-manager>
The <authentication-manager> element configures an AuthenticationManager instance. The
<authentication-provider> element configures an AuthenticationProvider instance. By default, the
<authentication-provider> element configures a DaoAuthenticationProvider (an implementation of
AuthenticationProvider)thatusesSpringsUserDetailsServiceasaDAOtoloaduserdetails.
DaoAuthenticationProvider uses the configured UserDetailsService to load user details from the user
repository based on the supplied username. DaoAuthenticationProvider performs authentication by
comparing the login credentials supplied by the user with the user details loaded by the configured
UserDetailsService.YoushouldnotethataUserDetailsServicemayloaduserdetailsfromadatasource,
aflatfileoranyotheruserrepository.
The <user-service> sub-element of <authentication-provider> configures anin-memory
UserDetailsServicethatloadsusersdefinedbythe<user>elements.Inexamplelisting14-3,the<user-
service> element defines that the application has three users: admin (ROLE_ADMIN role), cust1
(ROLE_CUSTOMER role) and cust2 (ROLE_CUSTOMER role). The name attribute specifies the
username assigned to the user,the password attribute specifies the password assigned to the user, and
authoritiesattributespecifiestherole(s)assignedtotheuser.
Now, if you deploy the ch14-bankapp-simple-security project and access it by going to the
http://localhost:8080/ch14-bankapp-simple-security URL, the login page (refer figure 14-1) of the web
application is displayed. If you authenticate by entering username as cust1 and password as cust1, the
webapplicationwilldisplayfixeddepositsassociatedwithcust1(referfigure14-2)user.Similarly,if
youloginwithusernameascust2andpasswordascust2,thewebapplicationwilldisplayfixeddeposits
associated with cust2 user. If you login with username as admin and password as admin, the web
applicationwilldisplayfixeddepositsofbothcust1andcust2users.
LetsnowlookathowtouseSpringSecuritysJSPtaglibrarytoaccesssecurityinformationandtoapply
securityconstraintsonthecontentdisplayedbyJSPpages.
SecuringJSPcontentusingSpringSecurity’sJSPtablibrary
OneoftherequirementsofMyBankwebapplicationisthattheoptiontoeditafixeddeposit(referfigure
14-2)isavailableonlytouserswithroleROLE_CUSTOMER.And,theoptiontocloseafixeddeposit
(refer figure 14-3) isavailable only touser withrole ROLE_ADMIN.As we need tosecure Edit and
Close hyperlinks based on the authenticated users role, the MyBank web application uses Spring
SecuritysJSPtaglibrarytosecureJSPcontent.
ThefollowingexamplelistingshowsusageofSpringSecuritysJSPtaglibrarytoaccessauthenticated
usersusername,andtosecureJSPcontentbasedontheroleoftheloggedinuser:
Examplelisting14-4–fixedDepositList.jsp
Project–ch14-bankapp-simple-security
Sourcelocation-src/main/webapp/WEB-INF/jsp
<%@tagliburi="http://www.springframework.org/security/tags"prefix="security"%>
.....
<body>
.....
<tdstyle="font-family:'arial';font-size:12px;font-weight:bold"align="right">
<ahref="${pageContext.request.contextPath}/j_spring_security_logout">Logout</a>
<p>
Username:<security:authenticationproperty="principal.username"/>
</p>
</td>
.....
<tdclass="td">
<security:authorizeaccess="hasRole('ROLE_CUSTOMER')">
<ahref="${pageContext.request.contextPath}/fixedDeposit?.....">Edit</a>
</security:authorize>
<security:authorizeaccess="hasRole('ROLE_ADMIN')">
<ahref="${pageContext.request.contextPath}/fixedDeposit.....">Close</a>
</security:authorize>
</td>
</body>
</html>
The above example listing shows that the Logout hyperlink refers to
${pageContext.request.contextPath}/j_spring_security_logout URL. As mentioned earlier, if you dont
specify the logout-url attribute of <logout> element, the logout-url value is set to
/j_spring_security_logout. So, when a user clicks the Logout hyperlink, the user is logged out of the
MyBankwebapplication.
TheaboveexamplelistingalsoshowsthattheJSPpageincludesSpringSecuritysJSPtaglibraryusing
thetaglibdirective.SpringSecuritysAuthenticationobjectcontainsinformationabouttheauthenticated
user. Forinstance, itcontains informationaboutauthenticated users role(s) and username thattheuser
usedforauthentication.The<authentication>elementprintsthespecifiedpropertyoftheAuthentication
object. In the above example, the principal.username property refers to the username property of the
authenticateduser.
The<authorize>elementsecurestheenclosedJSPcontentbasedontheresultofevaluationofthesecurity
expression specified by the access attribute. If the security expression evaluates to true, the enclosed
content is rendered, otherwise the enclosed content is not rendered. In the above example listing, the
hasRole(ROLE_CUSTOMER)expressionreturnstrueiftheauthenticateduserhasROLE_CUSTOMER
role, and the hasRole(ROLE_ADMIN’) expression returns true if the authenticated user has
ROLE_ADMIN role. In the above example listing, the hasRole expression has been used such that the
EditoptionisdisplayedonlytoauserwithROLE_CUSTOMERroleandtheCloseoptionisdisplayed
onlytoauserwithROLE_ADMINrole.
Letsnowlookathowtoincorporatemethod-levelsecurityusingSpringSecurity.
Securingmethods
One of the requirements of MyBank application is that a user with ROLE_ADMIN role can view the
‘Create new Fixed Deposit’ button (refer figure 14-3) but an attempt to save details of the new fixed
deposit will result in a security exception. This is an example in which we want to secure the
FixedDepositService’ssaveFixedDepositmethodsuchthatonlyauserwithROLE_CUSTOMERrolecan
invokeit.
WealsowanttosecureothermethodsoftheFixedDepositServicesothatitisnotinvokedbyunauthorized
users.Forinstance,cust1userloggedinwithROLE_CUSTOMERcaninvoketheFixedDepositService’s
closeFixedDeposit method to close an existing fixed deposit by entering the following URL in the
browser:
http://localhost:8080/ch14-bankapp-simple-security/fixedDeposit?fdAction=close&fixedDepositId=
<fixed-fixed-id>
The<fixed-deposit-id>intheaboveURListhefixeddepositidthatyouwanttoremove,ashighlightedin
thefollowingfigure:
Figure14-4–FixeddepositIDofafixeddepositisdisplayedintheIDcolumn
Toaddmethod-levelsecuritytoyourapplication,youneedtodothefollowing:
§configuremethod-levelsecurityforyourapplicationbyusing<global-method-security>elementof
securityschema
§add@Securedannotationstothemethodsthatyouwanttosecureagainstunauthorizedaccess
Letsfirstlookatthe<global-method-security>element.
Configuringmethod-levelsecurityusing<global-method-security>element
Thefollowingexamplelistingshowsusageof<global-method-security>element:
Examplelisting14-5–applicationContext-security.xml
Project–ch14-bankapp-simple-security
Sourcelocation-src/main/resources/META-INF/spring
<beans:beansxmlns="http://www.springframework.org/schema/security"
.....>
<global-method-securitysecured-annotations="enabled"/>
</beans:beans>
The<global-method-security> element configures method-level security. The <global-method-security>
elementisapplicableonlytotheapplicationcontextinwhichitisdefined.Forinstance,ifthe<global-
method-security>elementisdefinedintherootwebapplicationcontextXMLfile,thenitisapplicable
only to the beans registered with the root WebApplicationContext instance. In ch14-bankapp-simple-
security project, the applicationContext-security.xml (shown in the above example listing) and the
applicationContext.xml(thatdefinesservicesandDAOs)filesconstitutetherootwebapplicationcontext
XMLfiles(referweb.xmlfileofch14-bankapp-simple-securityproject);therefore,the<global-method-
security>elementappliesonlytothebeansdefinedintheseapplicationcontextXMLfiles.
The <global-method-security> element’s secured-annotations attribute specifies whether the use of
Springs@Secured annotation should be enabled or disabled for the beans registered with the Spring
container.Asthevalueissettoenabled,youcanuseSprings@Securedannotationtospecifythebean
methodsthataresecured.
NOTEIfyouwanttosecurecontrollermethods,thendefinethe<global-method-security>elementinthe
webapplicationcontextXMLfileinsteadoftherootwebapplicationcontextXMLfile.
LetsnowlookathowtosecuremethodsusingSprings@Securedannotation.
Specifyingsecurityconstraintsonbeanmethodsusing@Securedannotation
The following example listing shows usage of Springs @Secured annotation to define security
constraintsonmethods:
Examplelisting14-6–FixedDepositServiceinterface
Project–ch14-bankapp-simple-security
Sourcelocation-src/main/java/sample/spring/chapter14/service
packagesample.spring.chapter14.service;
importorg.springframework.security.access.annotation.Secured;
.....
publicinterfaceFixedDepositService{
.....
@Secured("ROLE_CUSTOMER")
voidsaveFixedDeposit(FixedDepositDetailsfixedDepositDetails);
.....
@Secured("ROLE_ADMIN")
voidcloseFixedDeposit(intfixedDepositId);
@Secured("ROLE_CUSTOMER")
voideditFixedDeposit(FixedDepositDetailsfixedDepositDetails);
}
TheaboveexamplelistingshowstheFixedDepositServiceinterfacethatdefinesmethodsthatoperateon
fixed deposits. @Secured("ROLE_CUSTOMER") annotation on the saveFixedDeposit and
editFixedDeposit methods specifies that these methods can only be invoked by a user whose role is
ROLE_CUSTOMER. @Secured("ROLE_ADMIN") annotation on the closeFixedDeposit method
specifiesthatthemethodcanonlybeinvokedbyauserwhoseroleisROLE_ADMIN.
NOTEBydefault,method-levelsecurityisbasedonSpringAOP.IfyouwanttouseAspectJinsteadof
Spring AOP, set mode attribute of <global-method-security> element to aspectj. Also, add spring-
security-aspects module to your project, and specify @Secured annotations on the class instead of the
interface.
Insteadofusing@Securedannotation,youcanuseSprings@PreAuthorizeannotationtoapplysecurity
constraints on methods. Unlike @Secured annotation, @PreAuthorize annotation accepts security
expressions,likehasRole,hasAnyRole,andsoon.Toenableuseof@PreAuthorizeannotation,setpre-
post-annotationsattributeof<global-method-security>elementtoenabled.Thefollowingexamplelisting
showsusageof@PreAuthorizeannotation:
Examplelisting14-6–@PreAuthorizeannotation
importorg.springframework.security.access.prepost.PreAuthorize;
.....
publicinterfaceSomeService{
.....
@PreAuthorize("hasRole('ROLE_XYZ')")
voiddoSomething(.....);
.....
}
In the above example listing, @PreAuthorize annotation specifies that the doSomething method is
accessibleonlytouserswithroleROLE_XYZ.
SpringSecurityalsosupportssecurityannotations,like@RolesAllowed,@DenyAll,@PermitAll,andso
on, defined by JSR-250 – Common Annotations. To enable use of JSR-250 security annotations, set
jsr250-annotations attribute of <global-method-security> to enabled. The following example listing
showsusageof@RolesAllowedannotation:
Examplelisting14-7–@RolesAllowedannotation
importjavax.annotation.security.RolesAllowed;
.....
publicinterfaceSomeService{
.....
@RolesAllowed("ROLE_XYZ")
voiddoSomething(.....);
.....
}
In the above example listing, @RolesAllowed annotation specifies that the doSomething method is
accessibleonlytouserswithroleROLE_XYZ.
NOTEWesawearlierinthisbookthatJSR250annotations,like@PreDestroy,@PostConstruct,andso
on,arepartofJavaSE6orlater.AssecurityrelatedannotationsofJSR250arenotpartofJavaSE,you
need to add jsr250-api JAR file to your project to use @RolesAllowed, @PermitAll, and so on,
annotations.
Inthissection,welookedathowtouseSpringSecuritytoauthenticateusers,securewebrequestsand
implementmethod-levelsecurity.Let’snowlookatSpringSecuritysACLmoduleforsecuringdomain
objectinstances.
IMPORTchapter14/ch14-bankapp-db-security(ThisprojectrepresentstheMyBankwebapplication
thatusesSpringSecuritysACLmoduleforsecuringFixedDepositDetailsinstances.)
14-4 MyBank web application - securing FixedDepositDetailsinstances
usingSpringSecurity’sACLmodule
Thech14-bankapp-db-securityprojectrepresentsavariantofMyBankwebapplicationthatusesSpring
SecuritysACLmoduletosecureFixedDepositDetailsinstances.
Letslookathowtodeployandusech14-bankapp-db-securityproject.
Deployingandusingch14-bankapp-db-securityproject
The ch14-bankapp-db-security project uses MySQL database to store application users, fixed deposit
detailsandACLinformation.Beforedeployingthech14-bankapp-db-securityproject,createadatabase
named securitydb in MySQL and execute the bankapp.sql script located in scripts folder of ch14-
bankapp-db-securityproject.
The execution of bankapp.sql script creates the following tables: ACL_CLASS, ACL_ENTRY,
ACL_OBJECT_IDENTITY, ACL_SID, FIXED_DEPOSIT_DETAILS, AUTHORITIES, and USERS.
TableswhosenamesbeginwithACL_storeACLrelatedinformation(moreonthesetableslaterinthis
chapter).FIXED_DEPOSIT_DETAILStablecontainsfixeddepositdetails.USERSandAUTHORITIES
tablescontainuserandroleinformation,respectively.Thebankapp.sqlscriptalsoinsertssetupdatainto
USERS,AUTHORITIES,ACL_CLASSandACL_SIDtables.
Now, that you have setup the database for ch14-bankapp-db-security project, deploy the project on
embeddedTomcat7serverbyexecutingthetomcat7:rungoalfromtheprojectsdirectory(referappendix
AformoreinformationonhowtodeploywebprojectsonembeddedTomcat7server).Oncetheproject
issuccessfullydeployed,gotohttp://localhost:8080/ch14-bankapp-db-securityURL.Youshouldseethe
loginpage,asshownbelow:
Figure14-5–LoginpageofMyBankwebapplication
By default, the following three users are configured for the MyBank web application: cust1
(ROLE_CUSTOMERrole),cust2(ROLE_CUSTOMERrole), and admin(ROLE_ADMIN role). When
youloginwithusernamecust1andpasswordascust1,you’llseethefixeddepositsassociatedwithcust1
customer,asshowninthefollowingfigure:
Figure14-6–Listoffixeddepositsassociatedwithcustomercust1
Asnofixeddepositsarecurrentlyassociatedwithcust1,theabovefigureshowsanemptylistoffixed
deposits.Clickingthe‘CreatenewFixedDeposit’buttonopenstheformforcreatinganewfixeddeposit.
Ifyoucreateanewfixeddeposit,it’llappearinthelistoffixeddeposits,asshownhere:
Figure14-7–Acustomercaneditfixeddepositsormakethemaccessibletotheadminuser.
Intheabovefigure,theEdit’optionallowsthecustomertoeditfixeddepositdetails,andtheProvide
accesstoadminoptionmakesthefixeddepositaccessibletotheadminuser.Theadminusercanonly
viewfixeddepositsthataremadeaccessiblebycustomers.Clickthe‘Provideaccesstoadminhyperlink
tomakethefixeddepositaccessibletotheadminuser.
Now,logoutfromtheMyBankwebapplication,andloginusingadminusernameandadminaspassword.
Theadminusercanviewallthefixeddepositsthatweremadeaccessiblebycustomers,asshownhere:
Figure14-8–Theadminusercancloseafixeddepositbyselectingthe‘Close’option
The above figure shows that the admin user can choose the ‘Close’ option to close the fixed deposit.
ClosingafixeddepositdeletesthefixeddepositfromtheFIXED_DEPOSIT_DETAILStable.
To summarize, you can login using cust1/cust1, cust2/cust2 and admin/admin credentials to see the
followingfeaturesoftheMyBankwebapplication:
§onlycust1(ROLE_CUSTOMERrole)andcust2(ROLE_CUSTOMERrole)userscancreatefixed
deposits
§ cust1 and cust2 can only edit fixed deposits that they own. For instance, cust1 can’t edit a fixed
depositcreatedbycust2.
§ cust1 andcust2 can onlymakethefixeddepositsthatthey ownaccessibletotheadmin user. For
instance,cust1cantmakeafixeddepositcreatedbycust2accessibletotheadminuser.
§adminuser(ROLE_ADMINrole)canonlyviewfixeddepositsthataremadeaccessiblebycust1
andcust2users
§onlytheadminusercanclosefixeddeposits
Before delving into the implementation details of MyBank web application, lets look at the standard
databasetablesrequiredbySpringSecuritytostoreACLanduserinformation.
DatabasetablestostoreACLanduserinformation
SpringSecuritysACLmoduleprovidesdomainobjectinstancesecurity.MyBankwebapplicationuses
Spring Securitys ACL module to secure instances of FixedDepositDetails. Spring Security tables
(ACL_CLASS,ACL_ENTRY,ACL_OBJECT_IDENTITYandACL_SID)containpermissionsthatapply
tofixeddepositsstoredintheFIXED_DEPOSIT_DETAILStable.WhenaFixedDepositDetailsinstance
is accessed, Spring Securitys ACL module verifies that the authenticated user has the necessary
permissionstooperateontheFixedDepositDetailsinstance.
LetslookateachoftheSpringSecuritytablesthatareusedtostoreACLinformation.
ACL_CLASStable
ACL_CLASS table contains the fully-qualified name of domain classes whose instances we want to
secureinourapplication.IncaseofMyBankwebapplication,theACL_CLASStablecontainsthefully-
qualifiednameoftheFixedDepositDetailsclass,asshownhere:
Figure14-9ACL_CLASStable
Tablecolumndescription
id–containstheprimarykey
class–fully-qualifiednameofthedomainclasswhoseinstanceswewanttosecure
ACL_SIDtable
ACL_SIDtable(SIDmeanssecurityidentity’)containstheprincipals(thatis,usernames)orauthorities
(thatis,roles)inthesystem.IncaseofMyBankwebapplication,ACL_SIDtablecontainsadmin,cust1
andcust2usernames,asshownhere:
Tablecolumndescription
id–containstheprimarykey
principal–specifieswhetherthesidcolumnstoresroleorusername.Thevaluetruespecifiesthatthesid
columnstoresusername.Thevaluefalsespecifiesthatthesidcolumnstoresrole.
sid–containsusernameorrole
ACL_OBJECT_IDENTITYtable
ACL_OBJECT_IDENTITYtablecontainsidentitiesofdomainobjectsthatwewanttosecure.Incaseof
MyBank web application, the ACL_OBJECT_IDENTITY table contains identities of fixed deposits
storedinFIXED_DEPOSIT_DETAILStable,asshownhere:
Figure14-11ACL_OBJECT_IDENTITYtable
In the above figure, the object_id_identity column contains identities of fixed deposits stored in the
FIXED_DEPOSIT_DETAILStable.
Tablecolumndescription
id–containstheprimarykey
object_id_class–referstothedomainclassdefinedintheACL_CLASStable
object_id_identity–referstothedomainobjectinstanceintheFIXED_DEPOSIT_DETAILStable
parent_object – if a parent object exists for the domain object referenced by the object_id_identity
column,thiscolumnreferstotheidentityoftheparentobject
owner_sid–referstotheuserorrolethatownsthedomainobjectinstance
entries_inheriting–flagthatindicateswhethertheobjectinheritsACLentriesfromanyparentACLentry
ornot
ACL_ENTRYtable
ACL_ENTRY table contains permissions (read, write, create, and so on) assigned to users on domain
objects. In case of MyBank web application, the ACL_ENTRY table contains permissions assigned to
usersonfixeddepositsstoredinFIXED_DEPOSIT_DETAILStable,asshownhere:
Figure14-12ACL_ENTRYtable
Intheabovefigure,theacl_object_identity,maskandsidcolumnsdeterminethepermissionsassignedto
auser(orrole)onadomainobjectinstance.YoushouldnotethatanentryintheACL_ENTRYtableis
commonlyreferredtoasACE(AccessControlEntry).
Tablecolumndescription
id–containstheprimarykey
acl_object_identity – refers to the id column of the ACL_OBJECT_IDENTITY table, which in turn
identifiesthedomainobjectinstance
ace_order–specifiestheorderingoftheaccesscontrolentries
sid–referstotheidcolumnofACL_SIDtable,whichinturnidentifiestheuser(orrole)
mask–specifiesthepermissions(read,write,create,andsoon)assignedtotheuser(orrole).1means
read,2meanswrite,8meansdeleteand16meansadministrationpermission.
granting – flag that indicates whether the entry in the mask column identifies as granting access or
denyingaccess.Forinstance,ifthevalueinthemaskcolumnis1andgrantingcolumnistrue,itmeans
thatthecorrespondingSIDhasreadaccess.But,ifthevalueinthemaskcolumnis1andgrantingcolumn
isfalse,itmeansthatthecorrespondingSIDdoesn’thavereadaccess.
audit_success–flagthatindicateswhethertoauditsuccessfulpermissionsornot.Laterinthischapter,
we’llseethatSpringSecuritysConsoleAuditLoggercanbeusedtologsuccessfulpermissions.
audit_failure-flagthatindicateswhethertoauditfailedpermissionsornot.Laterinthischapter,we’ll
seethatSpringSecuritysConsoleAuditLoggercanbeusedtologfailedpermissions.
Asexplainedsofar,thediagram14-13depictsrelationshipbetweenACLtables.Thearrowsinthefigure
representforeignkeyreferencesfromatable.Forinstance,theACL_OBJECT_IDENTITYtablecontains
foreignkeysthatrefertoACL_CLASS,ACL_SIDandFIXED_DEPOSIT_DETAILStables.
Figure14-13 ACL tables and their relationships. The arrows represent foreign key references from a
table.
Now,thatwehaveseentheACLtablesrequiredtostoreACLinformation,letsnowlookattheSpring
Securitytablesthatstoreusersandtheirrolesinformation.
USERStable
USERStablestorescredentialsofusers,asshownhere:
Figure14-14USERStable
Tablecolumndescription
username–usernameoftheuser
password–passwordoftheuser
enabled–flagthatindicateswhethertheuserisenabledordisabled
AUTHORITIEStable
AUTHORITIEStablecontainstheroleassignedtoeachuserdefinedintheUSERStable
Tablecolumndescription
username–usernameoftheuser
authority–roleassignedtotheuser
Figure14-15AUTHORITIEStable
LetsnowlookathowtheusersareauthenticatedinMyBankwebapplication.
Userauthentication
MyBank web application explicitly configures the UserDetailsService to load user details from the
USERSandAUTHORITIESdatabasetables,asshowninthefollowingexamplelisting:
Examplelisting14-8–applicationContext-security.xml
Project–ch14-bankapp-db-security
Sourcelocation-src/main/resources/META-INF/spring
<authentication-manager>
<authentication-provideruser-service-ref="userDetailsService"/>
</authentication-manager>
<beans:beanid="userDetailsService"
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<beans:propertyname="dataSource"ref="dataSource"/>
</beans:bean>
Intheaboveexamplelisting,theuser-service-refattributeof<authentication-provider>elementrefersto
an implementation of UserDetailsService that is responsible for loading user (and their authorities)
details based on the supplied username. JdbcDaoImpl is an implementation of UserDetailsService that
loadsuser(andtheirauthorities)detailsfromthedatasource(specifiedbythedataSourceproperty)using
JDBCqueries.RefertotheapplicationContext.xmlfileofch14-bankapp-db-securityprojecttoviewthe
dataSourcebeandefinition.Bydefault,JdbcDaoImplloadsuserdetailsfromtheUSERS(referfigure14-
14)tableandauthoritiesinformationfromtheAUTHORITIES(referfigure14-15)table.Ifyoualready
havecustomdatabasetablesthatcontainuserandauthoritiesdetails,thensettheusersByUsernameQuery
andauthoritiesByUsernameQuerypropertiesofJdbcDaoImpltoretrieveuserdetailsandtheirauthorities
fromthesecustomtables.
TheusersByUsernameQuerypropertyspecifiestheSQLquerytoretrieveuserdetailsbasedonthegiven
username. If user details are stored in a table named MY_USERS that contains USERNAME and
PASSWORD columns, you can set the following SQL query as the value of usersByUsernameQuery
propertytoretrieveuserdetails:
selectUSERNAME,PASSWORD,‘true’asENABLEDfromMY_USERSwhereUSERNAME=?
You should note that the columns returned by the SQL query must be USERNAME, PASSWORD and
ENABLED.Ifaparticularcolumn(like,ENABLED)doesn’texistinyourdatabasetable,thenreturna
defaultvalue(like,‘true’)forthatcolumn.
TheauthoritiesByUsernameQuerypropertyspecifiestheSQLquery toretrieve authorities basedonthe
givenusername.IfauthoritydetailsarestoredinatablenamedMY_AUTHORITIESthatcontainsUSER
andROLEcolumns, youcan set the followingSQLquery as the value of authoritiesByUsernameQuery
propertytoretrieveauthorities:
selectUSERASUSERNAME,ROLEASAUTHORITYfromMY_AUTHORITIESwhereUSER=?
YoushouldnotethatthecolumnsreturnedbytheSQLquerymustbeUSERNAMEandAUTHORITY.
Ifyourapplicationstoresencodedpasswordsinthedatabase,youcanusethe<password-encoder>sub-
element of <authentication-provider> element to specify the password encoder (an implementation of
SpringsPasswordEncoderinterface)tobeusedtoconvertthesubmittedpasswordsintotheirencoded
form. BCryptPasswordEncoder is a concrete implementation of PasswordEncoder that uses BCrypt
hashing algorithm (http://en.wikipedia.org/wiki/Bcrypt). The DaoAuthenticationProvider uses the
configured password encoder to encode the submitted password and compare it with the password
loadedbytheUserDetailsService.
LetsnowlookatthewebrequestsecurityconfigurationintheMyBankwebapplication.
Webrequestsecurity
The following example listing shows how web request security is configured for the MyBank web
application:
Examplelisting14-9–applicationContext-security.xml–websecurityconfiguration
Project–ch14-bankapp-db-security
Sourcelocation-src/main/resources/META-INF/spring
<httpuse-expressions="true">
<access-denied-handlererror-page="/access-denied"/>
<intercept-urlpattern="/fixedDeposit/*"
access="hasAnyRole('ROLE_CUSTOMER','ROLE_ADMIN')"/>
<form-loginlogin-page="/login"authentication-failure-handler-ref="authFailureHandler"/>
<logout/>
....
</http>
<beans:beanid="authFailureHandler"
class="sample.spring.chapter14.security.MyAuthFailureHandler"/>
If you compare the web request security configuration shown above with the one we saw in ch14-
bankapp-simple-security project (refer example listing 14-2), youll notice that we have added some
additionalconfigurationinformation.
The <access-denied-handler> element’s error-page attribute specifies the error page (refer to
scr/main/webapp/WEB-INF/jsp/access-denied.jsppage)to which anauthenticateduser isredirectedin
case the user attempts to access an unauthorized web page. The <form-login> elements login-page
attribute specifies the URL that renders the login page. The value /login URL is mapped to
LoginController (refer to LoginController class of ch14-bankapp-db-security project) that renders the
loginpage(refer to scr/main/webapp/WEB-INF/jsp/login.jsp page). The authentication-failure-handler-
ref attribute refers to an AuthenticationFailureHandler bean that handles authentication failures. As the
above example listing shows, MyAuthFailureHandler (an implementation of
AuthenticationFailureHandler) is responsible for handling authentication failures in MyBank web
application.ThefollowingexamplelistingshowstheimplementationofMyAuthFailureHandlerclass:
Examplelisting14-10–MyAuthFailureHandlerclass
Project–ch14-bankapp-db-security
Sourcelocation-src/main/java/sample/spring/chatper14/security
packagesample.spring.chapter14.security;
.....
importorg.springframework.security.core.AuthenticationException;
importorg.springframework.security.web.authentication.AuthenticationFailureHandler;
publicclassMyAuthFailureHandlerimplementsAuthenticationFailureHandler{
@Override
publicvoidonAuthenticationFailure(HttpServletRequestrequest,
HttpServletResponseresponse,AuthenticationExceptionexception)
throwsIOException,ServletException{
request.setAttribute("exceptionMsg",exception.getMessage());
response.sendRedirect(request.getContextPath()+"/login?exceptionMsg="+
exception.getMessage());
}
}
AuthenticationFailureHandler interface defines an onAuthenticationFailure method which is invoked
when authentication fails. The onAuthenticationFailure method accepts an instance of
AuthenticationException that represents an authentication failure. In the above example listing, the
onAuthenticationFailuremethodredirectstheusertotheloginpageandpassestheexceptionmessageasa
querystringparameter.Ifyouenterwrongcredentials(orentercredentialsofauserwhoisdisabledin
thesystem)ontheloginpageofMyBankwebapplication,youllnoticethattheMyAuthFailureHandlers
onAuthenticationFailuremethod isinvoked.Forinstance,ifyouenter wrongcredentials, youllseethe
message‘Badcredentials’.
LetsnowlookatACL-specificconfigurationinMyBankwebapplication.
JdbcMutableAclServiceconfiguration
As ACL permissions are stored in database tables, the MyBank web application uses Springs
JdbcMutableAclService to perform CRUD (CreateRead Update Delete) operations on ACLs in the
tables.ThefollowingexamplelistingshowstheconfigurationofJdbcMutableAclService:
Examplelisting14-11–applicationContext-security.xml–JdbcMutableAclServiceconfiguration
Project–ch14-bankapp-db-security
Sourcelocation-src/main/resources/META-INF/spring
<beans:beanid="aclService"class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
<beans:constructor-argref="dataSource"/>
<beans:constructor-argref="lookupStrategy"/>
<beans:constructor-argref="aclCache"/>
</beans:bean>
The above example listing shows references to dataSource, lookupStrategy and aclCache beans are
passed to the JdbcMutableAclServices constructor. Let’s now look at how dependencies (dataSource,
lookupStrategyandaclCache)ofJdbcMutableAclServiceareconfigured.
The dataSource bean identifies the javax.sql.DataSource that holds the ACL tables (refer to the
dataSourcebeandefinitionintheapplicationContext.xmlfileformoredetails).
The lookupStrategy bean represents an implementation of Springs LookupStrategy interface that is
responsible for looking up ACL information. The following example listing shows the lookupStrategy
beandefinition:
Examplelisting14-12–applicationContext-security.xml–LookupStrategyconfiguration
Project–ch14-bankapp-db-security
Sourcelocation-src/main/resources/META-INF/spring
<beans:beanid="lookupStrategy"
class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
<beans:constructor-argref="dataSource"/>
<beans:constructor-argref="aclCache"/>
<beans:constructor-arg>
<beans:beanclass="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<beans:constructor-argvalue="ROLE_ADMIN"/>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
</beans:constructor-arg>
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy">
<beans:constructor-arg>
<beans:beanclass="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
</beans:constructor-arg>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
In the above example listing, Springs BasicLookupStrategy (an implementation of
LookupStrategy interface) uses JDBC queries to fetch ACL details from standard ACL tables
(ACL_CLASS, ACL_ENTRY, ACL_SID and ACL_OBJECT_IDENTITY). If the ACL information is
stored in custom database tables, then you can customize the JDBC queries by setting selectClause,
lookupPrimaryKeysWhereClause, lookupObjectIdentitiesWhereClause and orderByClause properties of
BasicLookupStrategy. For more details on these properties, please refer to the API documentation of
SpringSecurity.
BasicLookupStrategys constructor accepts arguments of type DataSource (represents the database that
contains the ACL tables), AclCache (represents the ACL caching layer),
AclAuthorizationStrategy (represents the strategy to determine if a SIDhas the permissions to perform
administrative actions on the ACL entries of a domain object instance), and
PermissionGrantingStrategy (strategy to grant or deny access to secured objects depending on the
permissionsassignedtoSIDs).
In the above example listing, the AclAuthorizationStrategyImpl class implements
AclAuthorizationStrategy. The AclAuthorizationStrategyImpls constructor accepts an instance of
GrantedAuthoritythatspecifiestherolethatcanperformadministrativeactions(like,changingownership
ofanACLentry)ontheACLentries(representedbyanobjectoftypeMutableAcl)ofadomainobject
instance. In the above example listing, ROLE_ADMIN role is passed to the
AclAuthorizationStrategyImpl, which means that a user with ROLE_ADMIN role can perform
administrativeactionsonACLentries.Laterinthischapter,we’llseethattheAclAuthorizationStrategy
securestheMutableAclinstancefromunauthorizedmodification.
In the above example listing, the DefaultPermissionGrantingStrategy implements
PermissionGrantingStrategy.TheDefaultPermissionGrantingStrategysconstructoracceptsaninstanceof
AuditLogger that logs success and/or failure in granting permissions for an ACL entry in the
ACL_ENTRY table. In the above example listing, the ConsoleAuditLogger (an implementation of
AuditLoggerthatwritesontheconsole)logssuccessfulpermissionsifaudit_successcolumnsvalueis
settotrue(thatis,1),andlogsfailedpermissionsifaudit_failurecolumnsvalueissettotrue(thatis,1).
Forinstance,thefollowingmessageshowsoutputfromtheConsoleAuditLoggeronsuccessfulpermission
toanACLentry:
GRANTEDduetoACE:AccessControlEntryImpl[id:1037;granting:true;sid:PrincipalSid[cust1];permission:
BasePermission[...............................R=1];auditSuccess:true;auditFailure:true]
BasicLookupStrategy accepts an instance of AclCache object (represented by the aclCache bean in
example listing 14-12) that represents a cache for ACLs. The following example listing shows the
aclCachebeandefinitionthatisusedbyBasicLookupStrategytocacheACLs:
Examplelisting14-13–applicationContext-security.xml–Cacheconfiguration
Project–ch14-bankapp-db-security
Sourcelocation-src/main/resources/META-INF/spring
<beans:bean id="aclCache"
class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
<beans:constructor-arg>
<beans:beanclass="org.springframework.cache.ehcache.EhCacheFactoryBean">
<beans:propertyname="cacheManager">
<beans:beanclass="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
</beans:property>
<beans:propertyname="cacheName"value="aclCache"/>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
EhCacheBasedAclCache is an implementation of AclCache that uses EhCache (http://ehcache.org/) for
caching ACLs. EhCacheFactoryBean is Spring FactoryBean that creates an instance of
net.sf.ehcache.EhCache. The cacheManager property of EhCacheFactoryBean specifies the
net.sf.ehcache.CacheManagerinstancethatisresponsibleformanagingthecache.Intheaboveexample
listing, EhCacheManagerFactoryBean is a Spring FactoryBean that creates an instance of
net.sf.ehcache.CacheManager.TheEhCacheFactoryBeanscacheNamepropertyreferstothecacheregion
tobecreatedinEhCacheforstoringACLs.
Now,thatwehaveconfiguredJdbcMutableAclServicetoperformCRUDoperationsonACLs,letslook
at the method-level security configuration that uses ACLs loaded by JdbcMutableAclService for
authorizationpurposes.
Method-levelsecurityconfiguration
Thefollowingexamplelistingshowsmethod-levelsecurityconfigurationintheMyBankwebapplication:
Examplelisting14-14–applicationContext-security.xml–Method-levelsecurityconfiguration
Project–ch14-bankapp-db-security
Sourcelocation-src/main/resources/META-INF/spring
<global-method-securitypre-post-annotations="enabled">
<expression-handlerref="expressionHandler"/>
</global-method-security>
The <global-method-security> element’s pre-post-annotations attribute value is set to enabled, which
enables use of @PreAuthorize (explained earlier in this chapter), @PostAuthorize, @PostFilter and
@PostAuthorizeannotations.Intheaboveexamplelisting,the<expression-handler>elementreferstothe
expressionHandlerbeanthatconfiguresaSecurityExpressionHandlerinstance.
ASecurityExpressionHandlerisusedbySpringSecuritytoevaluatesecurityexpressions,likehasRole,
hasAnyRole,hasPermission,andsoon.ThefollowingexamplelistingshowstheexpressionHandlerbean
definition that configures a DefaultMethodSecurityExpressionHandler (a SecurityExpressionHandler
implementation)instance:
Examplelisting14-15–applicationContext-security.xml–SecurityExpressionHandlerconfiguration
Project–ch14-bankapp-db-security
Sourcelocation-src/main/resources/META-INF/spring
<beans:beanid="expressionHandler"class="org.springframework.security.access.expression.method.
DefaultMethodSecurityExpressionHandler">
<beans:propertyname="permissionEvaluator"ref="permissionEvaluator"/>
<beans:propertyname="permissionCacheOptimizer">
<beans:beanclass="org.springframework.security.acls.AclPermissionCacheOptimizer">
<beans:constructor-argref="aclService"/>
</beans:bean>
</beans:property>
</beans:bean>
<beans:beanid="permissionEvaluator"
class="org.springframework.security.acls.AclPermissionEvaluator">
<beans:constructor-argref="aclService"/>
</beans:bean>
In the above example listing, the permissionEvaluator property refers to an instance of
AclPermissionEvaluator instance that uses ACLs to evaluate security expressions. The
permissionCacheOptimzer property refers to an instance of AclPermissionCacheOptimizer that loads
ACLsinbatchestooptimizeperformance.
LetsnowlookathowdomainobjectinstancesecurityisachievedintheMyBankwebapplication.
Domainobjectinstancesecurity
We saw earlier that the @PreAuthorize annotation specifies role-based security constraints on the
methods. If a @PreAuthorize annotated method accepts a domain object instance as an argument, the
@PreAuthorizeannotationcanspecifytheACLpermissionsthattheauthenticatedusermusthaveonthe
domainobjectinstance to invoke themethod. The following examplelisting showsthe @PreAuthorize
annotationthatspecifiesACLpermissions:
Example listing 14-16 – FixedDepositService interface – @PreAuthorize annotation with ACL
permissions
Project–ch14-bankapp-db-security
Sourcelocation-src/main/java/sample/spring/chatper14/service
packagesample.spring.chapter14.service;
importorg.springframework.security.access.prepost.PreAuthorize;
importsample.spring.chapter14.domain.FixedDepositDetails;
.....
publicinterfaceFixedDepositService{
.....
@PreAuthorize("hasPermission(#fixedDepositDetails,write)")
voideditFixedDeposit(FixedDepositDetailsfixedDepositDetails);
}
Intheaboveexamplelisting,theFixedDepositService’seditFixedDepositmethodacceptsaninstanceof
FixedDepositDetails. In the hasPermission expression, #fixedDepositDetails represents an expression
variable that refers to the FixedDepositDetails instance passed to the editFixedDeposit method. The
hasPermission expression evaluates to true if the authenticated user has write permission on the
FixedDepositDetails instance passed to the editFixedDeposit method. At runtime, the hasPermission
expressionisevaluatedby the configured AclPermissionEvaluator (refer example listing 14-15). If the
hasPermissionevaluatestotrue,theeditFixedDepositmethodisinvoked.
If a method accepts a domain objectidentifier (instead of the actual domain object instance) as an
argument,youcanstillspecifyACLpermissionsthatapplytothedomainobjectinstancereferredbythe
identifier. The following example listing shows the provideAccessToAdmin method that accepts
fixedDepositId(whichuniquelyidentifiesaFixedDepositDetailsinstance)asargument:
Examplelisting14-17–FixedDepositServiceinterface–@PreAuthorizeannotationusage
Project–ch14-bankapp-db-security
Sourcelocation-src/main/java/sample/spring/chatper14/service
packagesample.spring.chapter14.service;
importorg.springframework.security.access.prepost.PreAuthorize;
.....
publicinterfaceFixedDepositService{
.....
@PreAuthorize("hasPermission(#fixedDepositId,
'sample.spring.chapter14.domain.FixedDepositDetails',write)")
voidprovideAccessToAdmin(intfixedDepositId);
}
Intheaboveexamplelisting,#fixedDepositIdexpressionvariablereferstothefixedDepositIdargument
passedtotheprovideAccessToAdminmethod.AsthefixedDepositIdargumentidentifiesaninstanceof
FixedDepositDetailsobject,thefully-qualifiednameoftheFixedDepositDetailsclassisspecifiedasthe
second argument of hasPermission expression. The hasPermission(#fixedDepositId,
‘sample.spring.chapter14.domain.FixedDepositDetails,write)evaluatestotrueiftheauthenticateduser
has write permission on the FixedDepositDetails instance identified by the fixedDepositId argument
passedtotheprovideAccessToAdminmethod.
Itisalsopossibletocombinemultiplesecurityexpressionstoformamorecomplexsecurityexpression,
asshowninthefollowingexamplelisting:
Examplelisting14-18–FixedDepositServiceinterface–@PreAuthorizeannotationusage
Project–ch14-bankapp-db-security
Sourcelocation-src/main/java/sample/spring/chatper14/service
packagesample.spring.chapter14.service;
importorg.springframework.security.access.prepost.PreAuthorize;
.....
publicinterfaceFixedDepositService{
.....
@PreAuthorize("hasPermission(#fixedDepositId,
'sample.spring.chapter14.domain.FixedDepositDetails',read)or"
+"hasPermission(#fixedDepositId,
'sample.spring.chapter14.domain.FixedDepositDetails',admin)")
FixedDepositDetailsgetFixedDeposit(intfixedDepositId);
.....
}
Intheaboveexamplelisting,thetwohasPermissionexpressionshavebeencombinedusingoroperatorto
formamoresophisticatedsecurityexpression.ThegetFixedDepositmethodwillbeinvokedonlyifthe
authenticated userhas read or admin permission on the FixedDepositDetails instance identified by the
fixedDepositIdargument.
If a method returns a list of domain object instances, you can filter the results by using @PostFilter
annotation.Thefollowingexamplelistingshowsusageof@PostFilterannotation:
Examplelisting14-19–FixedDepositServiceinterface–@PostFilterannotationusage
Project–ch14-bankapp-db-security
Sourcelocation-src/main/java/sample/spring/chatper14/service
packagesample.spring.chapter14.service;
importorg.springframework.security.access.prepost.PostFilter;
.....
publicinterfaceFixedDepositService{
.....
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostFilter("hasPermission(filterObject,read)orhasPermission(filterObject,admin)")
List<FixedDepositDetails>getAllFixedDeposits();
.....
}
Like @PreAuthorize annotation, @PostFilter specifies a security expression. If a method is annotated
with @PostFilter annotation, Spring Security iterates over the collection returned by the method and
removes the elements for which the specified security expression returns false. In the above example
listing, Spring Security iterates over the collection of FixedDepositDetails instances returned by the
getAllFixedDepositsmethodandremovestheinstancesforwhichtheauthenticateduserdoesn’thaveread
or admin permission. The term filterObject in the hasPermission expression of @PostFilter annotation
referstothecurrentobjectinthecollection.NoticethatthegetAllFixedDepositsmethodisalsoannotated
with@PreAuthorizeannotation,whichindicatesthatthegetAllFixedDepositsmethodisonlyinvokedif
theauthenticateduserhasROLE_ADMINrole.
Wesawearlierthatacustomer(ROLE_CUSTOMERrole)makesafixeddepositavailabletotheadmin
user(ROLE_ADMINrole)byclickingtheProvideaccesstoadminhyperlink(referfigure14-7).When
thecustomerclickstheProvideaccesstoadmin,applicationgrantsread,adminanddeletepermissions
onthefixeddeposittotheadminuser.We’llseelaterinthischapterhowthisisdoneprogrammatically.
The FixedDepositServices getAllFixedDeposits method is invoked when a user with ROLE_ADMIN
rolevisitsthewebpagethatshowslistsoffixeddeposits(referfigure14-8).Astheadminusershould
onlybeabletoseefixeddepositsforwhichcustomershavegrantedpermissions,thegetAllFixedDeposits
method is annotated with @PostFilter annotation to remove fixed deposits on which the admin user
doesnthavereadoradminpermission.
LetsnowlookathowtoprogrammaticallymanageACLentries.
ManagingACLentriesprogrammatically
YoucanmanageACLentriesprogrammaticallybyusingtheJdbcMutableAclServicethatwasconfigured
intheapplicationcontextXMLfile(referexamplelisting14-11).
When a customer creates a new fixed deposit, read and write permissions on the newly created fixed
deposit are granted to the customer. When a customer clicks the ‘Provide access to admin hyperlink
correspondingtoafixeddeposit,theMyBankwebapplicationgrantsread,adminanddeletepermissions
onthefixeddeposittotheadminuser.
ThefollowingexamplelistingshowstheFixedDepositServiceImplsprovideAccessToAdminmethodthat
isinvokedwhenthe‘Provideaccesstoadminhyperlinkisclicked:
Examplelisting14-20–FixedDepositServiceImplclass–addingACLpermissions
Project–ch14-bankapp-db-security
Sourcelocation-src/main/java/sample/spring/chatper14/service
packagesample.spring.chapter14.service;
importorg.springframework.security.acls.domain.*;
importorg.springframework.security.acls.model.*;
.....
@Service
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
@Autowired
privateMutableAclServicemutableAclService;
@Override
publicvoidprovideAccessToAdmin(intfixedDepositId){
addPermission(fixedDepositId,newPrincipalSid("admin"),BasePermission.READ);
addPermission(fixedDepositId,newPrincipalSid("admin"),BasePermission.ADMINISTRATION);
addPermission(fixedDepositId,newPrincipalSid("admin"),BasePermission.DELETE);
}
privatevoidaddPermission(longfixedDepositId,Sidrecipient,Permissionpermission){.....}
}
Intheaboveexamplelisting,theprovideAccessToAdminmethodusestheaddPermissionmethodtogrant
read, admin and delete permissions to the admin user. The following arguments are passed to the
addPermissionmethod:
§fixedDepositId–uniquelyidentifiestheFixedDepositDetails instance on whom wewantto grant
permissions
§  PrincipalSid object - represents the SID (that is, the user or role) whom we want to grant
permissions.ThePrincipalSidclassimplementsSpringSecuritysSidinterface.
§ permission to grant – The BasePermission class defines constants, like READ,
ADMINISTRATION,DELETE,andsoon,representingstandardpermissionsthatwecangrantto
PrincipalSid.TheBasePermissionclassimplementsSpringSecuritysPermissioninterface.
ThefollowingexamplelistingshowstheimplementationofaddPermissionmethod:
Examplelisting14-21–FixedDepositServiceImplclass–addingACLpermissions
Project–ch14-bankapp-db-security
Sourcelocation-src/main/java/sample/spring/chatper14/service
packagesample.spring.chapter14.service;
importorg.springframework.security.acls.domain.*;
importorg.springframework.security.acls.model.*;
.....
@Service
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
@Autowired
privateMutableAclServicemutableAclService;
.....
privatevoidaddPermission(longfixedDepositId,Sidrecipient,Permissionpermission){
MutableAclacl;
ObjectIdentityoid=newObjectIdentityImpl(FixedDepositDetails.class,fixedDepositId);
try{
acl=(MutableAcl)mutableAclService.readAclById(oid);
}catch(NotFoundExceptionnfe){
acl=mutableAclService.createAcl(oid);
}
acl.insertAce(acl.getEntries().size(),permission,recipient,true);
mutableAclService.updateAcl(acl);
}
.....
}
As JdbcMutableAclService class implements MutableAclService interface, JdbcMutableAclService
instanceisautowiredintotheFixedDepositServiceImplclass.
Tograntpermissions,theaddPermissionmethodfollowsthesesteps:
1)declaresanobjectoftypeMutableAcl.AMutableAclobject representsACLentriesof adomain
objectinstance.MutableAcldefinesmethodsthatyoucanusetomodifyACLentries.
2)    creates an instance of ObjectIdentityImpl by passing domain object type (which is
FixedDepositDetails.class)andidentity(whichisfixedDepositId)asargumentstotheconstructor
3)    retrieves the ACL entries for the domain object instance by calling MutableAclService’s
readAclById method. If no ACL entries are found, the readAclById method throws
NotFoundException.
oIfNotFoundException isthrown,MutableAclServices createAcl method is used to create an
empty instance of MutableAcl that doesn’t contain any ACL entries. This is equivalent to
creatinganentryintheACL_OBJECT_IDENTITYtable(referfigure14-11).
4)  adds ACL entries to the MutableAcl instance using insertAce method. The ACL entries added to
MutableAclareeventuallypersistedintotheACL_ENTRYtable(referfigure14-12).Thearguments
passed to the insertAce method are - the index location where the ACL entry is to be added
(corresponds to the ACE_ORDER column), the permission to be added (corresponds to the MASK
column),theSIDforwhomthepermissionistobeadded(correspondstotheSIDcolumn),andthe
flag indicating that the ACL entry is for granting or denying permission (corresponds to the
GRANTINGcolumn).
5)persistschangesmadetotheMutableAclinstanceusingMutableAclService’supdateAclmethod.
The following example listing shows FixedDepositServiceImpls closeFixedDeposit method that is
invokedwhentheadminuserclicksthe‘Close’hyperlinktocloseafixeddeposit(referfigure14-8):
Examplelisting14-22–FixedDepositServiceImplclass–removingACLs
Project–ch14-bankapp-db-security
Sourcelocation-src/main/java/sample/spring/chatper14/service
packagesample.spring.chapter14.service;
importorg.springframework.security.acls.domain.ObjectIdentityImpl;
importorg.springframework.security.acls.model.MutableAclService;
importorg.springframework.security.acls.model.ObjectIdentity;
.....
@Service
publicclassFixedDepositServiceImplimplementsFixedDepositService{
.....
@Autowired
privateMutableAclServicemutableAclService;
.....
@Override
publicvoidcloseFixedDeposit(intfixedDepositId){
fixedDepositDao.closeFixedDeposit(fixedDepositId);
ObjectIdentityoid=newObjectIdentityImpl(FixedDepositDetails.class,fixedDepositId);
mutableAclService.deleteAcl(oid,false);
}
.....
}
Intheaboveexamplelisting,MutableAclServicesdeleteAclmethodisusedtodeleteACLentriesofthe
fixed deposit identified by the ObjectIdentity instance. For instance, if the fixedDepositId is 101,
deleteAclmethoddeletesallACLentriesoffixeddeposit101fromACL_ENTRY(referfigure14-12)
andACL_OBJECT_IDENTITY(referfigure14-11)tables.
LetsnowlookathowMutableAclinstanceissecuredfromunauthorizedmodifications.
MutableAclandsecurity
Spring Securitys MutableAcl interface defines methods for modifying ACL entries of a domain object
instance.WesawthattheMyBankwebapplicationusesMutableAclsinsertAcemethodtoaddanACL
entry for a domain object instance (refer example listing 14-21). The
AclAuthorizationStrategyImplinstancethatwesuppliedtotheBasicLookupStrategy(referexamplelisting
14-12) is used behind the scenes to ensure that the authenticated user has appropriate permissions to
modifyACLentries.
AnauthenticatedusercanmodifyACLentriesofadomainobjectinstanceifatleastoneofthefollowing
conditionsistrue:
§iftheauthenticateduserownsthedomainobjectinstance,theusercanmodifytheACLentriesofthat
domainobjectinstance
§  if the authenticated user holds the authority that was passed to AclAuthorizationStrategyImpls
constructor. In example listing 14-12, the ROLE_ADMIN role was passed to
AclAuthorizationStrategyImpls constructor; therefore, a user with ROLE_ADMIN role can make
changestoACLentriesofanydomainobjectinstance.
§ if the authenticated user has BasePermissions ADMINISTRATION permission on the domain
objectinstance.
14-5Summary
In this chapter, we lookedathowto useSpring Securityframeworkto secureSpringapplications. We
looked at how to incorporate web request security, method-level security, and domain object instance
security.
Appendix A Importing and deploying sample projects in
EclipseIDE(orIntelliJIDEA)
Inthisappendix,we’lllookathowtosetupthedevelopmentenvironment,importasampleprojectinto
EclipseIDE(orIntelliJIDEA),andrunitasastandaloneapplication(ifthesampleprojectrepresentsa
standalone Java application) or deploy it on Tomcat 7 server (if the sample project represents a web
application).
A-1Settingupthedevelopmentenvironment
Beforesettingupthedevelopmentenvironment,youneedtodothefollowing:
·DownloadandinstallEclipseIDE(orIntelliJIDEA)–YoucandownloadtheEclipseIDEfor
JavaEEDevelopersfromhttp://www.eclipse.org/downloads.ToinstallEclipseIDE,allyouneedto
doistounzipthedownloadedZIPfileintoadirectory.
·Download and install Tomcat 7 server – You can download the Tomcat 7 server from
http://tomcat.apache.org/download-70.cgi.ItisrecommendedthatyoudownloadtheTomcat7bundled
asZIPfile,andunzipthebundleintoyourlocalfilesystem.
·Download and install Maven 3 build tool – You can download Maven 3 from
http://maven.apache.org/download.cgi. To install Maven, all you need to do is to unzip the
downloaded ZIP file into a directory. Maven is used for converting the sample web projects that
accompanythisbookintoEclipseIDEorIntelliJIDEAprojects.
LetslookathowtoimportasampleprojectintoEclipseIDE.
A-2ImportingasampleprojectintoEclipseIDE(orIntelliJIDEA)
Itisrecommendedthatyoudownloadthesampleprojectsthataccompanythisbookfromthefollowing
Googlecodeproject:
https://code.google.com/p/getting-started-with-spring-framework-2edition/
Therestofthissectionassumesthatyouhavecreatedaspring-samplesdirectoryinyourlocalfilesystem
thatcontainsallthesampleprojectsthataccompanythisbook.
Tosuccessfullyimportasampleproject,youneedtodothefollowing:
§ConverttheprojectintoanEclipseIDEorIntelliJIDEAproject
§  Configure an M2_REPO classpath variable in the Eclipse IDE (or IntelliJ IDEA). M2_REPO
variable points to the localmavenrepository that contains the JAR files on which the project
depends.
Letsnowlookattheabovementionedstepsindetail.
Importingasampleproject
Each sample project contains a pom.xml file that contains configuration of Eclipse, IntelliJ IDEA and
Tomcatmavenplugins.ThesepluginsareusedbymavenforconvertingasampleprojectintoEclipseIDE
orIntelliJIDEAproject,andfordeployingtheprojectonanembeddedTomcat7instance.Youshould
note that the Tomcat Maven plugin (http://tomcat.apache.org/maven-plugin.html) is configured only for
sample projects that represent web applications. The pom.xml file also specifies the JAR files (like
spring-core,spring-beans,andsoon)onwhichtheprojectdepends.
TocreateEclipseIDEorIntelliJIDEAspecificconfigurationfilesforthesampleproject,followthese
steps:
§  Open the command prompt and set JAVA_HOME environment variable to point to Java SDK
installationdirectory:
C:\>setJAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0_25
§Gotothedirectorycontainingthesampleproject:
C:\>cdspring-samples
C:\spring-samples>cdch01-bankapp-xml
C:\spring-samples\ch01-bankapp-xml>
§AddpathofthebindirectoryofyourmaveninstallationtothePATHenvironmentvariable:
C:\spring-samples\ch01-bankapp-xml>setpath=%path%;C:\apache-maven-3.0.4\bin
§IfyouwanttoimportthesampleprojectintoEclipseIDE,executetheeclipse:eclipsegoalofMaven
EclipsePlugin(http://maven.apache.org/plugins/maven-eclipse-plugin/):
C:\spring-samples\ch01-bankapp-xml>mvneclipse:eclipse
Executing the eclipse:eclipse goal downloads dependencies of the sample project and creates
configurationfiles(like.classpathand.project)forEclipseIDE.
OR
§IfyouwanttoimportthesampleprojectintoIntelliJIDEA,executetheidea:idea goalof Maven
IDEAPlugin(http://maven.apache.org/plugins/maven-idea-plugin/):
C:\spring-web-mvc-samples\ch01-xml-config>mvnidea:idea
Executing the idea:idea goal downloads dependencies of the sample project and creates
configurationfiles(like.ipr,.imland.iws)forIntelliJIDEA.
NOTEApom.xmlfileisalsoprovidedattherootofthesourcecodedistribution,whichbuildsallthe
projects.Youcangotospring-samplesdirectoryandexecutethemvneclipse:eclipse(ormvnidea:idea)
commandtoconvertalltheprojectsintoEclipseIDE(orIntelliJIDEA)projects.
Now,importthesampleprojectintoEclipseIDEbyfollowingthesesteps:
§GotoFileàImportoption.
§SelecttheGeneralàExistingProjectsintoWorkspaceoptionfromthedialogbox,andclickNext.
§Selectthesampleproject(ex.ch01-bankapp-xml)directoryfromthefilesystem,andclickFinish.
ConfiguringtheM2_REPOclasspathvariableintheEclipseIDE
Whenyouexecutetheeclipse:eclipseoridea:ideagoal,dependenciesoftheprojectaredownloadedinto
the<home-directory>/.m2/repositorydirectory.Here,<home-directory>isthehomedirectoryoftheuser.
OnWindows,thisreferstoC:\DocumentsandSettings\myusername\.m2\repositorydirectory.Bydefault,
.classpathfilecreatedbyexecutionofeclipse:eclipsegoalreferstotheJARdependenciesoftheproject
usingM2_REPOclasspathvariable.Forthisreason,youneedtoconfigureanewM2_REPOclasspath
variableinEclipseIDEthatrefersto<home-directory>/.m2/repositorydirectory.
ToconfigureanewM2_REPOvariable,followthesesteps:
§GotoWindowsàPreferencesoption.ThiswillshowthePreferencesdialogbox.
§SelecttheJavaàBuildPathàClasspathVariablesoptioninthedialogboxtoviewtheconfigured
classpathvariables.
§Now,clickNewbuttontoconfigureanewM2_REPOclasspathvariable.Itisimportanttonotethat
yousettheM2_REPOclasspathvariableto<home-directory>/.m2/repositorydirectory.
We have now successfully imported the sample project into the Eclipse IDE and set the M2_REPO
classpath variable. If the project represents a standalone application, you can run the application by
followingthesesteps:
§InEclipseIDEsProjectExplorertab,right-clickontheJavaclassthatcontainsthemainmethodof
theapplication.YoullnowseethelistofactionsthatcanbeperformedontheselectedJavaclass.
§SelectRunAsàJavaApplicationoption.ThiswillexecutethemainmethodoftheJavaclass.
LetsnowlookathowEclipseIDEisconfiguredtoworkwithTomcat7server.
A-3ConfiguringEclipseIDEwithTomcat7server
YouneedtoopenEclipseIDEsServersviewtoconfigureEclipseIDEwithTomat7server.Toopenthe
Serversview, select Window à Show View à Serversoption from the Eclipse IDEs menu bar. To
configureaserverwithEclipseIDE,firstgototheServersview,right-clickintheServersviews,and
selectNewàServeroption.YoullnowseeaNewServerwizardwhichallowsyoutoconfigureaserver
withEclipseIDEinastep-by-stepfashion.Thefirststepis‘DefineaNewServer,whereinyouneedto
choose the type and version of the server with which you want to configure your Eclipse IDE. The
followingfigureshowsthe‘DefineaNewServerstep:
FigureA-1SelecttheTomcatserverversionthatyouwanttousewithEclipseIDE
SelectApacheàTomcatv7.0Serverastheserver,andsetTomcatv7.0’astheservername.Clickthe
NextbuttontogotothenextstepofconfiguringTomcat7serverwithEclipseIDE.Thenextstepisto
specifyinstallationdirectoryofTomcat7server,asshowninfigureA-2.
FigureA-2SpecifyTomcatserverinstallationdirectoryandsettheJavaSDKtobeusedbytheserver.
To set the Tomcat installation directory, click the Browse button (refer figure A-2) and select the
directoryinwhichyouunzippedtheTomcatZIPfile.Also,clicktheInstalledJREsbuttonandconfigure
the Java SDK to be used by Eclipse IDE for running the Tomcat server. Click the Finish button to
complete configuration of Tomcat 7 server with Eclipse IDE. Youll now be able to see the newly
configuredTomcat7serverintheServersview,asshowninthefollowingfigure:
FigureA-3TheServersviewshowsthenewlyconfiguredTomcat7server
Now,thatwehaveconfiguredTomcat7server,letslookathowtodeployasamplewebprojecttothe
configuredTomcat7server.
A-4DeployingawebprojectonTomcat7server
Todeployawebproject(ex.ch10-helloworld)onTomcat7server,followthesesteps:
§Right-clickonthesamplewebprojectinEclipseIDE’sProjectExplorertab.You’llnowseethelist
ofactionsthatcanbeperformedontheselectedwebproject.
§  If you want to simply deploy the web project, select Run AsàRun on Server option. This will
deploythewebprojectontheTomcat7serverthatweconfiguredinsectionA-3.
OR
§Ifyouwanttodeployanddebugthewebproject,thenselectDebugAsàDebugonServeroption.
ThiswilldeploythewebprojectontheTomcat7thatweconfiguredinsectionA-3,andallowyou
todebugthewebprojectbysettingbreakpointsintheEclipseIDE.
IfTomcat7serverisconfiguredcorrectlywithEclipseIDE,you’llnoticethatTomcat7serverisstarted
and the web project is deployed on it. If you now open a web browser and go to
http://localhost:8080/<sample-project-folder-name>,youllseethehomepageofthewebproject.Here,
<sample-project-folder-name>referstothenameofthefolderofthesampleproject.
RunningtheTomcat7serverinembeddedmode
AsimplerwaytodeployandrunasamplewebprojectistouseanembeddedTomcat7server.Inallthe
samplewebprojects,MavenTomcatplugin(http://tomcat.apache.org/maven-plugin-2.0/)isconfiguredin
thepom.xmlfile.Ifyouexecutetomcat7:rungoalofMavenTomcatpluginbygoingtosampleprojects
directory, the plugin takes care of downloading and starting Tomcat 7 in embedded mode and
automaticallydeployingthesamplewebprojectontheembeddedTomcat7instance.Tostoptheserver,
allyouneedtodoistopressCtrl-C.

Navigation menu