getting started with spring framework ashish sarin, j sharma€¦ · 1-3 spring ioc container 1-4...

517

Upload: others

Post on 19-Jun-2020

25 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global
Page 2: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

GettingstartedwithSpringFrameworkSecondEdition

AshishSarin,JSharma

Page 3: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

TableofcontentsPreface

HowtousethisbookConventionsusedinthisbookFeedbackandquestionsAbouttheauthors

Chapter1–IntroductiontoSpringFramework1-1Introduction1-2SpringFrameworkmodules1-3SpringIoCcontainer1-4BenefitsofusingSpringFrameworkConsistentapproachtomanaginglocalandglobaltransactionsDeclarativetransactionmanagementSecurityJMX(JavaManagementExtensions)JMS(JavaMessageService)Caching1-5AsimpleSpringapplicationIdentifyingapplicationobjectsandtheirdependenciesCreatingPOJOclassescorrespondingtoidentifiedapplicationobjectsCreatingtheconfigurationmetadataCreatinganinstanceofSpringcontainerAccessbeansfromtheSpringcontainer1-6FrameworksbuiltontopofSpring1-7Summary

Chapter2–SpringFrameworkbasics2-1Introduction2-2ProgrammingtointerfacesdesignprincipleScenario:DependentclasscontainsreferencetotheconcreteclassofdependencyScenario:DependentclasscontainsreferencetotheinterfaceimplementedbythedependencySpring’ssupportfor‘programmingtointerfaces’designapproach

Page 4: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

2-3DifferentapproachestoinstantiatingSpringbeansInstantiatingbeansviastaticfactorymethodsInstantiatingbeansviainstancefactorymethods2-4DependencyinjectiontechniquesSetter-basedDIConstructor-basedDI2-5BeanscopesSingletonPrototypeChoosingtherightscopeforyourbeans2-6Summary

Chapter3-Configuringbeans3-1Introduction3-2BeandefinitioninheritanceMyBank–BeandefinitioninheritanceexampleWhatgetsinherited?3-3ConstructorargumentmatchingPassingsimplevaluesandbeanreferencesusing<constructor-arg>elementConstructorargumentmatchingbasedontypeConstructorargumentmatchingbasedonname3-4ConfiguringdifferenttypesofbeanpropertiesandconstructorargumentsBuilt-inpropertyeditorsinSpringSpecifyingvaluesfordifferentcollectiontypesSpecifyingvaluesforarraysDefaultcollectionimplementationfor<list>,<set>and<map>elements3-5Built-inpropertyeditorsCustomCollectionEditorCustomMapEditorCustomDateEditor3-6RegisteringpropertyeditorswiththeSpringcontainerCreatingaPropertyEditorRegistrarimplementationConfiguringtheCustomEditorConfigurerclass3-7Concisebeandefinitionswithpandcnamespacesp-namespacec-namespace3-8Spring’sutilschema

Page 5: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<list><map><set><properties><constant><property-path>3-9FactoryBeaninterfaceMyBankapplication–StoringeventsinthedatabaseMyBank–FactoryBeanexampleAccessingtheFactoryBeaninstance3-10Summary

Chapter4-Dependencyinjection4-1Introduction4-2Innerbeans4-3Explicitlycontrollingthebeaninitializationorderwithdepends-onattributeMyBank–implieddependenciesbetweenbeansImplicitdependencyproblem4-4Singleton-andprototype-scopedbean’sdependenciesSingleton-scopedbean’sdependenciesPrototype-scopedbean’sdependencies4-5ObtainingnewinstancesofprototypebeansinsidesingletonbeansApplicationContextAwareinterface<lookup-method>element<replaced-method>element4-6AutowiringdependenciesbyTypeconstructorbyNamedefault/noMakingbeansunavailableforautowiringAutowiringlimitations4-7Summary

Chapter5-Customizingbeansandbeandefinitions5-1Introduction5-2Customizingbean’sinitializationanddestructionlogic

Page 6: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

MakingSpringinvokecleanupmethodspecifiedbythedestory-methodattributeCleanupmethodsandprototype-scopedbeansSpecifyingdefaultbeaninitializationanddestructionmethodsforallbeansInitializingBeanandDisposableBeanlifecycleinterfacesJSR250’s@PostConstructand@PreDestroyannotations5-3InteractingwithnewlycreatedbeaninstancesusingBeanPostProcessorBeanPostProcessorexample–ValidatingbeaninstancesBeanPostProcessorexample–ResolvingbeandependenciesBeanPostProcessorbehaviorforFactoryBeansRequiredAnnotationBeanPostProcessorDestructionAwareBeanPostProcessor5-4ModifyingbeandefinitionsusingBeanFactoryPostProcessorBeanFactoryPostProcessorexamplePropertySourcesPlaceholderConfigurerPropertyOverrideConfigurer5-5Summary

Chapter6-Annotation-drivendevelopmentwithSpring6-1Introduction6-2IdentifyingSpringcomponentswith@Component6-3@Autowired-autowiringdependenciesbytype6-4@Qualifier–autowiringdependenciesbyname6-5JSR330’s@Injectand@Namedannotations6-6JSR250’s@Resourceannotation6-7@Scope,@Lazy,@DependsOnand@Primaryannotations6-8Simplifyingcomponentconfigurationusing@Valueannotation6-9ValidatingobjectsusingSpring’sValidatorinterface6-10SpecifyingconstraintsusingJSR303annotationsJSR303supportinSpring6-11ProgrammaticallyconfiguringSpringbeansusing@Configurationand@Beanannotations6-12Summary

Chapter7-DatabaseinteractionusingSpring7-1Introduction7-2MyBankapplication’srequirements

Page 7: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

7-3DevelopingtheMyBankapplicationusingSpring’sJDBCmoduleConfiguringadatasourceCreatingDAOsthatuseSpring’sJDBCmoduleclasses7-4DevelopingtheMyBankapplicationusingHibernateConfiguringSessionFactoryinstanceCreatingDAOsthatuseHibernateAPIfordatabaseinteraction7-5TransactionmanagementusingSpringMyBank’stransactionmanagementrequirementsProgrammatictransactionmanagementDeclarativetransactionmanagementSpring’ssupportforJTA7-6Summary

Chapter8-Messaging,emailing,asynchronousmethodexecution,andcachingusingSpring8-1Introduction8-2MyBankapplication’srequirements8-3SendingJMSmessagesConfiguringActiveMQbrokertoruninembeddedmodeConfiguringaJMSConnectionFactorySendingJMSmessagesusingJmsTemplateSendingJMSmessageswithinatransactionDynamicJMSdestinationsandJmsTemplateconfigurationJmsTemplateandmessageconversion8-4ReceivingJMSmessagesSynchronouslyreceivingJMSmessagesusingJmsTemplateAsynchronouslyreceivingJMSmessagesusingmessagelistenercontainers8-5Sendingemails8-6TaskschedulingandasynchronousexecutionTaskExecutorinterfaceTaskSchedulerinterface@Asyncand@Scheduledannotations8-7CachingConfiguringaCacheManagerCachingannotations-@Cacheable,@CacheEvictand@CachePut8-8RunningtheMyBankapplication8-9Summary

Page 8: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter9-Aspect-orientedprogramming9-1Introduction9-2AsimpleAOPexample9-3SpringAOPframeworkProxycreationexpose-proxyattribute9-4Pointcutexpressions@PointcutannotationexecutionandargspointcutdesignatorsbeanpointcutdesignatorAnnotations-basedpointcutdesignators9-5AdvicetypesBeforeadviceAfterreturningadviceAfterthrowingadviceAfteradviceAroundadvice9-6SpringAOP-XMLschema-styleConfiguringanAOPaspectConfiguringanadviceAssociatingapointcutexpressionwithanadvice9-7Summary

Chapter10–SpringWebMVCbasics10-1Introduction10-2Directorystructureofsamplewebprojects10-3Understandingthe‘HelloWorld’webapplicationHelloWorldController.java–HelloWorldwebapplication’scontrollerclasshelloworld.jsp–JSPpagethatshowsthe‘HelloWorld!!’messagemyapp-config.xml–WebapplicationcontextXMLfileweb.xml–Webapplicationdeploymentdescriptor10-4DispatcherServlet–thefrontcontrollerAccessingServletContextandServletConfigobjects10-5Developingcontrollersusing@Controllerand@RequestMappingannotationsDevelopinga‘HelloWorld’webapplicationusinganannotatedcontroller10-6MyBankwebapplication’srequirements

Page 9: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-7SpringWebMVCannotations-@RequestMappingand@RequestParamMappingrequeststocontrollersorcontrollermethodsusing@RequestMapping@RequestMappingannotatedmethodsarguments@RequestMappingannotatedmethodsreturntypesPassingrequestparameterstocontrollermethodsusing@RequestParam10-8Validation10-9Handlingexceptionsusing@ExceptionHandlerannotation10-11LoadingrootwebapplicationcontextXMLfile(s)10-12Summary

Chapter11–ValidationanddatabindinginSpringWebMVC11-1Introduction11-2Addingandretrievingmodelattributesusing@ModelAttributeannotationAddingmodelattributesusingmethod-level@ModelAttributeannotationRetrievingmodelattributesusing@ModelAttributeannotationRequestprocessingand@ModelAttributeannotatedmethodsBehaviorof@ModelAttributeannotatedmethodargumentsRequestToViewNameTranslator11-3Cachingmodelattributesusing@SessionAttributesannotation11-4DatabindingsupportinSpringWebDataBinder–databinderforwebrequestparametersConfiguringaWebDataBinderinstanceAllowingordisallowingfieldsfromdatabindingprocessInspectingdatabindingandvalidationerrorsusingBindingResultobject11-5ValidationsupportinSpringValidatingmodelattributesusingSpring’sValidatorinterfaceSpecifyingconstraintsusingJSR303annotationsValidatingobjectsthatuseJSR303annotations11-6Spring’sformtaglibraryHTML5supportinSpring’sformtaglibrary11-7Summary

Chapter12–DevelopingRESTfulwebservicesusingSpringWebMVC12-1Introduction12-2Fixeddepositwebservice12-3ImplementingaRESTfulwebserviceusingSpringWebMVC

Page 10: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

JSON(JavaScriptObjectNotation)FixedDepositWSwebserviceimplementation12-4AccessingRESTfulwebservicesusingRestTemplate12-5ConvertingJavaobjectstoHTTPrequestsandresponsesandviceversausingHttpMessageConverter12-6@PathVariableand@MatrixVariableannotations12-7Summary

Chapter13–MoreSpringWebMVC–internationalization,fileuploadandasynchronousrequestprocessing13-1Introduction13-2Pre-andpost-processingrequestsusinghandlerinterceptorsImplementingandconfiguringahandlerinterceptor13-3InternationalizingusingresourcebundlesMyBankwebapplication’srequirementsInternationalizingandlocalizingMyBankwebapplication13-4AsynchronouslyprocessingrequestsAsynchronousrequestprocessingconfigurationReturningCallablefrom@RequestMappingmethodsReturningDeferredResultfrom@RequestMappingmethodsSettingdefaulttimeoutvalueInterceptingasynchronousrequests13-5TypeconversionandformattingsupportinSpringCreatingacustomConverterConfiguringandusingacustomConverterCreatingacustomFormatterConfiguringacustomFormatterCreatingAnnotationFormatterFactorytoformatonly@AmountFormatannotatedfieldsConfiguringAnnotationFormatterFactoryimplementation13-6FileuploadsupportinSpringWebMVCUploadingfilesusingCommonsMultipartResolverUploadingfilesusingStandardServletMultipartResolver13-7Summary

Chapter14–SecuringapplicationsusingSpringSecurity14-1Introduction

Page 11: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

14-2SecurityrequirementsoftheMyBankwebapplication14-3SecuringMyBankwebapplicationusingSpringSecurityWebrequestsecurityconfigurationAuthenticationconfigurationSecuringJSPcontentusingSpringSecurity’sJSPtablibrarySecuringmethods14-4MyBankwebapplication-securingFixedDepositDetailsinstancesusingSpringSecurity’sACLmoduleDeployingandusingch14-bankapp-db-securityprojectDatabasetablestostoreACLanduserinformationUserauthenticationWebrequestsecurityJdbcMutableAclServiceconfigurationMethod-levelsecurityconfigurationDomainobjectinstancesecurityManagingACLentriesprogrammaticallyMutableAclandsecurity14-5Summary

AppendixA–ImportinganddeployingsampleprojectsinEclipseIDE(orIntelliJIDEA)A-1SettingupthedevelopmentenvironmentA-2ImportingasampleprojectintoEclipseIDE(orIntelliJIDEA)ImportingasampleprojectConfiguringtheM2_REPOclasspathvariableintheEclipseIDEA-3ConfiguringEclipseIDEwithTomcat7serverA-4DeployingawebprojectonTomcat7serverRunningtheTomcat7serverinembeddedmode

Page 12: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global
Page 13: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

PrefaceHowtousethisbookDownloadsampleprojects

This book comeswithmany sample projects that you can download from the followingGoogleCodeproject:http://code.google.com/p/getting-started-with-spring-framework-2edition/.YoucandownloadthesampleprojectsasasingleZIPfileoryoucancheckoutthesampleprojectsusingSVN.Formoredetails,refertotheaboveURL.

ImportsampleprojectsintoyourEclipseorIntelliJIDEAIDE

IfyouseeIMPORTchapter<chapter-number>/<projectname>at anypointwhile reading thebook,youshouldimportthespecifiedprojectintoyourEclipseorIntelliJIDEAIDE(oranyotherIDEthatyouareusing).ThesampleprojectsuseMaven3.xbuildtoolforbuildingtheproject;therefore,you’llfindapom.xmlfileinsideeachoftheprojects.Apom.xmlfileisalsoprovidedattherootofthesourcecodedistribution,whichbuildsalltheprojects.

ReferappendixAtoseethestepsrequiredforimportingandrunningthesampleprojects.

Refertocodeexamples

Each example listing specifies the sample project name (usingProject label) and the location of thesourcefile(usingSourcelocationlabel).IftheProjectandSourcelocationlabelsarenotspecified,youcanassumethatthecodeshownintheexamplelistingisnotbeingusedanywhereinthesampleprojects,andithasbeenshownpurelytosimplifyunderstanding.

ConventionsusedinthisbookItalicshasbeenusedforemphasizingterms

Comic Sans MS has been used for example listings, Java code, configuration details in XML andpropertiesfiles

Comic Sans MS has been used in example listings to highlight important parts of the code orconfiguration

ANOTEhighlightsanimportaintpoint.

FeedbackandquestionsYou 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

AbouttheauthorsAshishSarinisaSunCertifiedEnterpriseArchitectwithmorethan14yearsofexperienceinarchitectingapplications.HeistheauthorofSpringRoo1.1Cookbook(byPacktPublishing)andPortletsinAction

Page 14: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

(byManningPublications)

JSharmaisafreelanceJavadeveloperwithextensiveexperienceindevelopingSpringapplications.

Page 15: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter1–IntroductiontoSpringFramework

Page 16: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1-1IntroductionInthetraditionalJavaenterpriseapplicationdevelopmentefforts,itwasadeveloper’sresponsibilitytocreatewell-structured,maintainableandeasilytestableapplications.Thedevelopersusedmyriaddesignpatternstoaddressthesenon-businessrequirementsofanapplication.Thisnotonlyledtolowdeveloperproductivity,butalsoadverselyaffectedthequalityofdevelopedapplications.

Spring Framework (or ‘Spring’ in short) is an open source application framework fromSpringSource(http://www.springsource.org) that simplifies developing Java enterprise applications. It provides theinfrastructurefordevelopingwell-structured,maintainableandeasily testableapplications.WhenusingSpring Framework, a developer only needs to focus on writing the business logic of the application,resultinginimproveddeveloperproductivity.YoucanuseSpringFrameworktodevelopstandaloneJavaapplications,webapplications,applets,oranyothertypeofJavaapplication.

ThischapterstartsoffwithanintroductiontoSpringFrameworkmodulesanditsbenefits.AttheheartofSpringFrameworkisitsInversionofControl(IoC)container,whichprovidesdependencyinjection(DI)feature. This chapter introducesSpring’sDI feature and IoC container, and shows how to develop astandalone Java application using Spring. Towards the end of this chapter, we’ll look at some of theSpringSource’sprojectsthatuseSpringFrameworkastheirfoundation.ThischapterwillsetthestagefortheremainingchaptersthatdelvedeeperintotheSpringFramework.

NOTEInthisbook,we’lluseanexampleInternetBankingapplication,MyBank,tointroduceSpringFrameworkfeatures.

Page 17: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1-2SpringFrameworkmodulesSpringFrameworkconsistsofmultiplemodulesthataregroupedbasedontheapplicationdevelopmentfeaturestheyaddress.ThefollowingtabledescribesthedifferentmodulegroupsinSpringFramework:

Modulegroup Description

CorecontainerContainsmodulesthatformthefoundationofSpringFramework.ThemodulesinthisgroupprovideSpring’sDIfeatureandIoCcontainerimplementation.

AOPandinstrumentation

Contains modules that support AOP (Aspect-oriented Programming) and classinstrumentation.

DataAccess/IntegrationContainsmodules that simplify interactionwith databases andmessaging providers. Thismodulegroupalsocontainsmodulesthatsupportprogrammaticanddeclarativetransactionmanagement,andobject/XMLmappingimplementations,likeJAXBandCastor.

Web Containsmodulesthatsimplifydevelopingwebandportletapplications.

Test Containsasinglemodulethatsimplifiescreatingunitandintegrationtests.

Theabove tableshowsthatSpringcoverseveryaspectofenterpriseapplicationdevelopment;youcanuseSpringfordevelopingwebapplications,accessingdatabases,managingtransactions,creatingunitandintegration tests, and soon.TheSpringFrameworkmodules aredesigned in suchaway thatyouonlyneedtoincludethemodulesthatyourapplicationneeds.Forinstance,touseSpring’sDIfeatureinyourapplication,youonlyneedtoincludethemodulesgroupedunderCorecontainer.Asyouprogressthroughthisbook,you’llfinddetailsofsomeofthemodulesthatarepartofSpring,andexamplesthatshowhowtheyareusedindevelopingapplications.

Thefollowingfigureshowstheinter-dependenciesofdifferentmodulesofSpring:

Figure1-1Springmodulesinter-dependencies

YoucaninferfromtheabovefigurethatthemodulescontainedintheCorecontainergrouparecentraltotheSpringFramework,andothermodulesdependonit.EquallyimportantarethemodulescontainedintheAOPand instrumentationgroupbecause theyprovideAOPfeatures toothermodules in theSpringFramework.

Now,thatyouhavesomebasicideaabouttheareasofapplicationdevelopmentcoveredbySpring,let’s

Page 18: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

lookattheSpringIoCcontainer.

Page 19: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1-3SpringIoCcontainerAJavaapplicationconsistsofobjectsthatinteractwitheachothertoprovideapplicationbehavior.Theobjectswithwhichanobject interactsarereferred toas itsdependencies.For instance, ifanobjectXinteractswithobjectsYandZ,thenYandZaredependenciesofobjectX.DIisadesignpatterninwhichthedependenciesofanobjectaretypicallyspecifiedasargumentstoitsconstructorandsettermethods.And,thesedependenciesareinjectedintotheobjectwhenit’screated.

In a Spring application, Spring IoC container (also referred to as Spring container) is responsible forcreating application objects and injecting their dependencies. The application objects that the Springcontainercreatesandmanagesarereferredasbeans.As theSpringcontainer isresponsibleforputtingtogetherapplicationobjects,youdon’tneedtoimplementdesignpatterns,likeFactory,ServiceLocator,andsoon,tocomposeyourapplication.DIisalsoreferredtoasInversionofControl(IoC)becausetheresponsibilityofcreatingandinjectingdependenciesisnotwiththeapplicationobjectbutwiththeSpringcontainer.

Let’ssaythattheMyBankapplication(whichisthenameofoursampleapplication)containstwoobjects,FixedDepositController and FixedDepositService. The following example listing shows that theFixedDepositControllerobjectdependsonFixedDepositServiceobject:

Examplelisting1-1:FixedDepositControllerclass

publicclassFixedDepositController{privateFixedDepositServicefixedDepositService;publicFixedDepositController(){fixedDepositService=newFixedDepositService();}publicbooleansubmit(){//--savethefixeddepositdetailsfixedDepositService.save(.....);}}

In the above example listing, FixedDepositController’s constructor creates an instance ofFixedDepositService which is later used in FixedDepositController’s submit method. AsFixedDepositController interacts with FixedDepositService, FixedDepositService represents adependencyofFixedDepositController.

To configure FixedDepositController as a Spring bean, you first need to modify theFixedDepositControllerclassofexamplelisting1-1suchthatitacceptsFixedDepositServicedependencyas a constructor argument or as a setter method argument. The following example listing shows themodifiedFixedDepositControllerclass:

Example listing 1-2: FixedDepositController class – FixedDepositService is passed as a constructorargument

Page 20: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicclassFixedDepositController{privateFixedDepositServicefixedDepositService;publicFixedDepositController(FixedDepositServicefixedDepositService){this.fixedDepositService=fixedDepositService;}publicbooleansubmit(){//--savethefixeddepositdetailsfixedDepositService.save(.....);}}

TheaboveexamplelistingshowsthattheFixedDepositServiceinstanceisnowpassedasaconstructorargumenttotheFixedDepositControllerinstance.Now,theFixedDepositServiceclasscanbeconfiguredas a Spring bean.Notice that the FixedDepositController class doesn’t implement or extend from anySpringinterfaceorclass.

Foragivenapplication,informationaboutapplicationobjectsandtheirdependenciesisspecifiedusingconfigurationmetadata. Spring IoC container reads application’s configurationmetadata to instantiateapplicationobjectsandinjecttheirdependencies.Thefollowingexamplelistingshowstheconfigurationmetadata(inXMLformat)foranapplicationthatconsistsofMyControllerandMyServiceclasses:

Examplelisting1-3:Configurationmetadata

<beans.....><beanid="myController"class="sample.spring.controller.MyController"><constructor-argindex="0"ref="myService"/></bean><beanid="myService"class="sample.spring.service.MyService"/></beans>

Intheaboveexamplelisting,each<bean>elementdefinesanapplicationobject that ismanagedbytheSpringcontainer,andthe<constructor-arg>elementspecifiesthataninstanceofMyServiceispassedasanargumenttoMyController’sconstructor.The<bean>elementisdiscussedindetaillaterinthischapter,andthe<constructor-arg>elementisdiscussedinchapter2.

Spring container reads the configuration metadata (like the one shown in example listing 1-3) of anapplication and creates the application objects defined by <bean> elements and injects theirdependencies. Spring container makes use of Java Reflection API(http://docs.oracle.com/javase/tutorial/reflect/index.html) to create application objects and inject theirdependencies.ThefollowingfiguresummarizeshowtheSpringcontainerworks:

Page 21: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure 1-2 Spring container reads application’s configurationmetadata and creates a fully-configuredapplication

TheconfigurationmetadatacanbesuppliedtotheSpringcontainerviaXML(asshowninexamplelisting1-3),Javaannotations(referchapter6)andalsothroughtheJavacode(referchapter6).

AstheSpringcontainerisresponsibleforcreatingandmanagingapplicationobjects,enterpriseservices(like transactionmanagement, security, remote access, and so on) can be transparently applied to theobjectsbytheSpringcontainer.TheabilityoftheSpringcontainertoenhancetheapplicationobjectswithadditional functionality makes it possible for you to model your application objects as simple Javaobjects(alsoreferredtoasPOJOsorPlainOldJavaObjects). JavaclassescorrespondingtoPOJOsare referred to asPOJO classes, which are nothing but Java classes that don’t implement or extendframework-specificinterfacesorclasses.Theenterpriseservices,liketransactionmanagement,security,remoteaccess,andsoon,requiredbythesePOJOsaretransparentlyprovidedbytheSpringcontainer.

Now,thatweknowhowSpringcontainerworks,let’slookatsomeexamplesthatdemonstratebenefitsofdevelopingapplicationsusingSpring.

Page 22: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1-4BenefitsofusingSpringFrameworkIntheprevioussection,wediscussedthefollowingbenefitsofusingSpring:

§ Spring simplifiescomposing Javaapplicationsby takingcareofcreatingapplicationobjectsandinjectingtheirdependencies

§SpringpromotesdevelopingapplicationsasPOJOs

SpringalsosimplifiesinteractionwithJMSproviders,JNDI,MBeanservers,emailservers,databases,andsoon,byprovidingalayerofabstractionthattakescareoftheboilerplatecode.

Let’s take a quick look at a fewexamples to better understand thebenefits of developing applicationsusingSpring.

ConsistentapproachtomanaginglocalandglobaltransactionsIf you are using Spring for developing transactional applications, you can use Spring’s declarativetransactionmanagementsupporttomanagetransactions.

ThefollowingexamplelistingshowstheFixedDepositServiceclassofMyBankapplication:

Examplelisting1-4–FixedDepositServiceclass

publicclassFixedDepositService{publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....}}

TheFixedDepositService class is a POJO class that definesmethods to create and retrieve details offixeddeposits.Thefollowingfigureshowstheformforcreatinganewfixeddeposit:

Figure1-3HTMLformforcreatinganewfixeddepositAcustomerentersthefixeddepositamount,tenureandemailidinformationintheaboveformandclickstheSave button to create a new fixed deposit. The FixedDepositService’s createFixedDepositmethod(referexamplelisting1-1)isinvokedtocreatethefixeddeposit.ThecreateFixedDepositmethoddebitstheamountenteredbythecustomerfromhisbankaccount,andcreatesafixeddepositofthesameamount.

Let’ssaythatinformationaboutthebankbalanceofcustomersisstoredinBANK_ACCOUNT_DETAILSdatabasetable,andthefixeddepositdetailsarestoredinFIXED_DEPOSIT_DETAILSdatabasetable.If

Page 23: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

a customer creates a fixed deposit of amount x, amount x is subtracted from theBANK_ACCOUNT_DETAILStable,andanewrecordisinsertedinFIXED_DEPOSIT_DETAILStabletoreflectthenewlycreatedfixeddeposit.IfBANK_ACCOUNT_DETAILStableisnotupdatedoranewrecordisnotinsertedinFIXED_DEPOSIT_DETAILStable,it’llleavethesysteminaninconsistentstate.ThismeansthecreateFixedDepositmethodmustbeexecutedwithinatransaction.

The database used by theMyBank application represents a transactional resource. In the traditionalapproach toperformasetofdatabasemodificationsasasingleunitofwork,you’ll firstdisableauto-commitmode of JDBC connection, then execute SQL statements, and finally commit (or rollback) thetransaction. The following example listing shows how to manage database transactions in thecreateFixedDepositmethodusingthetraditionalapproach:

Examplelisting1-5–ProgrammaticallymanagingdatabasetransactionusingJDBCConnectionobject

importjava.sql.Connection;importjava.sql.SQLException;publicclassFixedDepositService{publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){Connectioncon=.....;try{con.setAutoCommit(false);//--executeSQLstatementsthatmodifydatabasetablescon.commit();}catch(SQLExceptionsqle){if(con!=null){con.rollback();}}.....}}

TheaboveexamplelistingshowsthatthecreateFixedDepositmethodprogrammaticallymanagesdatabasetransactionusingJDBCConnectionobject.Thisapproachissuitableforapplicationscenariosinwhichasingledatabaseisinvolved.Transactionsthatareresource-specific,likethetransactionassociatedwithaJDBCConnection,arereferredtoaslocaltransactions.

Whenmultiple transactional resources are involved, JTA (JavaTransactionAPI) is used formanagingtransactions.Forinstance,ifyouwanttosendaJMSmessagetoamessagingmiddleware(atransactionalresource)andupdateadatabase(anothertransactionalresource)inthesametransaction,youmustuseaJTA transaction manager to manage transactions. JTA transactions are also referred to as global (ordistributed)transactions.TouseJTA,youfetchUserTransactionobject(whichispartofJTAAPI)fromJNDIandprogrammaticallystartandcommit(orrollback)transactions.

As you can see, you can either useJDBCConnection (for local transactions) orUserTransaction (for

Page 24: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

global transactions)object toprogrammaticallymanage transactions. It is important tonote thata localtransaction cannot run within a global transaction. This means that if you want database updates increateFixedDepositmethod(referexamplelisting1-5)tobepartofaJTAtransaction,youneedtomodifythecreateFixedDepositmethodtousetheUserTransactionobjectfortransactionmanagement.Spring simplifies transaction management by providing a layer of abstraction that gives a consistentapproach to managing both local and global transactions. This means that if you write thecreateFixedDepositmethod(referexample listing1-5)usingSpring’s transactionabstraction,youdon’tneedtomodifythemethodwhenyouswitchfromlocaltoglobaltransactionmanagement,orviceversa.Spring’stransactionabstractionisexplainedinchapter7.

DeclarativetransactionmanagementSpringgivesyoutheoptiontousedeclarativetransactionmanagement.YoucanannotateamethodwithSpring’s@TransactionalannotationandletSpringhandletransactions,asshownhere:

Examplelisting1-6–@Transactionalannotationusage

importorg.springframework.transaction.annotation.Transactional;publicclassFixedDepositService{publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}@TransactionalpublicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....}}

TheaboveexamplelistingshowsthattheFixedDepositServiceclassdoesn’t implementorextendfromany Spring-specific interface or class to use Spring’s transaction management facility. The SpringFramework transparently provides transaction management feature to @Transactional annotatedcreateFixedDeposit method. This shows that Spring is a non-invasive framework because it doesn’trequireyour applicationobjects tobedependent uponSpring-specific classesor interfaces.Also, youdon’tneedtodirectlyworkwithtransactionmanagementAPIstomanagetransactions.

SecuritySecurity is an important aspect of any Java application. Spring Security(http://static.springsource.org/spring-security/site/) is a SpringSource’s project that is built on top ofSpringFramework.SpringSecurityprovidesauthenticationandauthorizationfeaturesthatyoucanuseforsecuringJavaapplications.

Let’s say that the following 3 user roles have been identified for the MyBank application:LOAN_CUSTOMER, SAVINGS_ACCOUNT_CUSTOMER and APPLICATION_ADMIN. A customermustbeassociatedwiththeSAVINGS_ACCOUNT_CUSTOMERortheAPPLICATION_ADMINroletoinvoke thecreateFixedDepositmethodofFixedDepositServiceclass (refer example listing1-6).UsingSpringSecurityyoucaneasilyaddress this requirementbyannotatingcreateFixedDepositmethodwithSpringSecurity’s@Securedannotation,asshowninthefollowingexamplelisting:

Examplelisting1-7–SecuredcreateFixedDepositmethod

Page 25: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importorg.springframework.transaction.annotation.Transactional;importorg.springframework.security.access.annotation.Secured;publicclassFixedDepositService{publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}

@Transactional@Secured({"SAVINGS_ACCOUNT_CUSTOMER","APPLICATION_ADMIN"})publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....}

}

If you annotate amethodwithSpringSecurity’s@Secured annotation, security feature is transparentlyapplied to the method by the Spring Security framework. The above example listing shows that forimplementingmethod-levelsecurityyoudon’tneedtoextendorimplementanySpring-specificclassesorinterfaces.Also,youdon’tneedtowritesecurity-relatedcodeinyourbusinessmethods.

SpringSecurityframeworkisdiscussedindetailinchapter14.

JMX(JavaManagementExtensions)Spring’sJMXsupportsimplifiesincorporatingJMXtechnologyinyourapplications.

Let’ssaythatthefixeddepositfacilityofMyBankapplicationshouldonlybeavailabletocustomersfrom9:00 AM to 6:00 PM everyday. To address this requirement, a variable is added to theFixedDepositServiceclass,whichactsasaflagindicatingwhetherthefixeddepositserviceisactiveorinactive.ThefollowingexamplelistingshowstheFixedDepositServiceclassthatusessuchaflag:

Examplelisting1-8–FixedDepositServicewithactivevariable

publicclassFixedDepositService{privatebooleanactive;publicFixedDepositDetailsgetFixedDepositDetails(.....){if(active){.....}}publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){if(active){.....}}publicvoidactivateService(){active=true;}publicvoiddeactivateService(){active=false;}}

TheaboveexamplelistingshowsthatavariablenamedactiveisaddedtotheFixedDepositServiceclass.

Page 26: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

If thevalueof the activevariable is true, thegetFixedDepositDetails and createFixedDepositmethodswork as expected. If the value of the active variable is false, the getFixedDepositDetails andcreateFixedDeposit methods throw an exception indicating that the fixed deposit service is currentlyinactive.TheactivateServiceanddeactivateServicemethodssetthevalueofactivevariabletotrueandfalse,respectively.

Now, who calls the activateService and deactivateService methods? Let’s say a separate schedulerapplication, Bank App Scheduler, runs at 9:00 AM and 6:00 PM to execute activateService anddeactivateService methods, respectively. The Bank App Scheduler application uses JMX (JavaManagementExtensions)APItoremotelyinteractwithFixedDepositServiceinstance.

NOTE Refer to the following article to learn more about JMX:http://docs.oracle.com/javase/tutorial/jmx/index.html.

AsBankAppSchedulerusesJMXtochangethevalueoftheactivevariableoftheFixedDepositServiceinstance,youneedtoregistertheFixedDepositServiceinstanceasamanagedbean(orMBean)withanMBean server, and expose FixedDepositService’s activateService and deactivateService methods asJMXoperations.InSpring,youregisterinstancesofaclasswiththeMBeanserverbyannotatingtheclasswithSpring’s@ManagedResource annotation, and expose themethodsof the class as JMXoperationsusingSpring’s@ManagedOperationannotation.

Thefollowingexamplelistingshowsusageof@ManagedResourceand@ManagedOperationannotationsto register instances of the FixedDepositService class with the MBean server, and to expose itsactivateServiceanddeactivateServicemethodsasJMXoperations:

Examplelisting1-9–FixedDepositServiceclassthatusesSpring’sJMXsupport

importorg.springframework.jmx.export.annotation.ManagedOperation;importorg.springframework.jmx.export.annotation.ManagedResource;@ManagedResource(objectName="fixed_deposit_service:name=FixedDepositService")publicclassFixedDepositService{privatebooleanactive;publicFixedDepositDetailsgetFixedDepositDetails(.....){if(active){.....}}publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){if(active){.....}}@ManagedOperationpublicvoidactivateService(){active=true;}@ManagedOperation

Page 27: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicvoiddeactivateService(){active=false;}}

The above example listing shows that theFixedDepositService classdoesn’t directlyuse JMXAPI toregisteritsinstanceswiththeMBeanserverandtoexposeitsmethodsasJMXoperations.

JMS(JavaMessageService)Spring’sJMSsupportsimplifiessendingandreceivingmessagesfromJMSproviders.

InMyBankapplication,whenacustomersubmitsarequesttoreceivedetailsoftheirfixeddepositsviaemail, the FixedDepositService sends the request details to a JMS messaging middleware (likeActiveMQ).Therequestislaterprocessedbyamessagelistener.SpringsimplifiesinteractionwithJMSproviders by providing a layer of abstraction. The following example listing shows howFixedDepositServiceclasssendsrequestdetailstoaJMSproviderusingSpring’sJmsTemplate:

Examplelisting1-10–FixedDepositServicethatsendsJMSmessages

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.jms.core.JmsTemplate;publicclassFixedDepositService{@AutowiredprivatetransientJmsTemplatejmsTemplate;.....publicbooleansubmitRequest(Requestrequest){jmsTemplate.convertAndSend(request);}}

TheaboveexamplelistingshowsthattheFixedDepositServicedefinesavariableoftypeJmsTemplate,andisannotatedwithSpring’[email protected],youcanassumethat the@AutowiredannotationprovidesaccesstoaJmsTemplateinstance.TheJmsTemplateinstanceknowsabout theJMSdestinationtowhichtheJMSmessageistobesent.HowtheJmsTemplateisconfiguredisdescribedindetail in chapter 8. The FixedDepositService’s submitRequest method invokes JmsTemplate’sconvertAndSend method to send request details (represented by Request argument of submitRequestmethod)asaJMSmessagetotheJMSprovider.

Onceagain,theaboveexamplelistingshowsthatifyouareusingSpringFrameworktosendmessagestoJMSproviders,thenyoudon’tneedtodirectlydealwithJMSAPI.

CachingSpring’scacheabstractionprovidesaconsistentapproachtousecachinginyourapplication.

It’scommontousecachingsolutionstoimprovetheperformanceofanapplication.MyBankapplicationusesacachingproduct to improvetheperformanceofreadoperationsfor fixeddepositdetails.SpringFrameworksimplifiesinteractingwithdifferentcachingsolutionsbyabstractingcaching-relatedlogic.

Page 28: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

ThefollowingexamplelistingshowsthattheFixedDepositService’sgetFixedDepositDetailsmethodusesSpring’scacheabstractionfeaturetocachefixeddepositdetails:

Examplelisting1-11–FixedDepositServicethatcachesfixeddepositdetails

importorg.springframework.cache.annotation.Cacheable;publicclassFixedDepositService{@Cacheable("FixedDeposits")publicFixedDepositDetailsgetFixedDepositDetails(.....){.....}publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....}}

In the above example listing, Spring’s@Cacheable annotation indicates that the fixed deposit detailsreturned by the getFixedDepositDetails method are cached. If the getFixedDepositDetails method isinvokedwith the same argument value(s), the getFixedDepositDetailsmethod isnot executed, and thefixeddepositdetailsarereturnedfromthecache.ThisshowsthatifyouareusingSpringFrameworkyoudon’tneedtowritecaching-relatedlogicinyourclasses.Spring’scacheabstractionisexplainedindetailinchapter8.

In this section, we saw that Spring Framework simplifies developing enterprise applications bytransparentlyprovidingservices toPOJOs, therebyshieldingdevelopers fromlower levelAPIdetails.Spring also provides easy integrationwith standard frameworks, likeHibernate, iBATIS,Quartz, JSF,Struts,EJB,andsoon,whichmakesSpringanidealchoiceforenterpriseapplicationdevelopment.

Now,thatwehavelookedatsomeofthebenefitsofusingSpringFramework,let’stakealookathowtodevelopasimpleSpringapplication.

Page 29: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1-5AsimpleSpringapplicationInthissection,we’lllookatasimpleSpringapplicationthatusesSpring’sDIfeature.TouseSpring’sDIfeatureinanapplication,followthesesteps:

1.identifyapplicationobjectsandtheirdependencies

2.createPOJOclassescorrespondingtotheapplicationobjectsidentifiedinstep1

3.createconfigurationmetadatathatdepictsapplicationobjectsandtheirdependencies

4.createaninstanceofSpringIoCcontainerandpasstheconfigurationmetadatatoit

5.accessapplicationobjectsfromtheSpringIoCcontainerinstance

Let’snowlookatabovementionedstepsinthecontextofMyBankapplication.

IdentifyingapplicationobjectsandtheirdependenciesWediscussedearlierthattheMyBankapplicationshowsaformforcreatingafixeddeposit(referfigure1-3) to its users for creating a fixed deposit. The following sequence diagram shows the applicationobjects(andtheirinteraction)thatcomeintopicturewhentheusersubmitstheform:

Figure1-4MyBank’sapplicationobjectsandtheirdependencies

In the above sequence diagram, FixedDepositController represents a web controller that receives therequestwhen theformissubmitted.Thefixeddepositdetailsarecontained in theFixedDepositDetailsobject.TheFixedDepositController invokes the createFixedDepositmethod of FixedDepositService (aservicelayerobject).Then,FixedDepositServiceinvokesFixedDepositDaoobject(adataaccessobject)to save the fixed deposit details in the application’s data store. So, we can interpret from the abovediagram that FixedDepositService is a dependency of FixedDepositController object, andFixedDepositDaoisadependencyofFixedDepositServiceobject.

IMPORT chapter 1/ch01-bankapp-xml (This project shows a simple Spring application that usesSpring’sDI feature. To run the application, execute themainmethod of theMyBankApp class of thisproject)

CreatingPOJOclassescorrespondingtoidentifiedapplicationobjectsOnceyouhave identifiedapplicationobjects, thenext step is tocreatePOJOclassescorresponding tothese application objects. POJO classes corresponding to the FixedDepositController,

Page 30: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

FixedDepositService and FixedDepositDao application objects are available in ch01-bankapp-xmlproject.Thech01-bankapp-xmlprojectrepresentsasimplifiedversionofMyBankapplicationthatusesSpring’sDIfeature.Youshouldimportthech01-bankapp-xmlproject intoyourIDEasintheremainingstepswe’llbelookingatthefilescontainedinthisproject.

In section 1-3 we discussed that a dependency is passed to an application object as a constructorargument or as a setter method argument. The following code listing shows that an instance ofFixedDepositService(adependencyofFixedDepositController)ispassedasasettermethodargumenttotheFixedDepositControllerobject:

Examplelisting1-12–FixedDepositControllerclassProject–ch01-bankapp-xmlSourcelocation-src/main/java/sample/spring/chapter01/bankapppackagesample.spring.chapter01.bankapp;.....publicclassFixedDepositController{.....privateFixedDepositServicefixedDepositService;.....publicvoidsetFixedDepositService(FixedDepositServicefixedDepositService){logger.info("SettingfixedDepositServiceproperty");this.fixedDepositService=fixedDepositService;}.....publicvoidsubmit(){fixedDepositService.createFixedDeposit(newFixedDepositDetails(1,10000,365,"[email protected]"));}.....}

In the above example listing, FixedDepositService dependency is passed to FixedDepositControllerthroughsetFixedDepositServicemethod.We’llsoonseethatthesetFixedDepositServicesettermethodisinvokedbySpring.

NOTE If you look at theFixedDepositController,FixedDepositService and FixedDepositDao classes,you’ll notice that none of these classes implement any Spring-specific interface or extend from anySpring-specificclass.

Let’s now look at how application objects and their dependencies are specified in the configurationmetadata.

CreatingtheconfigurationmetadataWe saw in section 1-3 that the configuration metadata specifies application objects and theirdependencies,which is read by the Spring container to instantiate application objects and inject theirdependencies.Inthissection,we’llfirstlookatwhatotherinformationiscontainedintheconfiguration

Page 31: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

metadata,followedbyanin-depthlookathowconfigurationmetadataisspecifiedinXMLformat.

The configuration metadata specifies information about the enterprise services (like transactionmanagement,securityandremoteaccess)thatarerequiredbytheapplication.Forinstance, ifyouwantSpring to manage transactions, you need to configure an implementation of Spring’sPlatformTransactionManager interface in the configuration metadata. The PlatformTransactionManagerimplementation is responsible formanaging transactions (refer chapter 7 to knowmore aboutSpring’stransactionmanagementfeature).

Ifyourapplicationinteractswithmessagingmiddlewares(likeActiveMQ),databases(likeMySQL),e-mailservers,andsoon,thenSpring-specificobjectsthatsimplifyinteractingwiththeseexternalsystemsarealsodefined in theconfigurationmetadata.For instance, ifyourapplicationsendsor receivesJMSmessages from ActiveMQ, then you can configure Spring’s JmsTemplate class in the configurationmetadata to simplify interaction with ActiveMQ. We saw in example listing 1-10 that if you useJmsTemplateforsendingmessagestoaJMSprovider,thenyoudon’tneedtodealwithlower-levelJMSAPI(referchapter8toknowmoreaboutSpring’ssupportforinteractingwithJMSproviders).

YoucansupplytheconfigurationmetadatatotheSpringcontainerviaanXMLfileorthroughannotationsinPOJOclasses.StartingwithSpring3.0,youcanalsosupplytheconfigurationmetadatatotheSpringcontainerthroughJavaclassesannotatedwithSpring’[email protected],we’llseehowconfigurationmetadata is specified inXMLformat. Inchapter6,we’ll seehowconfigurationmetadataissuppliedviaannotationsinPOJOclassesandthrough@ConfigurationannotatedJavaclasses.

You provide the configurationmetadata for an application in XML format by creating an applicationcontextXMLfilethatcontainsinformationabouttheapplicationobjectsandtheirdependencies.Examplelisting 1-3 showed how an application context XML file looks like. The following XML shows theapplication context XML file of MyBank application that consists of FixedDepositController,FixedDepositService andFixedDepositDao objects (refer figure 1-4 to see how these objects interactwitheachother):

Examplelisting1-13–applicationContext.xml-MyBank’sapplicationcontextXMLfileProject–ch01-bankapp-xmlSourcelocation-src/main/resources/META-INF/spring<?xmlversion="1.0"encoding="UTF-8"standalone="no"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsd"><beanid="controller"class="sample.spring.chapter01.bankapp.FixedDepositController"><propertyname="fixedDepositService"ref="service"/></bean><beanid="service"class="sample.spring.chapter01.bankapp.FixedDepositService"><propertyname="fixedDepositDao"ref="dao"/>

Page 32: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

</bean><beanid="dao"class="sample.spring.chapter01.bankapp.FixedDepositDao"/></beans>ThefollowingaretheimportantpointstonoteabouttheapplicationcontextXMLfileshownabove:

·The<beans>elementistherootelementoftheapplicationcontextXMLfile,andisdefinedinspring-beans-4.0.xsdschema(alsoreferredtoasSpring’sbeansschema).Thespring-beans-4.0.xsdschema is contained in spring-beans-4.0.0.RELEASE.jar JAR file that comes with the SpringFrameworkdistribution.

·Each<bean>elementconfiguresanapplicationobjectthatismanagedbytheSpringcontainer.InSpringFramework’s terminology,a<bean>element representsabeandefinition.Theobject thattheSpringcontainercreatesbasedonthebeandefinitionisreferredtoasabean.Theidattributespecifiesauniquenameforthebean,andtheclassattributespecifiesthefully-qualifiedclassnameofthebean.Youcanalsousethenameattributeof<bean>elementtospecifyaliasesforthebean.InMyBankapplication, theapplicationobjectsareFixedDepositController, FixedDepositServiceandFixedDepositDao;therefore,wehave3<bean>elements-oneforeachapplicationobject.Asapplication objects configured by <bean> elements are managed by the Spring container, theresponsibility for creating them and injecting their dependencies is with the Spring container.Insteadofdirectlycreatinginstancesofapplicationobjectsdefinedby<bean>elements,youshouldobtainthemfromtheSpringcontainer.Laterinthissection,we’lllookathowtoobtainapplicationobjectsmanagedbySpringcontainer.

· No<bean> element is defined corresponding to the FixedDepositDetails domain object ofMyBank application. This is because domain objects are not typically managed by the Springcontainer;theyarecreatedbytheORMframework(likeHibernate)usedbytheapplication,oryoucreatethemprogrammaticallyusingthenewoperator.

· The <property> element specifies a dependency (or a configuration property) of the beanconfiguredbythe<bean>element.The<property>elementcorrespondstoaJavaBean-stylesettermethod in the bean class which is invoked by the Spring container to set a dependency (or aconfigurationproperty)ofthebean.

Let’snowlookathowdependenciesareinjectedviasettermethods.

Injectingdependenciesviasettermethods

To understand how dependencies are injected via settermethods defined in the bean class, let’s onceagainlookattheFixedDepositControllerclassofMyBankapplication:

Examplelisting1-14–FixedDepositControllerclassProject–ch01-bankapp-xmlSourcelocation-src/main/java/sample/spring/chapter01/bankapppackagesample.spring.chapter01.bankapp;

Page 33: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importorg.apache.log4j.Logger;publicclassFixedDepositController{privatestaticLoggerlogger=Logger.getLogger(FixedDepositController.class);privateFixedDepositServicefixedDepositService;publicFixedDepositController(){logger.info("initializing");}publicvoidsetFixedDepositService(FixedDepositServicefixedDepositService){logger.info("SettingfixedDepositServiceproperty");this.fixedDepositService=fixedDepositService;}.....}

The above example listing shows that the FixedDepositController class declares an instance variablenamedfixedDepositServiceoftypeFixedDepositService.ThefixedDepositServicevariableissetbythesetFixedDepositServicemethod-aJavaBean-stylesettermethodforfixedDepositServicevariable.Thisisanexampleofsetter-basedDI,whereinasettermethodsatisfiesadependency.

The following figure describes the bean definition for the FixedDepositController class in theapplicationContext.xmlfile(referexamplelisting1-13):

Figure1-5Definingdependenciesusing<property>elements

The above bean definition shows that the FixedDepositController bean defines its dependence onFixedDepositServicebeanvia<property>element.The<property>element’snameattributecorrespondstotheJavaBean-stylesettermethodinthebeanclassthatisinvokedbytheSpringcontaineratthetimeofbeancreation.The<property>element’srefattributeidentifiestheSpringbeanwhoseinstanceneedstobecreatedandpassedto theJavaBean-stylesettermethod.Thevalueofrefattributemustmatch the idattribute’s value (or one of the names specified by the name attribute) of a <bean> element in theconfigurationmetadata.

Infigure1-5,thevalueof<property>element’snameattributeisfixedDepositService,whichmeansthat

Page 34: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

the <property> element corresponds to the setFixedDepositService setter method ofFixedDepositController class (refer example listing 1-14). As the value of <property> element’s refattribute is service, the<property> element refers to the<bean>elementwhose id attribute’s value isservice.Now,the<bean>elementwhoseidattribute’svalueisserviceistheFixedDepositServicebean(refer example listing 1-13). Spring container creates an instance of FixedDepositService class (adependency), and invokes the setFixedDepositService method (a JavaBean-style setter method forfixedDepositService variable) of FixedDepositController (a dependent object), passing theFixedDepositServiceinstance.

InthecontextofFixedDepositControllerapplicationobject,thefollowingfiguresummarizesthepurposeofnameandrefattributesof<property>element:

Figure 1-6 <property> element’s name attribute corresponds to a JavaBean-style setter method thatsatisfiesabeandependency,andrefattributereferstoanotherbean.

The above figure shows that fixedDepositService value of name attribute corresponds to thesetFixedDepositServicemethodofFixedDepositControllerclass,andservicevalueofrefattributereferstothebeanwhoseidisservice.

NOTEItisfairlycommontorefertoabeandefinitionbyitsname(whichisidattribute’svalue)ortype(which isclassattribute’svalue)or the interface implementedby thebeanclass.For instance,youcanrefer to ‘FixedDepositController bean’ as ‘controller bean’. And, if the FixedDepositController classimplements FixedDepositControllerIntf interface, you can refer to ‘FixedDepositController bean’ as‘FixedDepositControllerIntfbean’.

ThefollowingdiagramsummarizeshowtheSpringcontainercreatesbeansandinjectstheirdependenciesbasedontheconfigurationmetadatasuppliedbytheapplicationContext.xmlfile(referexamplelisting1-13)ofMyBankapplication:

Page 35: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure1-7-ThesequenceinwhichSpringIoCcontainercreatesbeansandinjectstheirdependencies.

The above figure shows the sequence of steps followed by the Spring IoC container to createFixedDepositController, FixedDepositService and FixedDepositDao beans and inject theirdependencies. Before attempting to create beans, the Spring container reads and validates theconfigurationmetadata supplied by the applicationContext.xml file. The order in which the beans arecreated by the Spring container depends on the order in which they are defined in theapplicationContext.xml file. Spring container ensures that the dependencies of a bean are completelyconfigured before the setter method is invoked. For example, the FixedDepositController bean isdependentonFixedDepositServicebean;therefore,SpringcontainerconfigurestheFixedDepositServicebeanbeforeinvokingthesetFixedDepositServicemethodofFixedDepositControllerbean.

The bean definitions that we have seen so far, instruct Spring container to create bean instances byinvokingtheno-argumentconstructorofthebeanclass,andinjectdependenciesusingsetter-basedDI.Inchapter 2,we’ll look at bean definitions that instruct Spring container to create a bean instance via afactorymethod defined in a class.Also,we’ll lookathow to injectdependencies throughconstructorarguments(referredtoasconstructor-basedDI),throughargumentstothefactorymethodthatcreatesthebeaninstance,andbyusingsetter-basedDIonthebeaninstancereturnedbythefactorymethod.

Let’snowlookathowtocreateaninstanceofSpringcontainerandpassconfigurationmetadatatoit.

CreatinganinstanceofSpringcontainerSpring’sApplicationContext object represents an instance of Spring container. Spring provides a fewbuilt-in implementations of ApplicationContext interface, like ClassPathXmlApplicationContext,FileSystemXmlApplicationContext,XmlWebApplicationContext, XmlPortletApplicationContext, and soon. The choice of the ApplicationContext implementation depends on how you have defined theconfiguration metadata (using XML, annotations or Java code), and the type of your application(standalone, web or portlet application). For instance, ClassPathXmlApplicationContext andFileSystemXmlApplicationContext classes are suitable for standalone applications in whichconfiguration metadata is supplied in XML format, XmlWebApplicationContext is suitable for webapplications in which the configuration metadata is supplied in XML format,AnnotationConfigWebApplicationContext is suitable for web applications in which configurationmetadataissuppliedthroughJavacode,andsoon.

Page 36: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

As MyBank application represents a standalone application, we can use eitherClassPathXmlApplicationContext or FileSystemXmlApplicationContext class to create an instance ofSpring container.You should note that theClassPathXmlApplicationContext class loads an applicationcontextXMLfilefromthespecifiedclasspathlocation,andtheFileSystemXmlApplicationContextclassloadsanapplicationcontextXMLfilefromthespecifiedlocationonthefilesystem.

The following BankApp class of MyBank application shows that an instance of Spring container iscreatedusingtheClassPathXmlApplicationContextclass:

Examplelisting1-15–BankAppclassProject–ch01-bankapp-xmlSourcelocation-src/main/java/sample/spring/chapter01/bankapppackagesample.spring.chapter01.bankapp;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassBankApp{.....publicstaticvoidmain(Stringargs[]){ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");.....}}

TheaboveexamplelistingshowstheBankApp’smainmethod,whichisresponsibleforbootstrappingtheSpringcontainer.TheclasspathlocationoftheapplicationcontextXMLfileispassedtotheconstructorof ClassPathXmlApplicationContext class. The creation of ClassPathXmlApplicationContext instanceresultsincreationofthosebeansintheapplicationcontextXMLfilethataresingleton-scopedandsettobepre-instantiated. Inchapter2,we’lldiscussbeanscopes, andwhat itmeans tohavebeanspre- orlazily-instantiated by Spring container. For now, you can assume that the beans defined in theapplicationContext.xml file ofMyBank 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 ofClassPathXmlApplicationContextiscreated.

Now,thatwehaveseenhowtocreateaninstanceoftheSpringcontainer, let’slookathowtoretrievebeaninstancesfromtheSpringcontainer.

AccessbeansfromtheSpringcontainerTheapplicationobjectsdefinedvia<bean>elementsarecreatedandmanagedby theSpringcontainer.You can access instances of these application objects by calling one of the getBean methods of theApplicationContextinterface.

The following example listing shows themainmethod of BankApp class that retrieves an instance ofFixedDepositControllerbeanfromtheSpringcontainerandinvokesitsmethods:

Page 37: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting1-16–BankAppclassProject–ch01-bankapp-xmlSourcelocation-src/main/java/sample/spring/chapter01/bankapppackagesample.spring.chapter01.bankapp;importorg.apache.log4j.Logger;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassBankApp{privatestaticLoggerlogger=Logger.getLogger(BankApp.class);publicstaticvoidmain(Stringargs[]){ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");FixedDepositControllerfixedDepositController=(FixedDepositController)context.getBean("controller");logger.info("Submissionstatusoffixeddeposit:"+fixedDepositController.submit());logger.info("Returnedfixeddepositinfo:"+fixedDepositController.get());}}

At first, the ApplicationContext’s getBean method is invoked to retrieve an instance ofFixedDepositController bean from the Spring container, followed by invocation of submit and getmethodsofFixedDepositControllerbean.TheargumentpassedtothegetBeanmethodisthenameofthebeanwhoseinstanceyouwanttoretrievefromtheSpringcontainer.ThenameofthebeanpassedtothegetBeanmethodmustbethevalueoftheidornameattributeofthebeanthatyouwanttoretrieve.Ifnobean with the specified name is registered with the Spring container, an exception is thrown by thegetBeanmethod.

In example listing 1-16, to configure theFixedDepositController instance,we didn’t programmaticallycreatean instanceofFixedDepositServiceand set it on theFixedDepositController instance.Also,wedidn’t create an instance of FixedDepositDao and set it on the FixedDepositService instance. This isbecausethetaskofcreatingdependencies,andinjectingthemintothethedependentobjectsishandledbytheSpringcontainer.

If yougo to ch01-bankapp-xml project and execute themainmethod ofBankApp class, you’ll see thefollowingoutputontheconsole:INFOsample.spring.chapter01.bankapp.FixedDepositController-initializingINFOsample.spring.chapter01.bankapp.FixedDepositService-initializingINFOsample.spring.chapter01.bankapp.FixedDepositDao-initializingINFOsample.spring.chapter01.bankapp.FixedDepositService-SettingfixedDepositDaopropertyINFOsample.spring.chapter01.bankapp.FixedDepositController-SettingfixedDepositServicepropertyINFOsample.spring.chapter01.bankapp.BankApp-Submissionstatusoffixeddeposit:true

Page 38: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

INFOsample.spring.chapter01.bankapp.BankApp-Returnedfixeddepositinfo:id:1,depositamount:10000.0,tenure:365,email:[email protected]

The above output shows that Spring container creates an instance of each of the beans defined in theapplicationContext.xmlfileofMyBankapplication.Also,Springcontainerusessetter-basedDItoinjectan instance of FixedDepositService into FixedDepositController instance, and an instance ofFixedDepositDaointotheFixedDepositServiceinstance.

Let’snowlookatsomeoftheframeworksthatarebuiltontopofSpringFramework.

Page 39: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1-6FrameworksbuiltontopofSpringThough there are many frameworks from SpringSource that use Spring Framework as the foundation,we’ll lookat someof thewidelypopularones.Foramorecomprehensive listof frameworks,andformoredetailsaboutan individual framework, it’s recommended thatyouvisit theSpringSourcewebsite(www.springsource.org).

Thefollowingtableprovidesahigh-leveloverviewoftheframeworksfromSpringSourcethatarebuiltontopofSpringFramework:

Framework Description

SpringSecurityAuthenticationandauthorizationframeworkforenterpriseapplications.Youneedtoconfigure a few beans in your application context XML file to incorporateauthenticationandauthorizationfeaturesintoyourapplication.

SpringData

Provides a consistent programming model to interact with different types ofdatabases.Forinstance,youcanuseittointeractwithnon-relationaldatabases,likeMongoDBorNeo4j,andyoucanalsouseitforaccessingrelationaldatabasesusingJPA.

SpringBatch Ifyourapplicationrequiresbulkprocessing,thisframeworkisforyou.

SpringIntegration ProvidesEnterpriseApplicationIntegration(EAI)capabilitiestoapplications.

SpringSocial If your application requires interactionwith socialmediawebsites, like FacebookandTwitter,thenyou’llfindthisframeworkhighlyuseful.

SpringBlazeDSIntegration

IfyouaredevelopinganAdobeFlexbasedapplication,youcanusethisframeworktoconnectFlexfrontendwithSpring-basedbusinesstier.

AstheframeworksmentionedintheabovetablearebuiltontopofSpringFramework,beforeusinganyoftheseframeworksmakesurethattheyarecompatiblewiththeSpringFrameworkversionthatyouareusing.

Page 40: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1-7SummaryInthischapter,welookedatthebenefitsofusingSpringFramework.WealsolookedatasimpleSpringapplicationthatshowedhowtospecifyconfigurationmetadatainXMLformat,createtheSpringcontainerinstanceandretrievebeansfromit.Inthenextchapter,we’lllookatsomeofthefoundationconceptsofSpringFramework.

Page 41: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter2–SpringFrameworkbasics

Page 42: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

2-1IntroductionInthepreviouschapter,wesawthattheSpringcontainerinvokestheno-argumentconstructorofabeanclasstocreateabeaninstance,andsetter-basedDIisusedtosetbeandependencies.Inthischapter,we’llgoastepfurtherandlookat:

§Spring’ssupportfor‘programmingtointerfaces’designprinciple

§differentapproachestoinstantiatingSpringbeans

§constructor-basedDIforpassingbeandependenciesasconstructorarguments

§constructor-andsetter-basedDIforpassingsimpleStringvaluestobeans,and

§beanscopes

Let’s begin this chapterwith looking at howSpring improves testability of applications by supporting‘programmingtointerfaces’designprinciple.

Page 43: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

2-2ProgrammingtointerfacesdesignprincipleInsection1-5ofchapter1,wesawthatadependentPOJOclasscontainedreferencetotheconcreteclassof the dependency. For example, the FixedDepositController class contained reference to theFixedDepositService class, and the FixedDepositService class contained reference to theFixedDepositDaoclass.Ifadependentclasshasdirectreferencetotheconcreteclassofthedependency,it results in tight coupling between the classes. This means that if you want to substitute a differentimplementationofthedependency,it’drequirechangingthedependentclass.

Let’snowlookatascenarioinwhichadependentclasscontainsdirectreferencetotheconcreteclassofthedependency.

Scenario:DependentclasscontainsreferencetotheconcreteclassofdependencyLet’s say that the FixedDepositDao class makes use of plain JDBC to interact with the database. Tosimplify database interaction, you create another DAO implementation, FixedDepositHibernateDao,whichusesHibernateORMfordatabaseinteraction.Now,toswitchfromplainJDBCtoHibernateORMimplementation,you’llneedtochangeFixedDepositServiceclasstouseFixedDepositHibernateDaoclassinsteadofFixedDepositDao,asshowninthefollowingexamplelisting:

Examplelisting2-1–FixedDepositServiceclasspublicclassFixedDepositService{privateFixedDepositHibernateDaofixedDepositDao;publicvoidsetFixedDepositDao(FixedDepositHibernateDaofixedDepositDao){this.fixedDepositDao=fixedDepositDao;}publicFixedDepositDetailsgetFixedDepositDetails(longid){returnfixedDepositDao.getFixedDepositDetails(id);}publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){returnfixedDepositDao.createFixedDeposit(fixedDepositDetails);}}

The above example listing shows that reference to FixedDepositDao class was replaced byFixedDepositHibernateDaosothatHibernateORMcanbeusedfordatabaseinteraction.Thisshowsthatif a dependent class refers to the concrete implementation class of the dependency, then substituting adifferentimplementationrequireschangesinthedependentclass.

Let’snowlookatascenarioinwhichadependentclasscontainsreferencetotheinterfaceimplementedbythedependency.

Page 44: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Scenario:Dependentclasscontainsreferenceto the interface implementedbythedependencyWeknowthataJavainterfacedefinesacontract towhichtheimplementationclassesconform.So, ifaclass dependson the interface implementedby thedependency, no change is required in the class if adifferent implementationof the dependency is substituted.The applicationdesign approach inwhich aclass depends on the interface implemented by the dependency is referred to as ‘programming tointerfaces’.Theinterfaceimplementedbythedependencyclassisreferredtoasadependencyinterface.

Asitisagooddesignpracticeto‘programtointerfaces’thanto‘programtoclasses’,thefollowingclassdiagramshowsthatitisagooddesignifABeanclassdependsonBBeaninterfaceandnotonBBeanImplclassthatimplementsBBeaninterface:

Figure2-1-‘Programtointerfaces’isagooddesignpracticethanto‘programtoclasses’

The followingclassdiagramshowshowFixedDepositService class canmakeuse of ‘programming tointerfaces’designapproachtoeasilyswitchthestrategyusedfordatabaseinteraction:

Figure2-2–TheFixedDepositServicedependsonFixedDepositDaointerface,whichisimplementedbyFixedDepositJdbcDaoandFixedDepositHibernateDaoclasses.

The above figure shows that the FixedDepositService class is not directly dependent on theFixedDepositJdbcDaoorFixedDepositHibernateDaoclass.Instead,FixedDepositServicedependsontheFixedDepositDao interface (the dependency interface) implemented by FixedDepositJdbcDao and

Page 45: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

FixedDepositHibernateDao classes. Now, depending on whether you want to use plain JDBC orHibernate ORM framework, you supply an instance of FixedDepositJdbcDao orFixedDepositHibernateDaototheFixedDepositServiceinstance.

As FixedDepositService depends on FixedDepositDao interface, you can support other databaseinteraction strategies in the future.Let’s say thatyoudecide touse iBATIS (now renamed toMyBatis)persistence framework for database interaction. You can use iBATIS without making any changes toFixedDepositService class by simply creating a new FixedDepositIbatisDao class that implementsFixedDepositDao interface, and supplying an instance of FixedDepositIbatisDao to theFixedDepositServiceinstance.

Sofarwehaveseenthat‘programmingtointerfaces’designapproachresultsinloosecouplingbetweenadependentclassanditsdependencies.Let’snowlookathowthisdesignapproachimprovestestabilityofthedependentclasses.

Improvedtestabilityofdependentclasses

In figure 2-2, we saw that the FixedDepositService class holds reference to the FixedDepositDaointerface.FixedDepositJdbcDaoandFixedDepositHibernateDaoareconcreteimplementationclassesofFixedDepositDaointerface.Now,tosimplifyunittestingofFixedDepositServiceclass,youcansubstituteamockimplementationofFixedDepositDaointerfacethatdoesn’trequireadatabase.

If the FixedDepositService class had direct reference to FixedDepositJdbcDao orFixedDepositHibernateDao class, testing FixedDepositService class would have required setting up adatabasefortestingpurposes.Thisshowsthatbyusingamockimplementationofdependencyinterface,youcansavetheefforttosetuptheinfrastructureforunittestingyourdependentclasses.

Let’snowseehowSpringsupports‘programmingtointerfaces’designapproachinapplications.

Spring’ssupportfor‘programmingtointerfaces’designapproachTouse ‘programming to interfaces’designapproach inyourSpringapplication,youneed toensure thefollowingthings:

§the<bean>elementsintheconfigurationmetadataspecifytheconcreteclassesofthedependency

§ thedependentbeanclasses refer to thedependency interface insteadof theconcreteclassof thedependency

Let’s now look at the modified MyBank application that uses ‘programming to interfaces’ designapproach.

IMPORT chapter 2/ch02-bankapp-interfaces (This project shows how ‘programming to interfaces’designapproachisusedincreatingSpringapplications.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

MyBankapplicationthatuses‘programmingtointerfaces’designapproach

Page 46: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

The following class diagram depicts the modified MyBank application that uses ‘programming tointerfaces’designapproach:

Figure2-3-MyBankapplicationthatuses‘programtointerfaces’designapproach

Theabovefigureshowsthatadependentclassdependsontheinterfaceimplementedbythedependency,and not on the concrete implementation class of the dependency. For instance, theFixedDepositControllerImpl class depends on the FixedDepositService interface, and theFixedDepositServiceImplclassdependsontheFixedDepositDaointerface.

Thefollowingexample listingshows theFixedDepositServiceImplclassbasedon thedesignshown infigure2-3:

Examplelisting2-2–FixedDepositServiceclassProject–ch02-bankapp-interfacesSourcelocation-src/main/java/sample/spring/chapter02/bankapppackagesample.spring.chapter02.bankapp;publicclassFixedDepositServiceImplimplementsFixedDepositService{privateFixedDepositDaofixedDepositDao;.....publicvoidsetFixedDepositDao(FixedDepositDaofixedDepositDao){this.fixedDepositDao=fixedDepositDao;}publicFixedDepositDetailsgetFixedDepositDetails(longid){returnfixedDepositDao.getFixedDepositDetails(id);}publicbooleancreateFixedDeposit(FixedDepositDetailsfdd){returnfixedDepositDao.createFixedDeposit(fdd);

Page 47: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

}}

The above example listing shows that the FixedDepositServiceImpl class contains reference to theFixedDepositDao interface. The FixedDepositDao implementation that you want to inject into theFixedDepositServiceImplinstanceisspecifiedintheapplicationcontextXMLfile.Asshowninfigure2-3, you can inject any one of the following concrete implementations of FixedDepositDao interface:FixedDepositIbatisDao,FixedDepositJdbcDaoandFixedDepositHibernateDao.

The followingexample listingshows theapplicationContext.xml file that caters to thedesign shown infigure2-3:

Examplelisting2-3–applicationContext.xml-MyBank’sapplicationcontextXMLfileProject–ch02-bankapp-interfacesSourcelocation-src/main/resources/META-INF/spring<?xmlversion="1.0"encoding="UTF-8"standalone="no"?><beans.....><beanid="controller"class="sample.spring.chapter02.bankapp.controller.FixedDepositControllerImpl"><propertyname="fixedDepositService"ref="service"/></bean><beanid="service"class="sample.spring.chapter02.bankapp.service.FixedDepositServiceImpl"><propertyname="fixedDepositDao"ref="dao"/></bean><beanid="dao"class="sample.spring.chapter02.bankapp.dao.FixedDepositHibernateDao"/></beans>

The above applicationContext.xml file shows that an instance of FixedDepositHibernateDao (animplementation of FixedDepositDao interface) is injected into FixedDepositServiceImpl. Now, if youdecidetouseiBATISinsteadofHibernateforpersistence,thenallyouneedtodoistochangetheclassattributeofthedaobeandefinitionintheapplicationContext.xmlfiletorefertothefully-qualifiednameoftheFixedDepositIbatisDaoclass.

Let’snowlookatdifferentwaysinwhichSpringcontainercaninstantiatebeans.

Page 48: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

2-3DifferentapproachestoinstantiatingSpringbeansSofarwehaveseenbeandefinitionexamplesthat instructSpringcontainertocreatebeaninstancesbyinvokingtheno-argumentconstructorofthebeanclass.Considerthefollowingbeandefinition:

<beanid=”myBean”class=”mypackage.MyBean”/>

In the above bean definition, MyBean class represents a POJO class that defines a no-argumentconstructor.MyBean classdoesn’t implement anySpring-specific interfaceor extend fromanySpring-specific class.This effectivelymeans that theSpring container can create andmanage instance of anyclassthatprovidesano-argumentconstructor.

NOTE It is important to note that the Spring container can create andmanage instance of any class,irrespectiveofwhethertheclassprovidesano-argumentconstructorornot.Insection2-4,we’lllookatbeandefinitionsinwhichtheconstructorofthebeanclassacceptsoneormorearguments.

Ifyouhaveanexistingprojectthatusesfactoryclassestocreateobjectinstances,youcanstilluseSpringcontainertomanageobjectscreatedbythesefactories.Let’snowlookathowSpringcontainerinvokesastaticoraninstancefactorymethodofaclasstomanagethereturnedobjectinstance.

InstantiatingbeansviastaticfactorymethodsInfigure2-3,wesawthattheFixedDepositDaointerfaceisimplementedbyFixedDepositHibernateDao,FixedDepositIbatisDao and FixedDepositJdbcDao classes. The following example listing shows aFixedDepositDaoFactoryclassthatdefinesastaticfactorymethodforcreatingandreturninganinstanceofFixedDepositDaobasedontheargumentpassedtothestaticmethod:

Examplelisting2-4–FixedDepositDaoFactoryclasspublicclassFixedDepositDaoFactory{privateFixedDepositDaoFactory(){}publicstaticFixedDepositDaogetFixedDepositDao(StringdaoType){FixedDepositDaofixedDepositDao=null;if("jdbc".equalsIgnoreCase(daoType)){fixedDepositDao=newFixedDepositJdbcDao();}if("hibernate".equalsIgnoreCase(daoType)){fixedDepositDao=newFixedDepositHibernateDao();}.....returnfixedDepositDao;}}

TheaboveexamplelistingshowsthattheFixedDepositDaoFactoryclassdefinesagetFixedDepositDaostaticmethod thatcreatesandreturnsan instanceofFixedDepositJdbcDao,FixedDepositHibernateDao

Page 49: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

orFixedDepositIbatisDaoclass,dependingonthevalueofthedaoTypeargument.

ThefollowingbeandefinitionfortheFixedDepositDaoFactoryclassinstructsSpringcontainertoinvokeFixedDepositDaoFactory’sgetFixedDepositDaomethod to obtain an instance of FixedDepositJdbcDaoclass:

Examplelisting2-5–BeandefinitionfortheFixedDepositDaoFactoryclass<beanid="dao"class="sample.spring.FixedDepositDaoFactory"factory-method="getFixedDepositDao"><constructor-argindex=”0”value="jdbc"/></bean>

Intheabovebeandefinition,classattributespecifiesthefully-qualifiednameoftheclassthatdefinesthestaticfactorymethod.Thefactory-methodattributespecifiesthenameofthestaticfactorymethodthattheSpringcontainerinvokestoobtainaninstanceofFixedDepositDaoobject.The<constructor-arg>elementis defined inSpring’s beansschema and is used for passing arguments to constructors, and static andinstancefactorymethods.Theindexattributereferstothelocationoftheargumentintheconstructor,orinthestaticorinstancefactorymethod.Intheabovebeandefinition,thevalue0of indexattributemeansthat the <constructor-arg> element is supplying value for the first argument,which is daoType, of thegetFixedDepositDaofactorymethod.Thevalueattributespecifiestheargumentvalue.Ifafactorymethodacceptsmultiplearguments,youneedtodefinea<constructor-arg>elementforeachofthearguments.

ItisimportanttonotethatcallingApplicationContext’sgetBeanmethodtoobtaindaobean(referexamplelisting 2-5) will result in invocation of the FixedDepositDaoFactory’s getFixedDepositDao factorymethod. This means that calling getBean("dao") returns the FixedDepositDao instance created by thegetFixedDepositDaofactorymethod,andnotaninstanceofFixedDepositDaoFactoryclass.

Now,thatwehaveseentheconfigurationofthefactoryclassthatcreatesaninstanceofFixedDepositDao,the following example listing shows how to inject an instance of FixedDepositDao intoFixedDepositServiceImplclass:

Examplelisting2-6–Injectingobjectinstancescreatedbystaticfactorymethod<beanid="service"class="sample.spring.chapter02.bankapp.FixedDepositServiceImpl"><propertyname=“fixedDepositDao"ref="dao"/></bean><beanid="dao"class="sample.spring.chapter02.basicapp.FixedDepositDaoFactory"factory-method="getFixedDepositDao"><constructor-argindex=”0”value="jdbc"/></bean>In the above example listing, <property> element injects an instance of FixedDepositDao returned byFixedDepositDaoFactory’sgetFixedDepositDao factorymethod intoFixedDepositServiceImpl instance.If you compare the bean definition for the FixedDepositServiceImpl class shown above with the oneshown in example listing 2-3, you’ll notice that they are exactly the same. This shows that the beandependenciesare specified the sameway irrespectiveofhow (usingno-argument constructororstatic

Page 50: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

factorymethod)theSpringcontainercreatesbeaninstances.

Let’snowlookathowSpringcontainerinstantiatebeansbyinvokinganinstancefactorymethod.

InstantiatingbeansviainstancefactorymethodsThefollowingexamplelistingshowstheFixedDepositDaoFactoryclassthatdefinesaninstance factorymethodforcreatingandreturninganinstanceofFixedDepositDao:

Examplelisting2-7–FixedDepositDaoFactoryclasspublicclassFixedDepositDaoFactory{publicFixedDepositDaoFactory(){}publicFixedDepositDaogetFixedDepositDao(StringdaoType){FixedDepositDaoFixedDepositDao=null;if("jdbc".equalsIgnoreCase(daoType)){FixedDepositDao=newFixedDepositJdbcDao();}if(“hibernate”.equalsIgnoreCase(daoType)){FixedDepositDao=newFixedDepositHiberateDao();}.....returnfixedDepositDao;}}

Ifaclassdefinesaninstancefactorymethod,theclassmustdefineapublicconstructorsothattheSpringcontainercancreateaninstanceofthatclass.Intheaboveexamplelisting,theFixedDepositDaoFactoryclass defines a public no-argument constructor. The FixedDepositDaoFactory’s getFixedDepositDaomethodisaninstancefactorymethodthatcreatesandreturnsaninstanceofFixedDepositDao.

The following example listing shows how to instruct Spring container to invokeFixedDepositDaoFactory’sgetFixedDepositDaomethodtoobtainaninstanceofFixedDepositDao:

Examplelisting2-8–ConfigurationtoinvokeFixedDepositDaoFactory’sgetFixedDepositDaomethod<beanid="daoFactory"class="sample.spring.chapter02.basicapp.FixedDepositDaoFactory"/><beanid="dao"factory-bean="daoFactory"factory-method="getFixedDepositDao"><constructor-argindex="0"value="jdbc"/></bean><beanid="service"class="sample.spring.chapter02.bankapp.FixedDepositServiceImpl"><propertyname=“fixedDepositDao"ref="dao"/></bean>

Page 51: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

TheaboveexamplelistingshowsthattheFixedDepositDaoFactoryclass(aclassthatcontains instancefactory method) is configured like a regular Spring bean, and a separate <bean> element is used toconfiguretheinstancefactorymethoddetails.Toconfiguredetailsofaninstancefactorymethod,factory-beanandfactory-methodattributesof<bean>elementareused.Thefactory-beanattribute refers to thebeanthatdefinestheinstancefactorymethod,andthefactory-methodattributespecifiesthenameoftheinstance factory method. In the above example listing, <property> element injects an instance ofFixedDepositDao returned by FixedDepositDaoFactory’s getFixedDepositDao factory method intoFixedDepositServiceImplinstance.

Aswithstaticfactorymethods,youcanpassargumentstoinstancefactorymethodsusing<constructor-arg> element. It is important to note that invokingApplicationContext’sgetBeanmethod to obtain daobean in the above example listing will result in invocation of the FixedDepositDaoFactory’sgetFixedDepositDaofactorymethod.

So farwehave looked at beandefinition examples inwhichdependencies are injected intobeansviasettermethods.Let’snowlookatdifferentDImechanismsthatyoucanuseforinjectingdependencies.

Page 52: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

2-4DependencyinjectiontechniquesIn Spring, dependency injection is performed by passing arguments to a bean’s constructor and settermethods.Ifyouareusingastaticorinstancefactorymethodtocreatebeaninstances,youcanpassbeandependencies to the factory method or you can set them on the bean instance returned by the factorymethod.

We’llnowlookatexamplesthatdemonstratedifferentDItechniques.

Setter-basedDISofarinthisbook,we’veseenexamplesofsetter-basedDI.Insetter-basedDI,<property>elementsareused to specify bean dependencies. The <property> element is also used to pass configurationinformation(ifany)requiredbythebean.

Let’ssaythattheMyBankapplicationcontainsaPersonalBankingServiceservicethatallowscustomerstoretrievebankaccountstatement,checkbankaccountdetails,updatecontactnumber,changepassword,and contact customer service.ThePersonalBankingServiceclassuses JmsMessageSender (for sendingJMS messages), EmailMessageSender (for sending emails) and WebServiceInvoker (for invokingexternalweb services)objects to accomplish it’s intended functionality.The followingexample listingshowsthePersonalBankingServiceclass:

Examplelisting2-9–PersonalBankingServiceclasspublicclassPersonalBankingService{privateJmsMessageSenderjmsMessageSender;privateEmailMessageSenderemailMessageSender;privateWebServiceInvokerwebServiceInvoker;.....publicvoidsetJmsMessageSender(JmsMessageSenderjmsMessageSender){this.jmsMessageSender=jmsMessageSender;}publicvoidsetEmailMessageSender(EmailMessageSenderemailMessageSender){this.emailMessageSender=emailMessageSender;}publicvoidsetWebServiceInvoker(WebServiceInvokerwebServiceInvoker){this.webServiceInvoker=webServiceInvoker;}.....}

The above example listing shows that a setter method is defined for JmsMessageSender,EmailMessageSenderandWebServiceInvokerdependenciesofPersonalBankingServiceclass.

We can use setter-basedDI to inject the dependencies of thePersonalBankingService class, as shownhere:

Page 53: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting2-10–BeandefinitionsforPersonalBankingServiceclassanditsdependencies<beanid="personalBankingService"class="PersonalBankingService"><propertyname="emailMessageSender"ref="emailMessageSender"/><propertyname="jmsMessageSender"ref="jmsMessageSender"/><propertyname="webServiceInvoker"ref="webServiceInvoker"/></bean><beanid="jmsMessageSender"class="JmsMessageSender">.....</bean><beanid="webServiceInvoker"class="WebServiceInvoker"/>.....</bean><beanid="emailMessageSender"class="EmailMessageSender"/>.....</bean>

The personalBankingService bean definition shows that a <property> element is specified for eachdependencyofPersonalBankingServiceclass.

PersonalBankingServiceusesEmailMessageSenderbeantosendanemailnotificationtothecustomer’semailaddressincasecustomerchangeshiscontactnumber.EmailMessageSenderrequiresemailserveraddress, and username and password for authenticatingwith the email server. The following examplelistingshowsthatthe<property>elementcanalsobeusedforsettingbeanpropertiesoftypeString:

Examplelisting2-11EmailMessageSenderclassandthecorrespondingbeandefinition

publicclassEmailMessageSender{privateStringhost;privateStringusername;privateStringpassword;.....publicvoidsetHost(Stringhost){this.host=host;}publicvoidsetUsername(Stringusername){this.username=username;}publicvoidsetPassword(Stringpassword){this.password=password;}.....}

Page 54: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="emailMessageSender"class="EmailMessageSender"><propertyname="host"value="smtp.gmail.com"/><propertyname="username"value="myusername"/><propertyname="password"value="mypassword"/></bean>

The above example listing shows that <property> elements have been used to set host, username andpasswordpropertiesofEmailMessageSenderbean.ThevalueattributespecifiestheStringvaluetobesetfor the bean property identified by the name attribute. The host, username and password propertiesrepresentconfigurationinformationrequiredbyEmailMessageSenderbean.Inchapter3,we’llseehowthe <property> element is used to set primitive type (like int, long, and so on), collection type (likejava.util.List,java.util.Map,andsoon)andcustomtype(likeAddress)properties.

Setter-basedDI is also used to inject dependencies into beans created by static and instance factorymethods.Let’slookathowtousesetter-basedDIinconjunctionwithstaticandinstancefactorymethods.

Injectingdependenciesintobeaninstancescreatedbyfactorymethods

Youcanusesetter-basedDItoinjectdependenciesofthebeaninstancereturnedbyastaticorinstancefactorymethod.

ConsiderthefollowingFixedDepositJdbcDaoclassthatdefinesadatabaseInfoproperty:

Examplelisting2-12–FixedDepositJdbcDaoclasspublicclassFixedDepositJdbcDao{privateDatabaseInfodatabaseInfo;.....publicFixedDepositJdbcDao(){}publicvoidsetDatabaseInfo(DatabaseInfodatabaseInfo){this.databaseInfo=databaseInfo;}.....}

In the above example listing, the databaseInfo attribute represents a dependency of theFixedDepositJdbcDaoclassthatisfulfilledbysetDatabaseInfomethod.

The following FixedDepositDaoFactory class defines a factory method responsible for creating andreturninganinstanceofFixedDepositDaoJdbcclass:

Examplelisting2-13–FixedDepositDaoFactoryclasspublicclassFixedDepositDaoFactory{publicFixedDepositDaoFactory(){}publicFixedDepositDaogetFixedDepositDao(StringdaoType){

Page 55: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

FixedDepositDaoFixedDepositDao=null;if("jdbc".equalsIgnoreCase(daoType)){FixedDepositDao=newFixedDepositJdbcDao();}if(“hibernate”.equalsIgnoreCase(daoType)){FixedDepositDao=newFixedDepositHiberateDao();}.....returnfixedDepositDao;}}

Intheaboveexamplelisting,thegetFixedDepositDaomethodisaninstancefactorymethodforcreatingFixedDepositDao instances. The getFixedDepositDao method creates an instance ofFixedDepositJdbcDaoinstanceifthevalueofdaoTypeargumentisjdbc. It is important tonote that thegetFixedDepositDaomethoddoesn’tsetthedatabaseInfopropertyoftheFixedDepositJdbcDaoinstance.

Aswesawinexample listing2-8, thefollowingbeandefinitions instructSpringcontainer tocreateaninstance of FixedDepositJdbcDao by invoking the getFixedDepositDao instance factory method ofFixedDepositDaoFactoryclass:

Examplelisting2-14–ConfigurationtoinvokeFixedDepositDaoFactory’sgetFixedDepositDaomethod<beanid="daoFactory"class="FixedDepositDaoFactory"/>

<beanid="dao"factory-bean="daoFactory"factory-method="getFixedDepositDao"><constructor-argindex="0"value="jdbc"/></bean>

ThedaobeandefinitionresultsininvocationofFixedDepositDaoFactory’sgetFixedDepositDaomethod,which creates and returns an instance of FixedDepositJdbcDao. But, the FixedDepositJdbcDao’sdatabaseInfopropertyisnotset.TosetthedatabaseInfodependency,youcanperformsetter-basedDIontheFixedDepositJdbcDaoinstancereturnedbythegetFixedDepositDaomethod,asshownhere:

Examplelisting2-15–ConfigurationtoinvokeFixedDepositDaoFactory’sgetFixedDepositDaomethodandsetdatabaseInfopropertyofreturnedFixedDepositJdbcDaoinstance

<beanid="daoFactory"class="FixedDepositDaoFactory"/><beanid="dao"factory-bean="daoFactory"factory-method="getFixedDepositDao"><constructor-argindex="0"value="jdbc"/><propertyname="databaseInfo"ref="databaseInfo"/></bean><beanid="databaseInfo"class="DatabaseInfo"/>

Page 56: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

The above bean definition shows that <property> element is used to set databaseInfo property ofFixedDepositJdbcDao instance returned by getFixedDepositDao instance factory method. As with theinstancefactorymethod,youcanusethe<property>elementtoinjectdependenciesintothebeaninstancereturnedbythestaticfactorymethod.

Let’snowlookathowtoinjectbeandependenciesviaconstructorarguments.

Constructor-basedDIInconstructor-basedDI,dependenciesofabeanarepassedasargumentstothebeanclass’sconstructor.For instance, the following example listing shows PersonalBankingService class whose constructoracceptsJmsMessageSender,EmailMessageSenderandWebServiceInvokerobjects:

Examplelisting2-16–PersonalBankingServiceclasspublicclassPersonalBankingService{privateJmsMessageSenderjmsMessageSender;privateEmailMessageSenderemailMessageSender;privateWebServiceInvokerwebServiceInvoker;.....publicPersonalBankingService(JmsMessageSenderjmsMessageSender,EmailMessageSenderemailMessageSender,WebServiceInvokerwebServiceInvoker){this.jmsMessageSender=jmsMessageSender;this.emailMessageSender=emailMessageSender;this.webServiceInvoker=webServiceInvoker;}.....}

The arguments to the PersonalBankingService’s constructor represent dependencies of thePersonalBankingService class. The following example listing shows how dependencies ofPersonalBankingServiceinstancearesuppliedvia<constructor-arg>elements:

Examplelisting2-17–PersonalBankingServicebeandefinition<beanid="personalBankingService"class="PersonalBankingService"><constructor-argindex="0"ref="jmsMessageSender"/><constructor-argindex="1"ref="emailMessageSender"/><constructor-argindex="2"ref="webServiceInvoker"/></bean><beanid="jmsMessageSender"class="JmsMessageSender">

Page 57: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....</bean><beanid="webServiceInvoker"class="WebServiceInvoker"/>.....</bean><beanid="emailMessageSender"class="EmailMessageSender"/>.....</bean>

In the above example listing, <constructor-arg> elements specify details of the constructor argumentspassedtothePersonalBankingServiceinstance.Theindexattributespecifiestheindexoftheconstructorargument.Iftheindexattributevalueis0,itmeansthatthe<constructor-arg>elementcorrespondstothefirstconstructorargument,andiftheindexattributevalueis1,itmeansthatthe<constructor-arg>elementcorrespondstothesecondconstructorargument,andsoon.Wesawearlierthatrefattributeof<property>element isusedforpassingreference toabean.Similarly, refattributeof<constructor-arg>element isusedforpassingreferencetoabean.Likethe<property>element,the<constructor-arg>elementisalsousedtopassconfigurationinformation(ifany)requiredbythebean.

You should note that the <constructor-arg> element is also used for passing arguments to static andinstancefactorymethodsthatcreatebeaninstances(refersection2-3).

NOTE Insteadof using ref attributeof<property> and<constructor-arg> elements, you can use <ref>elementinsidethe<property>and<constructor-arg>elementstosetreferencetobeans.TherefattributeispreferredasitmakestheXMLlessverbose.

The following example listing shows the EmailMessageSender class and the corresponding beandefinitionthatdemonstratesuseof<constructor-arg>elementstosupplyvaluesforStringtypeconstructorarguments:

Examplelisting2-18EmailMessageSenderclassandthecorrespondingbeandefinition

publicclassEmailMessageSender{privateStringhost;privateStringusername;privateStringpassword;.....publicEmailMessageSender(Stringhost,Stringusername,Stringpassword){this.host=host;this.username=username;this.password=password;}.....}<beanid="emailMessageSender"class="EmailMessageSender"><constructor-argindex="0"value="smtp.gmail.com"/><constructor-argindex="1"value="myusername"/><constructor-argindex="2"value="mypassword"/></bean>

Page 58: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Sofarwehaveseenthat<constructor-arg>elementisusedforinjectingbeandependenciesandpassingvaluesforStringtypeconstructorarguments.Inchapter3,we’llseehowthe<constructor-arg>elementisusedtosetprimitivetype(likeint,long,andsoon),collectiontype(likejava.util.List,java.util.Map,andsoon)andcustomtype(likeAddress)properties.

Let’snowlookathowwecanuseconstructor-basedDIalongwithsetter-basedDI.

Usingamixofconstructor-andsetter-basedDImechanisms

Ifabeanclassrequiresbothconstructor-andsetter-basedDImechanisms,youcanuseacombinationof<constructor-arg>and<property>elementstoinjectdependencies.

The following example listing shows a bean class whose dependencies are injected as arguments toconstructorandsettermethods:

Examplelisting2-19–PersonalBankingServiceclasspublicclassPersonalBankingService{privateJmsMessageSenderjmsMessageSender;privateEmailMessageSenderemailMessageSender;privateWebServiceInvokerwebServiceInvoker;.....publicPersonalBankingService(JmsMessageSenderjmsMessageSender,EmailMessageSenderemailMessageSender){this.jmsMessageSender=jmsMessageSender;this.emailMessageSender=emailMessageSender;}publicvoidsetWebServiceInvoker(WebServiceInvokerwebServiceInvoker){this.webServiceInvoker=webServiceInvoker;}.....}

In the PersonalBankingService class, jmsMessageSender and emailMessageSender dependencies areinjected as constructor arguments, and webServiceInvoker dependency is injected via thesetWebServiceInvoker settermethod.The following bean definition shows that both <constructor-arg>and<property>elementsareusedtoinjectdependenciesofPersonalBankingServiceclass:

Examplelisting2-20–Mixingconstructor-andsetter-basedDImechanisms<beanid="dataSource"class="PersonalBankingService"><constructor-argindex="0"ref="jmsMessageSender"/><constructor-argindex="1"ref="emailMessageSender"/><propertyname="webServiceInvoker"ref="webServiceInvoker"/></bean>

Now, thatwehaveseenhow to instructSpringcontainer tocreatebeansandperformDI, let’s lookat

Page 59: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

differentscopesthatyoucanspecifyforbeans.

Page 60: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

2-5BeanscopesYoumaywanttospecifythescopeofabeantocontrolwhetherasharedinstanceofthebeaniscreated(singletonscope),oranewbeaninstanceiscreatedeverytimethebeanisrequested(prototypescope)fromtheSpringcontainer.Thescopeofabeanisdefinedbythescopeattributeofthe<bean>element.Ifthescopeattributeisnotspecified,itmeansthatthebeanisasingleton-scopedbean.

NOTEInwebapplicationscenarios,Springallowsyoutospecifyadditionalscopes:request, sessionand globalSession. These scopes determine the lifetime of the bean instance. For instance, a request-scopedbean’s lifetime is limited toa singleHTTP request.As in this chapterwe’llnot be discussingSpringWebMVCorSpringPortletMVC,we’llrestrictthediscussiontosingletonandprototypescopes.Therequest,sessionandglobalSessionscopesaredescribedinchapter10.

IMPORTchapter2/ch02-bankapp-scopes (Thisproject showsusageof singletonandprototype beanscopes.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject.Theprojectalsocontains2JUnittests,PrototypeTestandSingletonTestthatyoucanexecute)

SingletonThesingletonscope is thedefault scope forall thebeansdefined in theapplicationcontextXMLfile.Instance of a singleton-scoped bean is createdwhen the Spring container is created, and is destroyedwhentheSpringcontainerisdestroyed.Springcontainercreatesasingleinstanceofasingleton-scopedbean,whichissharedbyallthebeansthatdependonit.

ThefollowingexamplelistingshowstheapplicationContext.xmlfileofch02-bankapp-scopesproject inwhichallthebeansaresingleton-scoped:

Examplelisting2-21–applicationContext.xml-Singleton-scopedbeansProject–ch02-bankapp-scopesSourcelocation-src/main/resources/META-INF/spring<beans.....><beanid="controller"class="sample.spring.chapter02.bankapp.controller.FixedDepositControllerImpl"><propertyname=“fixedDepositService"ref="service"/></bean><beanid="service"class="sample.spring.chapter02.bankapp.service.FixedDepositServiceImpl"><propertyname=“fixedDepositDao"ref="dao"/></bean><beanid="dao"class="sample.spring.chapter02.bankapp.dao.FixedDepositDaoImpl"/>.....</beans>

IntheaboveapplicationContext.xmlfile,controller,serviceanddaobeansaresingleton-scopedbecauseno scope attribute is specified for the <bean> elements. This means that only a single instance of

Page 61: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

FixedDepositControllerImpl,FixedDepositServiceImplandFixedDepositDaoImplclasses is createdbytheSpringcontainer.Asthesebeansaresingleton-scoped,SpringcontainerreturnsthesameinstanceofthebeaneverytimeweretrieveoneofthesebeansusingApplicationContext’sgetBeanmethod.

NOTEIfthescopeattributeisnotspecifiedorthevalueofscopeattributeissingleton,itmeansthatthebeanissingleton-scoped.

ThefollowingexamplelistingshowsthetestInstancesmethodofSingletonTest(aJUnittestclass)classofch02-bankapp-scopes project. The testInstances method tests whether multiple invocation ofApplicationContext’sgetBeanmethodreturnsthesameordifferentinstanceofthecontrollerbean:

Examplelisting2-22–SingletonTestJUnittestclassProject–ch02-bankapp-scopesSourcelocation-src/test/java/sample/spring/chapter02/bankapppackagesample.spring.chapter02.bankapp;importstaticorg.junit.Assert.assertSame;importorg.junit.BeforeClass;importorg.junit.Test;importsample.spring.chapter02.bankapp.controller.FixedDepositController;publicclassSingletonTest{privatestaticApplicationContextcontext;@BeforeClasspublicstaticvoidinit(){context=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");}@TestpublicvoidtestInstances(){FixedDepositControllercontroller1=(FixedDepositController)context.getBean("controller");FixedDepositControllercontroller2=(FixedDepositController)context.getBean("controller");assertSame("DifferentFixedDepositControllerinstances",controller1,controller2);}.....}

Intheaboveexamplelisting,JUnit’s@BeforeClassannotationspecifies that theinitmethod is invokedbeforeanyofthetestmethods(thatis,methodsannotatedwithJUnit’s@Testannotation)intheclass.Thismeans that@BeforeClass annotated method is invoked only once, and@Test annotated methods areexecutedonlyaftertheexecutionof@BeforeClassannotatedmethod.Notethattheinitmethodisastaticmethod.The initmethod creates an instanceofApplicationContext object by passing the configurationmetadata (shown in example listing 2-21) to the ClassPathXmlApplicationContext’s constructor. The

Page 62: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

testInstancesmethodobtains2instancesofcontrollerbeanandcheckswhetherboththeinstancesarethesamebyusingJUnit’sassertSameassertion.Asthecontrollerbeanissingleton-scoped,controller1andcontroller2 bean instances are the same. For this reason, SingletonTest’s testInstances test executeswithoutanyassertionerrors.

Thefollowingfigureshowsthat theSpringcontainerreturns thesameinstanceofcontrollerbeanwhenyoucalltheApplicationContext’sgetBeanmethodmultipletimes:

Figure2-4Multiplerequestsforasingleton-scopedbeanresultsinthesamebeaninstancereturnedbytheSpringcontainer

The above figure shows thatmultiple calls to obtain controller bean returns the same instance of thecontrollerbean.

NOTEInfigure2-4,thecontrollerbeaninstanceisrepresentedbya2-compartmentrectangle.Thetopcompartmentshowsthenameofthebean(thatis,thevalueoftheidattributeofthe<bean>element)andthebottomcompartmentshowsthetypeofthebean(thatis,thevalueoftheclassattributeofthe<bean>element). In the rest of this book, we’ll use this convention to show bean instances inside a Springcontainer.

Asingleton-scopedbeaninstanceissharedamongstthebeansthatdependonit.Thefollowingexamplelisting shows the testReference method of SingletonTest JUnit test class that checks if theFixedDepositDao instance referenced by the FixedDepositController instance is the same as the oneobtaineddirectlybycallinggetBeanmethodofApplicationContext:

Examplelisting2-23–testReferencemethodofSingletonTestJUnittestclassProject–ch02-bankapp-scopesSourcelocation-src/test/java/sample/spring/chapter02/bankapppackagesample.spring.chapter02.bankapp;importstaticorg.junit.Assert.assertSame;importorg.junit.Test;

Page 63: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicclassSingletonTest{privatestaticApplicationContextcontext;.....@TestpublicvoidtestReference(){FixedDepositControllercontroller=(FixedDepositController)context.getBean("controller");FixedDepositDaofixedDepositDao1=controller.getFixedDepositService().getFixedDepositDao();FixedDepositDaofixedDepositDao2=(FixedDepositDao)context.getBean("dao");assertSame("DifferentFixedDepositDaoinstances",fixedDepositDao1,fixedDepositDao2);}}

Intheaboveexamplelisting,thetestReferencemethodfirstretrievestheFixedDepositDaoinstance(referfixedDepositDao1variableintheaboveexamplelisting)referencedbytheFixedDepositControllerbean,followed by directly retrieving another instance of FixedDepositDao bean (refer fixedDepositDao2variable in the above example listing) usingApplicationContext’s getBeanmethod. If you execute thetestReference test, you’ll see that the test completes successfully because the fixedDepositDao1 andfixedDepositDao2instancesarethesame.

Figure2-5showsthattheFixedDepositDaoinstancereferencedbyFixedDepositControllerinstanceisthesameastheonereturnedbyinvokinggetBean("dao")methodonApplicationContext.

Figure2-5Singleton-scopedbeaninstanceissharedbetweenbeansthatdependonit

Theabovefigureshows that theFixedDepositDao instancereferencedbyFixedDepositController beaninstance and the one retrieved directly by callingApplicationContext’s getBean are same. If there aremultiple beans dependent on a singleton-scoped bean, then all the dependent beans share the samesingleton-scopedbeaninstance.

Page 64: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Let’s now look atwhether or not the same singleton-scoped bean instance is shared betweenmultipleSpringcontainerinstances.

Singleton-scopedbeansandmultipleSpringcontainerinstances

Thescopeofasingleton-scopedbeaninstanceislimitedtotheSpringcontainerinstance.Thismeansthatif you create 2 instances of the Spring container using the same configuration metadata, each Springcontainerhasitsowninstancesofthesingleton-scopedbeans.

ThefollowingexamplelistingshowsthetestSingletonScopemethodofSingletonTestclass,which testswhethertheFixedDepositControllerbeaninstanceretrievedfromtwodifferentSpringcontainerinstancesaresameordifferent:

Examplelisting2-24–testSingletonScopemethodofSingletonTestJUnittestclassProject–ch02-bankapp-scopesSourcelocation-src/test/java/sample/spring/chapter02/bankapp

packagesample.spring.chapter02.bankapp;importstaticorg.junit.Assert.assertNotSame;publicclassSingletonTest{privatestaticApplicationContextcontext;.....@BeforeClasspublicstaticvoidinit(){context=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");}@TestpublicvoidtestSingletonScope(){ApplicationContextanotherContext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");FixedDepositControllerfixedDepositController1=(FixedDepositController)anotherContext.getBean("controller");FixedDepositControllerfixedDepositController2=(FixedDepositController)context.getBean("controller");assertNotSame("SameFixedDepositControllerinstances",fixedDepositController1,fixedDepositController2);}}

Page 65: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

TheSingletonTest’sinitmethod(annotatedwithJUnit’s@BeforeClassannotation)createsaninstanceofApplicationContext(identifiedbycontextvariable)beforeany@Testannotatedmethodisexecuted.ThetestSingletonScopemethodcreatesonemore instanceofSpringcontainer (identifiedbyanotherContextvariable) using the same applicationContext.xml file. An instance of FixedDepositController bean isretrieved from both the Spring containers and checked if they are not the same. If you execute thetestSingletonScope test, you’ll find that the test completes successfully because theFixedDepositControllerbeaninstanceretrievedfromcontextinstanceisdifferentfromtheoneretrievedfromanotherContextinstance.

ThefollowingfiguredepictsthebehaviorexhibitedbythetestSingletonScopemethod:

Figure2-6EachSpringcontainercreatesitsowninstanceofasingleton-scopedbean

TheabovefigureshowsthateachSpringcontainercreatesitsowninstanceofcontrollerbean.ThisisthereasonwhycontextandanotherContext instances returndifferent instancesofcontrollerbeanwhenyoucallgetBean("controller")method.

ThetestSingletonScopemethodshowedthateachSpringcontainercreatesitsowninstanceofasingleton-scopedbean.ItisimportanttonotethatSpringcontainercreatesaninstanceofasingleton-scopedbeanfor each bean definition. The following example listing shows multiple bean definitions for theFixedDepositDaoImplclass:

Examplelisting2-25–applicationContext.xml-MultiplebeandefinitionsforthesameclassProject–ch02-bankapp-scopesSourcelocation-src/main/resources/META-INF/spring<beanid="dao"class="sample.spring.chapter02.bankapp.dao.FixedDepositDaoImpl"/><beanid="anotherDao"class="sample.spring.chapter02.bankapp.dao.FixedDepositDaoImpl"/>

ThebeandefinitionsshownintheaboveexamplelistingareforFixedDepositDaoImplclass.Asscopeattributeisnotspecified,beandefinitionsshownintheaboveexamplelistingrepresentsingleton-scopedbeans.Evenifmultiplebeandefinitionsaredefinedforaclass,Springcontainercreatesabeaninstancecorresponding to each bean definition. This means that Spring container creates distinct instances ofFixedDepositDaoImpl class corresponding to dao and anotherDao bean definitions. The followingexample listing shows SingletonScope’s testSingletonScopePerBeanDef method that tests whether the

Page 66: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

FixedDepositDaoImpl instances corresponding to dao and anotherDao bean definitions are same ordifferent:

Examplelisting2-26–testSingletonScopePerBeanDefmethodofSingletonTestJUnittestclassProject–ch02-bankapp-scopesSourcelocation-src/test/java/sample/spring/chapter02/bankapp

packagesample.spring.chapter02.bankapp;importstaticorg.junit.Assert.assertNotSame;publicclassSingletonTest{privatestaticApplicationContextcontext;.....@TestpublicvoidtestSingletonScopePerBeanDef(){FixedDepositDaofixedDepositDao1=(FixedDepositDao)context.getBean("dao");FixedDepositDaofixedDepositDao2=(FixedDepositDao)context.getBean("anotherDao");assertNotSame("SameFixedDepositDaoinstances",fixedDepositDao1,fixedDepositDao2);}}In theaboveexample listing, fixedDepositDao1andfixedDepositDao2variables represent instancesofFixedDepositDaoImplclassthatSpringcontainercreatescorrespondingtothedaoandanotherDaobeandefinitions, respectively. If you execute the testSingleScopePerBeanDef test, it’ll execute without anyassertion errors because the fixedDepositDao1 instance (corresponding to dao bean definition) andfixedDepositDao2instance(correspondingtoanotherDaobeandefinition)aredistinct.

Thefollowingfiguresummarizesthatasingleton-scopedbeaniscreatedperbeandefinition:

Figure2-7Thereisonesingleton-scopedbeaninstanceperbeandefinition

Theabovefigureshowsthatthereexistsoneinstanceofsingleton-scopedbeanperbeandefinitionintheSpringcontainer.

We mentioned earlier that a singleton-scoped bean is pre-instantiated by default, which means aninstanceofasingleton-scopedbeaniscreatedwhenyoucreateaninstanceoftheSpringcontainer.Let’snowlookathowyoucanlazilyinitializeasingleton-scopedbean.

Page 67: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Lazilyinitializingasingleton-scopedbean

You can instruct Spring container to create an instance of a singleton-scoped bean only when it isrequested for the first time. The following lazyExample bean definition shows how to instruct SpringcontainertolazyinitializelazyBeanbean:

Examplelisting2-27–Lazilyinitializingasingleton-scopedbean<beanid="lazyBean"class="example.LazyBean"lazy-init=”true”/>

The<bean>element’slazy-initattributespecifieswhetherthebeaninstanceiscreatedlazilyoreagerly.Ifthevalueistrue(as incaseof thebeandefinitionshownabove), thebeaninstanceis initializedbytheSpringcontainerwhenitreceivestherequestforthebeanforthefirsttime.

Thefollowingsequencediagramshowshowlazy-initattributeaffectsthecreationofasingleton-scopedbeaninstance:

Figure2-8Alazily-initializedsingleton-scopedbeaninstanceiscreatedwhenitisrequestedforthefirsttimebytheapplication

In the above diagram,BeanA represents a singleton-scoped bean instance that isnot set to be lazily-initialized,andLazyBeanrepresentsasingleton-scopedbeanthatissettobelazily-initialized.WhentheSpring container instance is created, BeanA is also instantiated because it is not set to be lazily-initialized.On the other hand, LazyBean is instantiated whenApplicationContext’s getBean method isinvokedforthetimefirsttimetoretrieveaninstanceofLazyBeanfromtheSpringcontainer.

NOTEYoucanuse<beans>element’sdefault-lazy-initattributetospecifydefaultinitializationstrategyforbeansdefinesintheapplicationcontextXMLfile.Ifthe<bean>element’slazy-initattributespecifiesadifferentvaluethanthe<beans>element’sdefault-lazy-init,thevaluespecifiedbythelazy-initattributeappliestothebean.

Asasingleton-scopedbeancanbelazily-initializedorpre-instantiatedbytheSpringcontainer,youmaybethinkingatthistimewhetheryoushoulddefineyoursingleton-scopedbeanstobelazily-initializedorpre-instantiated.Inmostapplicationscenarios,itisbeneficialtopre-instantiatesingleton-scopedbeanstodiscover configuration issues at the time of creation of the Spring container. The following example

Page 68: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

listingshowsaaBeansingleton-scopedbeanthatissettobelazily-initialized,andthatdependsonbBeanbean:

Examplelisting2-28–Alazily-initializedsingleton-scopedbeanpublicclassABean{privateBBeanbBean;publicvoidsetBBean(BBeanbBean){this.bBean=bBean;}.....}<beanid="aBean"class="ABean"lazy-init="true"><propertyname="bBean"value="bBean"/></bean><beanid="bBean"class="BBean"/>

Intheaboveexamplelisting,ABean’sbBeanpropertyreferstotheBBeanbean.Noticethatinsteadofrefattribute, value attribute of <property> element has been used to set ABean’s bBean property. If youcreateanApplicationContextinstancebypassingittheXMLfilecontainingtheabovebeandefinition,noerrors will be reported. But, when you try to fetch the aBean bean by invoking ApplicationContext’sgetBeanmethod,you’llgetthefollowingerrormessage:Causedby:java.lang.IllegalStateException:Cannotconvertvalueoftype[java.lang.String]torequiredtype[BBean]forproperty'bBean:nomatchingeditorsorconversionstrategyfound

The above error message is shown because the Spring container fails to convert the String value ofABean’sbBeanpropertytoBBeantype.Thishighlightsasimpleconfigurationissueinwhichinsteadofspecifying<bean>element’srefattribute,valueattributewasspecified.IftheaBeanbeanwasdefinedaspre-instantiated(insteadoflazily-initialized),theaboveconfigurationissuecouldhavebeencaughtatthetimewecreatedaninstanceofApplicationContext,andnotwhenwetriedtoobtainaninstanceofaBeanbeanfromtheApplicationContext.

Let’snowlookatprototype-scopedbeansinSpring.

PrototypeAprototype-scopedbeanisdifferentfromasingleton-scopedbeaninthesensethattheSpringcontaineralways returns a new instance of a prototype-scoped bean. Another distinctive feature of prototype-scopedbeansisthattheyarealwayslazily-initialized.

The following FixedDepositDetails bean in the applicationContext.xml file of ch02-bankapp-scopesprojectrepresentsaprototype-scopedbean:

Examplelisting2-29–applicationContext.xml-Aprototype-scopedbeanexampleProject–ch02-bankapp-scopesSourcelocation-src/main/resources/META-INF/spring

Page 69: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="FixedDepositDetails"class="sample.spring.chapter02.bankapp.domain.FixedDepositDetails"scope="prototype"/>

Theaboveexamplelistingshowsthatthe<bean>element’sscopeattributevalueissettoprototype.ThismeansthattheFixedDepositDetailsbeanisaprototype-scopedbean.

The following testInstances method of PrototypeTest JUnit test class shows that the 2 instances ofFixedDepositDetailsbeanretrievedfromtheSpringcontaineraredifferent:

Examplelisting2-30–testInstancesmethodofPrototypeTestJUnittestclassProject–ch02-bankapp-scopesSourcelocation-src/test/java/sample/spring/chapter02/bankapp

packagesample.spring.chapter02.bankapp;importstaticorg.junit.Assert.assertNotSame;publicclassPrototypeTest{privatestaticApplicationContextcontext;.....@TestpublicvoidtestInstances(){FixedDepositDetailsfixedDepositDetails1=(FixedDepositDetails)context.getBean("fixedDepositDetails");FixedDepositDetailsfixedDepositDetails2=(FixedDepositDetails)context.getBean("fixedDepositDetails");assertNotSame("SameFixedDepositDetailsinstances",fixedDepositDetails1,fixedDepositDetails2);}}

If you execute the testInstances test, it’ll complete without any assertion errors because the 2FixedDepositDetails instances (fixedDepositDetails1 and fixedDepositDetails2) obtained from theApplicationContextaredifferent.

Let’snowlookathowtochoosetherightscope(singletonorprototype)forabean.

ChoosingtherightscopeforyourbeansIfabeandoesn’tmaintainanyconversationalstate(thatis,itisstatelessinnature),itshouldbedefinedasa singleton-scopedbean. If a beanmaintains conversational state, it shouldbedefined as a prototype-scopedbean.FixedDepositServiceImpl,FixedDepositDaoImplandFixedDepositControllerImplbeansofMyBank application are stateless in nature; therefore, they are defined as singleton-scoped beans.FixedDepositDetails bean (a domain object) of MyBank application maintains conversational state;therefore,itisdefinedasaprototype-scopedbean.

Page 70: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

NOTEIfyouareusinganORMframework(likeHibenateoriBATIS)inyourapplication,thedomainobjectsarecreatedeitherbytheORMframeworkoryoucreatethemprogrammaticallyinyourapplicationcodeusingthenewoperator.ItisbecauseofthisreasondomainobjectsarenotdefinedintheapplicationcontextXMLfileiftheapplicationusesanORMframeworkforpersistence.

Page 71: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

2-6SummaryIn this chapter,wediscussed someof thebasicsofSpringFramework.We lookedat ‘programming tointerfaces’designapproach,differentapproachestocreatebeaninstances,constructor-basedDIandbeanscopes.Inthenextchapter,we’lllookathowtosetdifferenttypes(likeint,long,Map,Set,andsoon)ofbeanpropertiesandconstructorarguments.

Page 72: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter3-Configuringbeans

Page 73: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-1IntroductionInpreviouschapters,we toucheduponsomeof thebasicconceptsofSpringFramework.WesawhowSpringbeansandtheirdependenciesarespecifiedintheapplicationcontextXMLfile.Wealsolookedatsingleton-andprototype-scopedbeans,anddiscussedtheimplicationsofassigningthesescopestobeans.Inthischapter,we’lllookat:

§beandefinitioninheritance§howargumentstoabeanclass’sconstructorareresolved§howtoconfigurebeanpropertiesandconstructorargumentsofprimitivetype(likeint,float,andso

on),collectiontype(likejava.util.List,java.util.Map,andsoon),customtype(likeAddress),andsoon

§ how you canmake the application contextXML file less verbose by using p-namespace and c-namespacetospecifybeanpropertiesandconstructorarguments,respectively

§ Spring’sFactoryBean interface thatallowsyou towriteyourownfactoryclass forcreatingbeaninstances

Page 74: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-2BeandefinitioninheritanceWesawinchapter1and2thatabeandefinitionintheapplicationcontextXMLfilespecifiesthefully-qualifiednameofthebeanclassanditsdependencies.Insomescenarios,tomakeabeandefinitionlessverbose,youmaywantabeandefinitiontoinheritconfigurationinformationfromanotherbeandefinition.Let’slookatonesuchscenarioinMyBankapplication.

IMPORTchapter3/ch03-bankapp-inheritance (Thisproject shows theMyBankapplication thatusesbeandefinitioninheritance.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

MyBank–BeandefinitioninheritanceexampleInthepreviouschapter,wesawthattheMyBankapplicationaccessesdatabasethroughDAOs.Let’ssaythat the MyBank application defines a DatabaseOperations class that simplifies interacting with thedatabase.So,all theDAOsintheMyBankapplicationdependonDatabaseOperationsclass toperformdatabaseoperations,asshowninthefollowingfigure:

Figure 3-1 - DAO classes inMyBank application make use of DatabaseOperations class to performdatabaseinteraction

TheabovefigureshowsthattheFixedDepositDaoandPersonalBankingDaoclassesaredependentontheDatabaseOperations class. The following application contextXML file shows the bean definitions fortheseclasses:

Examplelisting3-1–DAObeansaredependentonDatabaseOperationsbean<beanid="databaseOperations"class="sample.spring.chapter01.bankapp.utils.DatabaseOperations"/><beanid="personalBankingDao"class="sample.spring.chapter01.bankapp.dao.PersonalBankingDaoImpl"><propertyname="databaseOperations"ref="databaseOperations"/></bean>

Page 75: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="FixedDepositDao"class="sample.spring.chapter01.bankapp.dao.FixedDepositDaoImpl"><propertyname="databaseOperations"ref="databaseOperations"/></bean>

Both the personalBankingDao and FixedDepositDao bean definitions use the <property> element toperformdependencyinjectionoftheDatabaseOperationsinstance.AsthenameofthepropertythatreferstotheDatabaseOperationsinstanceisdatabaseOperationsinboththebeandefinitions,itimpliesthatbothPersonalBankingDaoImpl andFixedDepositDaoImpl classes define a setDatabaseOperationsmethod toallowSpringcontainertoinjectDatabaseOperationsinstance.

If multiple beans in your application share a common set of configuration (properties, constructorarguments,andsoon),youcancreateabeandefinitionthatactsasaparentforotherbeandefinitions.Incase of personalBankingDao and fixedDepositDao bean definitions, the common configuration is thedatabaseOperations property. The following example listing shows that the personalBankingDao andfixedDepositDaobeandefinitionsmakeuseofbeandefinitioninheritance:

Examplelisting3-2–applicationContext.xml-MyBank’sapplicationcontextXMLfileProject–ch03-bankapp-inheritanceSourcelocation-src/main/resources/META-INF/spring<beanid="databaseOperations"class="sample.spring.chapter03.bankapp.utils.DatabaseOperations"/><beanid="daoTemplate"abstract="true"><propertyname="databaseOperations"ref="databaseOperations"/></bean><beanid="FixedDepositDao"parent="daoTemplate"class="sample.spring.chapter03.bankapp.dao.FixedDepositDaoImpl"/><beanid="personalBankingDao"parent="daoTemplate"class="sample.spring.chapter03.bankapp.dao.PersonalBankingDaoImpl"/>

Intheaboveexamplelisting,thedaoTemplatebeandefinitiondefinesthecommonconfigurationsharedbyboth the fixedDepositDao andpersonalBankingDaobeandefinitions.Asboth the fixedDepositDao andpersonalBankingDaobeandefinitionsrequirethedatabaseOperationsdependency(referexample listing3-1), thedaoTemplatebeandefinitiondefines thedatabaseOperationsdependencyusing the<property>element.The<bean>element’sparentattributespecifiesthenameofthebeandefinitionfromwhichtheconfiguration is inherited. As the parent attribute value is daoTemplate for fixedDepositDao andpersonalBankingDao bean definitions, they inherit databaseOperations property from the daoTemplatebeandefinition.Theexamplelistings3-1and3-2aresame,exceptthattheexamplelisting3-2makesuseofbeandefinitioninheritance.

Ifthe<bean>element’sabstractattributevalueissettotrue,itmeansthatthebeandefinitionisabstract.It is important to note that the Spring container doesn’t attempt to create a bean corresponding to anabstractbeandefinition.Itisimportanttonotethatyoucan’tdefineabeantobedependentonanabstract

Page 76: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

bean,thatis,youcan’tuse<property>or<constructor-arg>elementtorefertoanabstractbean.

In example listing 3-2, daoTemplate bean definition is abstract. You may have noticed that thedaoTemplatebeandefinitiondoesn’tspecifytheclassattribute.Ifaparentbeandefinitiondoesn’tspecifytheclassattribute,childbeandefinitions(likethefixedDepositDaoandpersonalBankingDao)specifytheclass attribute. It is important to note that if you don’t specify the class attribute, youmust define theparent bean definition as abstract so that Spring container doesn’t attempt to create a bean instancecorrespondingtoit.

Toverify that thefixedDepositDaoandpersonalBankingDaobeandefinitions inheritdaoTemplate beandefinition’sdatabaseOperationsproperty,execute themainmethodofBankAppclassof ch03-bankapp-inheritance project. BankApp’s main method invokes methods on the fixedDepositDao andpersonalBankingDaobeans;thosebeansinturninvokemethodsontheDatabaseOperationsinstance.IfaDatabaseOperations instance isnot injected into the fixedDepositDao and personalBankingDao beans,java.lang.NullPointerExceptionwillbethrown.

Thefollowingdiagramsummarizeshowbeandefinition inheritanceworks incaseofFixedDepositDaoandpersonalBankingDaobeandefinitions:

Figure3-2–BeandefinitioninheritanceinMyBankapplication

Theabove figure shows that the fixedDepositDaoandpersonalBankingDaobeandefinitions inherit thedatabaseOperations property (shown in italics in the boxes labeled fixedDepositDao andpersonalBankingDao)fromthedaoTemplatebeandefinition.TheabovefigurealsodepictsthattheSpringcontainer doesn’t attempt to create a bean instance corresponding to the daoTemplate bean definitionbecauseitismarkedasabstract.

Let’snowlookatwhatconfigurationinformationgetsinheritedfromtheparentbeandefinition.

Whatgetsinherited?Achildbeandefinitioninheritsthefollowingconfigurationinformationfromtheparentbeandefinition:

·properties–specifiedvia<property>elements·constructorarguments–specifiedvia<constructor-arg>elements·methodoverrides(discussedinsection4-5ofchapter4)

Page 77: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

·initializationanddestroymethods(discussedinchapter5),and·factorymethods–specifiedviafactory-methodattributeof<bean>element(refersection2-3of

chapter2toknowhowstaticandinstancefactorymethodsareusedforcreatingbeans)IMPORTchapter3/ch03-bankapp-inheritance-example (Thisprojectshows theMyBankapplicationthatusesbeandefinitioninheritance.Inthisproject,you’llseemultiplescenariosinwhichbeandefinitioninheritanceisused.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

Let’snowlookatsomeofthebeandefinitioninheritanceexamples.

Beandefinitioninheritanceexample–parentbeandefinitionisnotabstract

Thefollowingexample listingshowsabeaninheritanceexample inwhichtheparentbeandefinitionisnotabstract,andthechildbeandefinitionsdefineanadditionaldependency:

Examplelisting3-3–applicationContext.xml-Beandefinitioninheritance–parentbeandefinitionisnotabstractProject–ch03-bankapp-inheritance-examplesSourcelocation-src/main/resources/META-INF/spring<beanid="serviceTemplate"class="sample.spring.chapter03.bankapp.base.ServiceTemplate"><propertyname="jmsMessageSender"ref="jmsMessageSender"/><propertyname="emailMessageSender"ref="emailMessageSender"/><propertyname="webServiceInvoker"ref="webServiceInvoker"/></bean><beanid="fixedDepositService"class=".....FixedDepositServiceImpl"parent="serviceTemplate"><propertyname=“fixedDepositDao"ref="fixedDepositDao"/></bean><beanid="personalBankingService"class=".....PersonalBankingServiceImpl"parent="serviceTemplate"><propertyname="personalBankingDao"ref="personalBankingDao"/></bean><beanid="userRequestController"class=".....UserRequestControllerImpl"><propertyname="serviceTemplate"ref="serviceTemplate"/></bean>

A littlebackgroundbeforewedelve into thedetailsof theabove listedconfiguration: a service in theMyBank applicationmay send JMSmessages to amessaging-middleware or send emails to an emailserveror itmay invokeanexternalwebservice. In theaboveexample listing, the jmsMessageSender,emailMessageSender and webServiceInvoker beans simplify these tasks by providing a layer ofabstraction.TheserviceTemplatebeanprovidesaccesstojmsMessageSender,emailMessageSenderandwebServiceInvoker beans. This is the reason why the serviceTemplate bean is dependent on the

Page 78: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

jmsMessageSender,emailMessageSenderandwebServiceInvokerbeans.

Example listing 3-3 shows that the serviceTemplate bean definition is the parent bean definition offixedDepositServiceandpersonalBankingServicebeandefinitions.NoticethattheserviceTemplatebeandefinitionisnotabstract;theclassattributespecifiesServiceTemplateastheclass.Inourpreviousbeandefinition inheritance example (refer example listing 3-2), child bean definitions didn’t define anyproperties.Intheaboveexamplelisting,noticethatthefixedDepositServiceandpersonalBankingServicechildbeandefinitionsdefinefixedDepositDaoandpersonalBankingDaoproperties,respectively.

As parent bean definition’s properties are inherited by the child bean definitions,FixedDepositServiceImpl and PersonalBankingServiceImpl classes must define setter methods forjmsMessageSender, emailMessageSender and webServiceInvoker properties. You have the option toeither define setter methods in FixedDepositServiceImpl and PersonalBankingServiceImpl classes ormake FixedDepositServiceImpl and PersonalBankingServiceImpl classes as subclasses ofServiceTemplate class. In ch03-bankapp-inheritance-examples, the FixedDepositServiceImpl andPersonalBankingServiceImplclassesaresubclassesofServiceTemplateclass.

ThefollowingexamplelistingshowsthePersonalBankingServiceImplclass:

Examplelisting3-4–PersonalBankingServiceImplclassProject–ch03-bankapp-inheritance-examplesSourcelocation-src/main/java/sample/spring/chapter03/bankapp/servicepackagesample.spring.chapter03.bankapp.service;publicclassPersonalBankingServiceImplextendsServiceTemplateimplementsPersonalBankingService{privatePersonalBankingDaopersonalBankingDao;publicvoidsetPersonalBankingDao(PersonalBankingDaopersonalBankingDao){this.personalBankingDao=personalBankingDao;}@OverridepublicBankStatementgetMiniStatement(){returnpersonalBankingDao.getMiniStatement();}}

In example listing 3-3, we saw that the personalBankingService bean definition specifiespersonalBankingDao as a dependency. In the above example listing, the setPersonalBankingDao settermethod corresponds to the personalBankingDao dependency. Also, notice that thePersonalBankingServiceImplclassisasubclassoftheServiceTemplateclass.

Thefollowingdiagramshowsthataparentbeandefinition(likeserviceTemplate)neednotbeabstract,child bean definitions (like fixedDepositService and personalBankingService) may define additionalproperties, and classes represented by parent (like ServiceTemplate class) and child bean definitions

Page 79: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

(like FixedDepositServiceImpl and PersonalBankingServiceImpl) may themselves be related byinheritance:

Figure3-3–Childbeandefinitionsaddadditionalproperties,parentbeandefinitionisnotabstract,andparent-childrelationshipexistsbetweentheclassesrepresentedbytheparentandchildbeandefinitions

Figure3-3shows:

·SpringcontainercreatesaninstanceofserviceTemplatebeanbecauseit’snotdefinedasabstract

·FixedDepositServiceImplandPersonalBankingServiceImplclasses(correspondingtothechildbean definitions) are subclasses of ServiceTemplate class – the class corresponding to theserviceTemplateparentbeandefinition.

· And, fixedDepositService and personalBankingService bean definitions define additionalproperties,fixedDepositDaoandpersonalBankingDao,respectively.Youshouldnotethatthechildbeandefinitionscanalsodefineadditionalconstructorargumentsandmethodoverrides(discussedinsection4-5).

AsserviceTemplatebeandefinitionisnotabstract,otherbeanscandefineserviceTemplatebeanastheirdependency. For instance, in example listing 3-3, the serviceTemplate bean is a dependency ofuserRequestController bean. You can infer from this discussion that if a parent bean definition is notabstract,thefunctionalityofferedbytheparentbeancanbeutilizednotonlybychildbeansbutalsobyotherbeansintheapplicationcontext.

Beandefinitioninheritanceexample–inheritingfactorymethodconfiguration

Childbeandefinitionscanusebeandefinitioninheritancetoinheritfactorymethodconfigurationfromtheparentbeandefinition.Let’slookatanexamplethatshowsfactorymethodconfigurationsareinheritedbychildbeandefinitions.

Page 80: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

ThefollowingControllerFactoryclassdefinesagetControllerinstancefactorymethod:

Examplelisting3-5–ControllerFactoryclassProject–ch03-bankapp-inheritance-examplesSourcelocation-src/main/java/sample/spring/chapter03/bankapp/controllerpackagesample.spring.chapter03.bankapp.controller;publicclassControllerFactory{publicObjectgetController(StringcontrollerName){Objectcontroller=null;if("fixedDepositController".equalsIgnoreCase(controllerName)){controller=newFixedDepositControllerImpl();}if("personalBankingController".equalsIgnoreCase(controllerName)){controller=newPersonalBankingControllerImpl();}returncontroller;}}

The above example listing shows that the getController factory method creates an instance ofFixedDepositControllerImpl or PersonalBankingControllerImpl class, depending upon the value of thecontrollerNameargumentpassedtoit.IfthevalueofcontrollerNameargumentisfixedDepositController,thegetControllermethodcreates an instanceofFixedDepositControllerImpl class.And, if thevalueofcontrollerNameargumentispersonalBankingController, thegetControllermethodcreatesan instanceofPersonalBankingControllerImplclass.

The followingbeandefinitions in the applicationContext.xml fileof ch03-bankapp-inheritance-exampleproject show that the child bean definitions inherit the getController instance factory methodconfigurationfromtheparentbeandefinition:

Example listing 3-6 – applicationContext.xml - Bean definition inheritance – inheriting the factorymethodconfigurationProject–ch03-bankapp-inheritance-examplesSourcelocation-src/main/resources/META-INF/spring<beanid="controllerFactory"class="sample.spring.chapter03.bankapp.controller.ControllerFactory"/><beanid="controllerTemplate"factory-bean="controllerFactory"factory-method="getController"abstract="true"></bean><beanid="fixedDepositController"parent="controllerTemplate"><constructor-argindex="0"value="fixedDepositController"/>

Page 81: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<propertyname=“fixedDepositService"ref="fixedDepositService"/></bean><beanid="personalBankingController"parent="controllerTemplate"><constructor-argindex="0"value="personalBankingController"/><propertyname="personalBankingService"ref="personalBankingService"/></bean>

In the above example listing, the ControllerFactory class represents a factory class that defines agetController instance factory method. The controllerTemplate bean definition specifies that theControllerFactory’sgetController factorymethod isused forcreatingbean instances.ThegetControllermethod (refer example listing 3-5) creates an instance of FixedDepositControllerImpl orPersonalBankingControllerImplbean,dependingontheargumentpassedtothegetControllermethod.

As the controllerTemplate bean definition has been defined as abstract, it is up to thefixedDepositController and personalBankingController child bean definitions to use the getControllerfactorymethodconfiguration.ThefixedDepositControllerbeandefinitionwouldliketopassanargumentto the ControllerFactory’s getController factory method so that it creates an instance ofFixedDepositControllerImplbean.And,personalBankingControllerbeandefinitionwouldliketopassanargument to the ControllerFactory’s getController factory method so that it creates an instance ofPersonalBankingControllerImpl bean. We saw in section 2-3 of chapter 2 that the <constructor-arg>element is used to pass an argument to an instance factory method. In example listing 3-6, the<constructor-arg>elementhasbeenusedbyfixedDepositControllerandpersonalBankingControllerchildbeandefinitionstopass‘fixedDepositService’and‘personalBankingService’values,respectively,tothegetControllerfactorymethod.

It is recommended that you now run themainmethod of BankApp class of ch03-bankapp-inheritance-examplesprojecttoseeusageofthebeandefinitioninheritanceexamplesdiscussedinthissection.

Let’snowlookathowconstructorargumentsarematched.

Page 82: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-3ConstructorargumentmatchingInthepreviouschapter,wesawthattheconstructorargumentsarespecifiedinthebeandefinitionsusingthe<constructor-arg>element.Inthissection,we’lllookathowSpringcontainermatchesaconstructorargumentspecifiedbya<constructor-arg>elementtothecorrespondingconstructorargumentspecifiedinthebeanclass’sconstructor.

Beforewegointothedetailsofconstructorargumentmatching,let’slookbackathowwepassargumentstoabeanclass’sconstructor.

IMPORT chapter 3/ch03-bankapp-constructor-args-by-type (This project shows the MyBankapplication in which bean class’s constructor arguments are matched by type (explained later in thissection).Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

Passingsimplevaluesandbeanreferencesusing<constructor-arg>elementIf a constructor argument is of simple Java type (like int, String, and so on), the <constructor-arg>element’svalueattributeisusedtospecifythevalueoftheconstructorargument.Ifaconstructorargumentis a reference to a bean, you specify the name of the bean using the <constructor-arg> element’s refattribute.

ThefollowingexamplelistingshowstheUserRequestControllerImplclassofch03-bankapp-constructor-args-by-typeprojectwhoseconstructoracceptsanargumentoftypeServiceTemplate:

Examplelisting3-7–UserRequestControllerImplclassProject–ch03-bankapp-constructor-args-by-typeSourcelocation-src/main/java/sample/spring/chapter03/bankapp/controllerpackagesample.spring.chapter03.bankapp.controller;publicclassUserRequestControllerImplimplementsUserRequestController{privateServiceTemplateserviceTemplate;publicUserRequestControllerImpl(ServiceTemplateserviceTemplate){this.serviceTemplate=serviceTemplate;}@OverridepublicvoidsubmitRequest(Requestrequest){//--dosomethingusingServiceTemplateserviceTemplate.getJmsMessageSender();//--Forex.,sendJMSmessage.....}}

The following example listing shows that a reference to ServiceTemplate instance (represented byserviceTemplatebeandefinition)ispassedtoUserRequestControllerImpl’sconstructorusingrefattributeof<constructor-arg>element:

Page 83: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Example listing 3-8 – applicationContext.xml - Passing reference to a Spring bean as constructorargumentProject–ch03-bankapp-constructor-args-by-typeSourcelocation-src/main/resources/META-INF/spring<beanid="serviceTemplate"class="sample.spring.chapter03.bankapp.base.ServiceTemplate">.....</bean><beanid="userRequestController"class="sample.spring.chapter03.bankapp.controller.UserRequestControllerImpl"><constructor-argindex="0"ref="serviceTemplate"/></bean>

With this background information on how to pass simple values and bean references as constructorarguments,let’snowlookathowSpringcontainermatchesconstructorargumenttypestolocatethebean’sconstructortobeinvoked.

ConstructorargumentmatchingbasedontypeIfthe<constructor-arg>element’sindexattributeisnotspecified,Springcontainerlocatestheconstructortobeinvokedbymatchingthetypesreferencedbythe<constructor-arg>elementswiththeargumenttypesspecifiedinthebeanclass’sconstructor(s).

Let’sfirstlookathowSpringcontainermatchesconstructorargumentswhentheconstructorargumentsareSpringbeansthatarenotrelatedbyinheritance.

ConstructorargumentsrepresentingdistinctSpringbeans

The following example listing shows theServiceTemplate class that defines a constructor that acceptsreferencestoJmsMessageSender,EmailMessageSenderandWebServiceInvokerbeans:

Examplelisting3-9–ServiceTemplateclassProject–ch03-bankapp-constructor-args-by-typeSourcelocation-src/main/java/sample/spring/chapter03/bankapp/basepackagesample.spring.chapter03.bankapp.base;publicclassServiceTemplate{.....publicServiceTemplate(JmsMessageSenderjmsMessageSender,EmailMessageSenderemailMessageSender,WebServiceInvokerwebServiceInvoker){.....}}

The followingexample listing shows thebeandefinitions for theServiceTemplate class and thebeans

Page 84: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

referencedbyServiceTemplate:

Example listing3-10–applicationContext.xml -Beandefinition for theServiceTemplate class and itsdependenciesProject–ch03-bankapp-constructor-args-by-typeSourcelocation-src/main/resources/META-INF/spring<beanid="serviceTemplate"class="sample.spring.chapter03.bankapp.base.ServiceTemplate"><constructor-argref="emailMessageSender"/><constructor-argref="jmsMessageSender"/><constructor-argref="webServiceInvoker"/></bean><beanid="jmsMessageSender"class="sample.spring.chapter03.bankapp.base.JmsMessageSender"/><bean id="emailMessageSender" class="sample.spring.chapter03.bankapp.base.EmailMessageSender"/><beanid="webServiceInvoker"class="sample.spring.chapter03.bankapp.base.WebServiceInvoker"/>

In theaboveexample listing, the<constructor-arg>elementsofserviceTemplatebeandon’t specify theindex attribute. The order in which the constructor arguments are specified by the <constructor-arg>elements is: EmailMessageSender, JmsMessageSender, WebServiceInvoker. The order in whichconstructor arguments are specified in theServiceTemplate class’s constructor is: JmsMessageSender,EmailMessageSender,WebServiceInvoker.Asyoucansee,theorderinwhichconstructorargumentsaredefinedby the<constructor-arg>elements isdifferent fromtheorderspecifiedby theServiceTemplateclass’sconstructor.

If you execute the main method of BankApp class of ch03-bankapp-constructor-args-by-type project,you’ll find that theSpring container successfully creates an instance of ServiceTemplate bean.This isbecauseJmsMessageSender,EmailMessageSenderandWebServiceInvokerclassesaredistinctinnature(thatis,theyarenotrelatedbyinheritance),whichmakesiteasierfortheSpringcontainertoinjecttheirinstancesintotheServiceTemplateclass’sconstructorinthecorrectorder.

If theconstructorargumenttypesarerelatedbyinheritance,Springcontainerneedsextrainstructionstohelp resolve constructor arguments. Let’s now look at how Spring container matches constructorargumentswhenbeansreferencedbytheconstructorargumentsarerelatedbyinheritance.

ConstructorargumentsrepresentingrelatedSpringbeans

ConsiderthefollowingSampleBeanbeanclasswhoseconstructoracceptsargumenttypesthatarerelatedbyinheritance:

Examplelisting3-11–SampleBeanclass

publicclassSampleBean{publicSampleBean(ABeanaBean,BBeanbBean){.....}.....}

The above example listing shows that the SampleBean class’s constructor accepts ABean and BBean

Page 85: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

typesasarguments.ABeanandBBeanrepresentSpringbeansthatarerelatedbyinheritance;BBeanisasubclassofABean.

The following application context XML file shows the bean definitions for SampleBean, ABean andBBeanclasses:

Examplelisting3-12–BeandefinitionsforSampleBean,ABeanandBBeanclasses

<beanid="aBean"class="example.ABean"/><beanid="bBean"class="example.BBean"/><beanid="sampleBean"class="example.SampleBean"><constructor-argref="bBean"/><constructor-argref="aBean"/></bean>

AsaBeanandbBeanbeansarerelatedbyinheritance,Springcontainerappliesconstructorargumentstothe SampleBean’s constructor in the order in which <constructor-arg> elements appear in the beandefinitionfortheSampleBeanclass.IntheabovesampleBeanbeandefinition,thefirst<constructor-arg>elementreferstobBeanbeanandthesecond<constructor-arg>elementreferstoaBeanbean.Thismeansthat bBean is passed as the first constructor argument and aBean is passed as the second constructorargument to theSampleBeanconstructor.As instanceofABean (thesuperclass)can’tbepassedwhereBBean(thesubclass)instanceisexpected,thesecond<constructor-arg>elementinthesampleBeanbeandefinitionresults inexceptionbeing thrownby theSpringcontainer.Tohandlesuchscenarios,youcanuse <constructor-arg> element’s index or type attribute to identify the constructor argument to which<constructor-arg>elementapplies.Forinstance,thefollowingsampleBeanbeandefinitionmakesuseoftype attribute to indicate the type of the constructor argument to which the <constructor-arg> elementapplies:

Example listing3-13–<constructor-arg>element’s type attribute identifies the typeof the constructorargument

<beanid="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’stypeattributespecifiesthefully-qualifiednameofthetypetowhichthe<constructor-arg>elementapplies.Intheaboveexamplelisting,thefirst<constructor-arg>appliestotheconstructorargumentoftypeBBean,andthesecond<constructor-arg>elementappliestotheconstructorargument of type ABean. Specifying the type attribute takes away the ambiguity that arises whenconstructorargumentsarerelatedbyinheritance.

NOTEIftwoormoreconstructorargumentsareofthesametype,theonlyoptionistouseindexattributetoidentifytheconstructorargumenttowhicheach<constructor-arg>elementapplies.

Page 86: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Sofarwehave lookedatconstructorargument typematchingscenarios inwhichconstructorargumentsrepresented distinct or related Spring beans. We’ll now look at how constructor argument types arematchedforstandardJavatypes(likeint,long,boolean,String,Date,andsoon)andcustomtypes.

ConstructorargumentsrepresentingstandardJavatypesandcustomtypes

Ifthetypeofaconstructorargumentisaprimitivetype(likeint,long,boolean,andsoon)oraStringtypeor a custom type (likeAddress), the<constructor-arg> element’s value attribute is used to specify thevalue. If there are 2 ormore constructor arguments intowhich the string value specified by the valueattributecanbeconverted,it’llnotbepossiblefortheSpringcontainertoderivethetype(forexample,whetherthevaluerepresentsanintorlongorString)oftheconstructorargument.Insuchscenarios,youneedtoexplicitlyspecifythetypeoftheconstructorargumentusingthetypeattribute.

ThefollowingexamplelistingshowstheTransferFundsServiceImplclassthatdefinesaconstructorwhichacceptsargumentsoftypesString,boolean,longandint:

Examplelisting3-14–TransferFundsServiceImplclassProject–ch03-bankapp-constructor-args-by-typeSourcelocation-src/main/java/sample/spring/chapter03/bankapp/servicepackagesample.spring.chapter03.bankapp.service;publicclassTransferFundsServiceImplimplementsTransferFundsService{publicTransferFundsServiceImpl(StringwebServiceUrl,booleanactive,longtimeout,intnumberOfRetrialAttempts){.....}.....}

As the above example listing shows, TransferFundsServiceImpl constructor accepts the followingarguments:webServiceUrl,active,timeoutandnumberOfRetrialAttempts.Thefollowingbeandefinitionfor the TransferFundsServiceImpl class shows how constructor argument values can be passed to theTransferFundsServiceImpl’sconstructor:

Examplelisting3-15–BeandefinitionfortheTransferFundsServiceImplclass<beanid="transferFundsService"class="sample.spring.chapter03.bankapp.service.TransferFundsServiceImpl"><constructor-argvalue="http://someUrl.com/xyz"/><constructor-argvalue="true"/><constructor-argvalue="5"/><constructor-argvalue="200"/></bean>

Let’sassumethatthe3rd<constructor-arg>element(valueattribute’svalueis‘5’)issupposedtosupplyvalueforthenumberOfRetrialAttemptsconstructorargument,andthe4th<constructor-arg>element(valueattribute’s value is ‘200’) is supposed to supply value for the timeout constructor argument. Spring

Page 87: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

containerapplies<constructor-arg>elementstotheTransferFundsServiceImpl’sconstructorintheorderinwhich<constructor-arg>elementsappearinthetransferFundsServicebeandefinition.Thismeansthatthe 3rd <constructor-arg> element applies to timeout argument, and the 4th <constructor-arg> elementappliestonumberOfRetrialAttemptsargument.Tohandlesuchambiguities,youcanspecifythetypeofaconstructorargumentvia<constructor-arg>element’s typeattribute,asshownin thefollowingexamplelisting:

Examplelisting3-16–applicationContext.xml-<constructor-arg>element’stypeattributeProject–ch03-bankapp-constructor-args-by-typeSourcelocation-src/main/resources/META-INF/spring<beanid="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>

IntheabovebeandefinitionfortheTransferFundsServiceImplclass,typeattributeisusedtospecifytheconstructor argument type. Spring container can now use typematching to correctly apply constructorarguments.

NOTEIftwoormoreconstructorargumentsareofthesametype,theonlyoptionistouseindexattributeforidentifyingtheconstructorargumenttowhicheach<constructor-arg>elementapplies.

Inthissection,wesawhowtypematchingisperformedbySpringtoresolveconstructorarguments.Let’snowlookathowyoucaninstructSpringtoperformconstructorargumentmatchingbasedonconstructorargument’sname.

IMPORT chapter 3/ch03-bankapp-constructor-args-by-name (This project shows the MyBankapplication inwhichbean class’s constructor arguments arematchedbyname.To run the application,executethemainmethodoftheBankAppclassofthisproject)

ConstructorargumentmatchingbasedonnameThe <constructor-arg> element’s name attribute is used for specifying the name of the constructorargument to which the <constructor-arg> element applies. The following example listing shows onceagaintheTransferFundsServiceImplclasswhoseconstructoracceptsmultiplearguments:

Examplelisting3-17–TransferFundsServiceImplclassProject–ch03-bankapp-constructor-args-by-nameSourcelocation-src/main/java/sample/spring/chapter03/bankapp/servicepackagesample.spring.chapter03.bankapp.service;publicclassTransferFundsServiceImplimplementsTransferFundsService{.....

Page 88: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicTransferFundsServiceImpl(StringwebServiceUrl,booleanactive,longtimeout,intnumberOfRetrialAttempts){.....}}The above example listing shows that the names of the constructor arguments defined byTransferFundsServiceImpl’s constructor are: webServiceUrl, active, timeout andnumberOfRetrialAttempts.

NOTETheTransferFundsServiceImplclass’sconstructoracceptsargumentsthataresimpleJavatypes(like,int,long,boolean,String,andsoon),buttheconceptexplainedinthissectionalsoappliestoscenariosinwhichconstructorargumentsarereferencestoSpringbeans.Thefollowingbeandefinitionfor theTransferFundsServiceImplclassuses<constructor-arg>element’sname attribute to specify the nameof the constructor argument towhich the<constructor-arg> elementapplies:

Examplelisting3-18–applicationContext.xml-<constructor-arg>element’snameattributeProject–ch03-bankapp-constructor-args-by-nameSourcelocation-src/main/resources/META-INF/spring<beanid="transferFundsService"class="sample.spring.chapter03.bankapp.service.TransferFundsServiceImpl"><constructor-argname="webServiceUrl"value="http://someUrl.com/xyz"/><constructor-argname="active"value="true"/><constructor-argname="numberOfRetrialAttempts"value="5"/><constructor-argname="timeout"value="200"/></bean>TheaboveconfigurationwillworkonlyifTransferFundsServiceImplclassiscompiledwithdebug flagenabled(referto-goptionofjavac).Whenthedebugflagisenabled,namesofconstructorargumentsarepreserved in the generated .class file. If you don’t compile your classeswith debug flag enabled, theconstructorargumentnamesarelostduringcompilation,andSpringhasnowaytolocatetheconstructorargument corresponding to the constructor argumentname specifiedby the<constructor-arg> element’snameattribute.

Ifyoudon’twanttocompileyourclassesusingdebugflagenabled,youcanuse@ConstructorPropertiesannotation(introduced inJavaSE6) toclearlyspelloutnamesof theconstructorarguments,asshownhereforTransferFundsServiceImplclass:

Examplelisting3-19–@ConstructorPropertiesannotationProject–ch03-bankapp-constructor-args-by-nameSourcelocation-src/main/java/sample/spring/chapter03/bankapp/servicepackagesample.spring.chapter03.bankapp.service;

Page 89: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importjava.beans.ConstructorProperties;publicclassTransferFundsServiceImplimplementsTransferFundsService{@ConstructorProperties({"webServiceUrl","active","timeout","numberOfRetrialAttempts"})publicTransferFundsServiceImpl(StringwebServiceUrl,booleanactive,longtimeout,intnumberOfRetrialAttempts){.....}}

In the above example listing, @ConstructorProperties annotation specifies the names of constructorargumentsintheorderinwhichtheyappearinthebeanclass’sconstructor.Youmustensurethatyouusethesameconstructorargumentnamesinthe<constructor-arg>elements.

Let’snowlookathowthe@ConstructorPropertiesannotationaffectsbeandefinitioninheritance.

@ConstructorPropertiesannotationandbeandefinitioninheritance

If the constructor of the class corresponding to the parent bean definition is annotated with@ConstructorPropertiesannotation, thebeanclasscorrespondingtothechildbeandefinitionmustalsobeannotatedwith@ConstructorPropertiesannotation.

The following example listing shows the serviceTemplate (parent bean definition) andFixedDepositService(childbeandefinition)beandefinitions:

Examplelisting3-20–applicationContext.xml-ParentandchildbeandefinitionsProject–ch03-bankapp-constructor-args-by-nameSourcelocation-src/main/resources/META-INF/spring

<beanid="serviceTemplate"class="sample.spring.chapter03.bankapp.base.ServiceTemplate"><constructor-argname="emailMessageSender"ref="emailMessageSender"/><constructor-argname="jmsMessageSender"ref="jmsMessageSender"/><constructor-argname="webServiceInvoker"ref="webServiceInvoker"/></bean><beanid="FixedDepositService"class="sample.spring.chapter03.bankapp.service.FixedDepositServiceImpl"parent="serviceTemplate"><propertyname=“fixedDepositDao"ref="FixedDepositDao"/></bean>

TheaboveexamplelistingshowsthattheserviceTemplatebeandefinitionisnotabstract,whichmeansthat the Spring container will create an instance of serviceTemplate bean. The serviceTemplate beandefinition specifies 3 <constructor-arg> elements, corresponding to the 3 arguments defined by theServiceTemplateclass(referexamplelisting3-21).Aswehavespecifiedconstructorargumentsbynamein the serviceTemplate bean definition, the ServiceTemplate class’s constructor is annotated with the@ConstructorPropertiesannotationtoensurethatconstructorargumentnamesareavailabletoSpringatruntime,asshownhere:

Page 90: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting3-21–ServiceTemplateclassProject–ch03-bankapp-constructor-args-by-nameSourcelocation-src/main/java/sample/spring/chapter03/bankapp/basepackagesample.spring.chapter03.bankapp.base;importjava.beans.ConstructorProperties;publicclassServiceTemplate{.....@ConstructorProperties({"jmsMessageSender","emailMessageSender","webServiceInvoker"})publicServiceTemplate(JmsMessageSenderjmsMessageSender,EmailMessageSenderemailMessageSender,WebServiceInvokerwebServiceInvoker){.....}}

As FixedDepositService is a child bean definition of serviceTemplate, the <constructor-arg>configurationinserviceTemplatebeandefinitionisinheritedbytheFixedDepositServicebeandefinition.ThismeansthattheFixedDepositServiceImplclassmustdefineaconstructorthatacceptsthesamesetofarguments as defined by the ServiceTemplate class, and it must also be annotated with@ConstructorProperties annotation. If you don’t annotate FixedDepositServiceImpl’s constructor with@ConstructorPropertiesannotation,Springcontainerwillnotbeabletomatchtheinherited<constructor-arg>elementswiththeconstructorargumentsspecifiedintheFixedDepositServiceImpl’sconstructor.

Youcan’tuse@ConstructorPropertiesannotationforpassingargumentsbynametoastaticor instancefactorymethod,asexplainednext.

@ConstructorPropertiesannotationandfactorymethods

We saw in section 2-3 of chapter 2 that the <constructor-arg> elements are also used for passingargumentstostaticandinstancefactorymethods.Youmightthinkthatyoucanpassargumentsbynametostatic and instance factory methods by specifying the <constructor-arg> element’s name attribute andannotating 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 youwant topass argumentsbyname to a static or instancefactorymethod,theonlyoptionyouhaveistocompileclasseswithdebugflagenabled.

NOTEIfyoucompileclasseswithdebugflagenabled,itresultsin.classfilesthatarelargerinsize,buthasnoimpactontheruntimeperformanceoftheapplication.Itonlyresultsinincreasedloadingtimefortheclasses.

Let’snowlookathowtoenableordisabledebugflaginEclipseIDE.

Enabling(ordisabling)thedebugflaginEclipseIDE

InEclipseIDE,followthesestepstoenablethedebugflagforprojects:

Page 91: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1.GotoWindowsàPreferencesandselecttheoptionJavaàCompiler

2.You’llnowseeasectiontitled‘ClassfileGeneration’.Inthissection,ifyoucheckthecheckboxlabeled‘Addvariableattributestogeneratedclassfiles(usedbythedebugger)’,thedebugflagisenabled.Uncheckingthischeckboxwilldisablethedebugflag.

Sofarwehavemostlyseenbeandefinitionexamplesinwhichbeanpropertiesandconstructorargumentswerereferencestootherbeans.We’llnowlookatbeandefinitionexamplesinwhichbeanpropertiesandconstructorargumentsareofprimitivetype,collectiontype,java.util.Date,java.util.Properties,andsoon.

Page 92: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-4 Configuring different types of bean properties and constructorargumentsInrealworldapplicationdevelopmentscenarios,propertiesandconstructorargumentsofaSpringbeancould range from a String type to reference to another bean to any other standard (like java.util.Date,java.util.Map)orcustom(likeAddress)type.SofarwehaveseenexamplesofhowtosupplyvalueforString type bean properties (using value attribute of <property> element) and String type constructorarguments (using value attribute of <constructor-arg> element). We also looked at how to injectdependenciesviabeanproperties(usingrefattributeof<property>element)andconstructorarguments(usingrefattributeof<constructor-arg>elements).

Inthissection,we’lllookatbuilt-inPropertyEditorimplementationsinSpringthatsimplifypassingbeanproperties and constructor arguments of types java.util.Date, java.util.Currency, primitive type, and soon.We’llalsolookathowtospecifyvaluesforcollectiontypes(likejava.util.Listandjava.util.Map)inthe application context XML file, and how to register a custom PropertyEditor implementation withSpring.

Let’s now look at bean definition examples that demonstrate use of built-in PropertyEditorimplementations.

IMPORT chapter 3/ch03-simple-types-examples (This project shows a Spring application inwhichbean 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 PropertyEditorimplementationwithSpringcontainer.Toruntheapplication,executethemainmethodoftheSampleAppclassofthisproject)

Built-inpropertyeditorsinSpringJavaBeansPropertyEditorsprovidethenecessarylogicforconvertingaJavatypetoastringvalue,andviceversa.Springprovidesacoupleofbuilt-inPropertyEditorsthatareusedforconvertingstringvalueof a bean property or a constructor argument (specified via value attribute of <property> and<constructor-arg>elements)totheactualJavatypeofthepropertyorconstructorargument.

Beforewe lookatexamples involvingbuilt-inPropertyEditors, let’s firstunderstand the importanceofPropertyEditorsinsettingvaluesofbeanpropertiesorconstructorarguments.

ConsiderthefollowingBankDetailsclassthatwewanttoconfigureasasingleton-scopedbeanwithpre-definedvaluesforitsattributes:

Examplelisting3-22–BankDetailsclasspublicclassBankDetails{privateStringbankName;publicvoidsetBankName(StringbankName){this.bankName=bankName;}}

Page 93: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Intheaboveexamplelisting,bankNameisanattributeoftheBankDetailsclass,andisoftypeString.ThefollowingbeandefinitionfortheBankDetailsclassshowshowtosetthevalueofbankNameattribute to‘MyPersonalBank’:

Examplelisting3-23–BeandefinitionfortheBankDetailsclass<beanid="bankDetails"class="BankDetails"><propertyname="bankName"value="MyPersonalBank"/></bean>

In the above bean definition, the <property> element’s value attribute specifies a string value for thebankNameproperty.Asyoucansee,ifabeanpropertyisoftypeString,youcansimplysetthatpropertyvalueusing<property>element’svalue attribute.Similarly, if a constructor argument isof typeString,youcansettheconstructorargumentvalueusing<constructor-arg>element’svalueattribute.

Let’ssaythatthefollowingattributes(alongwiththeirsettermethods)areaddedtotheBankDetailsclass:a bankPrimaryBusiness attribute of type byte[], a headOfficeAddress attribute of type char[], aprivateBank attribute of type char, a primaryCurrency attribute of type java.util.Currency, adateOfInception attribute of type java.util.Date, and a branchAddresses attribute of typejava.util.Properties.ThefollowingexamplelistingshowsthemodifiedBankDetailsclass:

Examplelisting3-24–BankDetailsclasscontainingdifferenttypesofpropertiesProject–ch03-simple-types-examplesSourcelocation-src/main/java/sample/spring/chapter03/beanspackagesample.spring.chapter03.beans;.....publicclassBankDetails{privateStringbankName;privatebyte[]bankPrimaryBusiness;privatechar[]headOfficeAddress;privatecharprivateBank;privateCurrencyprimaryCurrency;privateDatedateOfInception;privatePropertiesbranchAddresses;.....publicvoidsetBankName(StringbankName){this.bankName=bankName;}//--moresettermethods}

YoucanconfiguretheBankDetailsclassasaSpringbeanbyspecifyingstringvaluesfortheproperties,and letting the Spring container convert these string values into the corresponding Java types of thepropertiesbyusingregisteredJavaBeansPropertyEditorimplementations.

ThefollowingbeandefinitionfortheBankDetailsclassshowsthatsimplestringvaluesarespecifiedfordifferentpropertytypes:

Page 94: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting3-25–applicationContext.xml-BeandefinitionfortheBankDetailsclassProject–ch03-simple-types-examplesSourcelocation-src/main/resources/META-INF/spring

<beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails"><propertyname="bankName"value="MyPersonalBank"/><propertyname="bankPrimaryBusiness"value="Retailbanking"/><propertyname="headOfficeAddress"value="Addressofheadoffice"/><propertyname="privateBank"value="Y"/><propertyname="primaryCurrency"value="INR"/><propertyname="dateOfInception"value="30-01-2012"></property><propertyname="branchAddresses"><value>x=BranchX'saddressy=BranchY'saddress</value></property></bean>

Theaboveexample listingshows that stringvaluesarespecified forpropertiesof types java.util.Date,java.util.Currency, char[], byte[], char and java.util.Properties. Spring container uses registeredPropertyEditors for converting the string value of the property or constructor argument to thecorrespondingJavatypeofthepropertyorconstructorargument.Forinstance,Springcontainerconvertsthe value ‘30-01-2012’ of dateOfInception property to java.util.Date type using CustomDateEditor (abuilt-inPropertyEditorimplementationforjava.util.Datetype).

If you look at how branchAddresses property (of type java.util.Properties) is configured in examplelisting3-25, you’ll notice that insteadof<property> element’s value attribute,<value> sub-element of<property> element has been used to specify the value for the property. In case of single-valuedproperties,theuseof<property>element’svalueattributeispreferredover<value>sub-element.But,ifyouneedtospecifymultiplevaluesforapropertyorthevaluesneedtobespecifiedonseparatelines(asinthecaseofbranchAddressesproperty), the<value>sub-element ispreferredovervalueattribute. Inthe next section, you’ll see that values for properties (or constructor arguments) of typejava.util.Properties can also be specified using <props> sub-element of <property> ( or <constructor-arg>)element.

Springcomeswithcoupleofbuilt-inPropertyEditorimplementationsthatperformthetaskofconvertingvaluesspecifiedintheapplicationcontextXMLfiletotheJavatypeofthebeanpropertyorconstructorargument.Thefollowingtabledescribessomeofthebuilt-inPropertyEditorimplementationsinSpring:

Built-in PropertyEditorimplementation Description

CustomBooleanEditor convertsstringvaluetoBooleanorbooleantype

CustomNumberEditor convertsstringvaluetoanumber(likeint,long,andsoon)

ChracterEditor convertsstringvaluetochartype

ByteArrayPropertyEditor convertsstringvaluetobyte[]

CustomDateEditor convertsstringvaluetojava.util.Datetype

PropertiesEditor convertsstringvaluetojava.util.Propertiestype

Page 95: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Theabovetableshowsonlyasubsetofbuilt-inPropertyEditorimplementationsinSpring.Foracompletelist,refertotheorg.springframework.beans.propertyeditorspackageofSpring.Itisimportanttonotethatnot all built-in PropertyEditor implementations in Spring are registered with the Spring container bydefault. For instance, you need to explicitly register CustomDateEditor to allow Spring container toperformconversionfromastringvaluetoajava.util.Datetype.Laterinthissection,we’lllookathowyoucanregisterpropertyeditorswithSpringcontainer.

Let’s now look at how to specify values for bean properties (or constructor arguments) of typesjava.util.List,java.util.Setandjava.util.Map.

SpecifyingvaluesfordifferentcollectiontypesThe <list>, <map> and <set> sub-elements (defined in Spring’s beans schema) of <property> and<constructor-arg> elements are used to set properties and constructor arguments of type java.util.List,java.util.Mapandjava.util.Set,respectively.

NOTESpring’sutilschemaalsoprovides<list>,<set>and<map>elementsthatsimplifysettingpropertiesandconstructorargumentsofdifferentcollectiontypes.Laterinthischapter,we’lllookatSpring’sutilschemaelementsindetail.

ThefollowingDataTypesExampleclassshowsthatitsconstructoracceptsargumentsofdifferenttypes:

Examplelisting3-26–DataTypesExampleclassProject–ch03-simple-types-examplesSourcelocation-src/main/java/sample/spring/chapter03/beanspackagesample.spring.chapter03.beans;importjava.beans.ConstructorProperties;.....publicclassDataTypesExample{privatestaticLoggerlogger=Logger.getLogger(DataTypesExample.class);@SuppressWarnings("rawtypes")@ConstructorProperties({"byteArrayType","charType","charArray","classType","currencyType","booleanType","dateType","longType","doubleType","propertiesType","listType","mapType","setType","anotherPropertiesType"})publicDataTypesExample(byte[]byteArrayType,charcharType,char[]charArray,ClassclassType,CurrencycurrencyType,booleanbooleanType,DatedateType,longlongType,doubledoubleType,PropertiespropertiesType,List<Integer>listType,MapmapType,SetsetType,PropertiesanotherPropertiesType){.....logger.info("classType"+classType.getName());logger.info("listType"+listType);

Page 96: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

logger.info("mapType"+mapType);logger.info("setType"+setType);logger.info("anotherPropertiesType"+anotherPropertiesType);}}

The above example listing shows that theDataTypesExample class’s constructor accepts arguments oftypesjava.util.List,java.util.Map,java.util.Setandjava.util.Properties,andsoon,andlogs thevalueofeachconstructorargument.

ThefollowingexamplelistingshowsthebeandefinitionfortheDataTypesExampleclass:

Examplelisting3-27–applicationContext.xml-BeandefinitionforDataTypesExampleclassProject–ch03-simple-types-examplesSourcelocation-src/main/resources/META-INF/spring

<beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="anotherPropertiesType"><props><propkey="book">GettingstartedwiththeSpringFramework</prop></props></constructor-arg><constructor-argname="listType"value-type="java.lang.Integer"><list><value>1</value><value>2</value></list></constructor-arg><constructor-argname="mapType"><map><entry><key><value>mapkey1</value></key><value>mapkey1’svalue</value></entry></map></constructor-arg><constructor-argname="setType"><set><value>Element1</value><value>Element2</value></set></constructor-arg></bean>

Page 97: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Theaboveexamplelistingshows:

· the value of anotherPropertiesType (of type java.util.Properties) is specified using the<props>sub-elementof<constructor-arg>element.Each<prop>elementspecifiesakey-valuepair;thekeyattributespecifiesthekeyvalueandthecontentof<prop>elementisthevalueforthekey.Insteadofusing<props>element,youcanuse<value>sub-elementof<constructor-arg>elementtospecifythevalueforanotherPropertiesTypeargument.

·thevalueoflistTypeconstructorargument(oftypejava.util.List)isspecifiedusingthe<list>sub-element of <constructor-arg>. The <value> sub-elements of <list> element specify itemscontained in the list. The <list> element’s value-type attribute specifies the Java type of theelements that the java.util.List type constructor argument accepts. As the listType constructorargumentisoftypeList<Integer>(referexamplelisting3-26),thevalue-typeattribute’svalueisspecifiedasjava.lang.Integer.Thevalue-typeattributeisoptional,andisparticularlyuseful ifyou are using a parameterized List type, like List<Integer>. If you specify the value-typeattribute,Springcontainerusestheregisteredpropertyeditorstoperformconversionofvaluestothetypespecifiedbythevalue-typeattribute,followedbyconverting(ifrequired)thevaluestothetypeacceptedbytheparameterizedListtype.Ifyoudon’tspecifythevalue-typeattribute,SpringcontainersimplyusestheregisteredpropertyeditorstoperformconversionofvaluestothetypeacceptedbytheparameterizedListtype.

· thevalueofmapTypeconstructorargument (of type java.util.Map) is specifiedusing the<map>sub-elementof<constructor-arg>.The<entry> sub-elementof<map> specifies a key-valuepaircontainedintheMap;the<key>elementspecifies thekeyand the<value>elementspecifiesthevalueforthekey.Thekey-typeandvalue-typeattributesof<map>elementspecifythe Java type of keys and values that java.util.Map accepts. The key-type and value-typeattributes are optional, and especially useful if you are using parameterized Map type, likeMap<Integer,Integer>.Springcontainerusesregisteredpropertyeditorstoperformconversionofkeysandvalues to the types specifiedby thekey-type andvalue-type attributes, and to thetypesacceptedbytheparameterizedMaptype.

· thevalueofthesetTypeconstructorargument(oftypejava.util.Set) isspecifiedusing the<set> sub-element of <constructor-arg>. Each <value> sub-element of <set> specifies anelementcontainedintheSet.Thevalue-typeattributeof<set>elementspecifiestheJavatypeofelementsthatjava.util.Setaccepts.Thevalue-typeattributeisoptional,andisusefulifyouareusing parameterized Set type, like Set<Integer>. Spring container uses registered propertyeditorstoperformconversionofvaluestothetypespecifiedbythevalue-typeattribute,andtothetypeacceptedbytheparameterizedSettype.

InDataTypesExample class (refer example listing 3-26 and 3-27), constructor arguments of type List,Map andSet contained elements of type String or Integer. In an application, a collectionmay containelements of typeMap, Set, Class, Properties, or any other Java type. The elements contained in thecollectioncanalsobebeanreferences.Toaddresssuchscenarios,Springallowsyoutouseelementslike<map>,<set>,<list>,<props>,<ref>,andsoon,assub-elementsof<list>,<map>and<set>elements.Let’snowlookatexamplesthatdemonstratehowtoadddifferenttypesofelementstoMap,ListandSettypeconstructorargumentsandbeanproperties.

Page 98: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

AddingelementsoftypeList,Map,SetandPropertiestocollectiontypes

Ifabeanpropertyorconstructorargumentisof typeList<List>,simplyuseanested<list>element,asshownhere:

Examplelisting3-28–Configurationexample:ListinsideaList<constructor-argname="nestedList"><list><list><value>AsimpleStringvalueinthenestedlist</value><value>AnothersimpleStringvalueinnestedlist</value></list></list></constructor-arg>

The <constructor-arg> element shown in the above example listing supplies value for a constructorargumentnamednestedListwhichisoftypeList<List>.Thenested<list>elementrepresentsanelementof typeList.Similarly,youcanuse<map>,<set>and<props>elements insidea<list> element to setvalue of properties or constructor arguments of type List<Map>, List<Set> and List<Properties>,respectively.Aswiththe<list>element,a<set>elementcancontain<set>,<list>,<map>or<props>element.Incaseofa<map>element,youcanuse<map>,<set>,<list>or<props>elementtospecifykeyandvalueofanentry.

ThefollowingexamplelistingshowshowyoucanspecifyvaluesforaMap<List,Set> typeconstructorargument:

Examplelisting3-29–Configurationexample:MapcontainingListtypeaskeyandSettypeasvalue<constructor-argname="nestedListAndSetMap"><map><entry><key><list><value>aListelement</value></list></key><set><value>aSetelement</value></set></entry></map></constructor-arg>

The above example listing shows that the nestedListAndSetMap constructor argument is ofMap typewhosekeyisof typeListandvalueisoftypeSet.The<key>elementcanhaveeitherof thefollowingelements as its sub-element:<map>,<set>,<list> and<props>. The value for the key can be defined

Page 99: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

using<map>,<set>,<list>or<props>element.

Addingbeanreferencestocollectiontypes

Youcanuse<ref>elementsinside<list>and<set>elementstoaddreferencestobeansintopropertiesandconstructorargumentsoftypeListandSet,respectively.

The following example listing shows how references to beans are added to a List type constructorargument:

Examplelisting3-30–Configurationexample:Listcontainingreferencetobeans

<bean.....><constructor-argname="myList"><list><refbean="aBean"/><refbean="bBean"/></list></constructor-arg></bean><beanid="aBean"class="somepackage.ABean"/><beanid="bBean"class="somepackage.BBean"/>

Theaboveexample listingshows that themyListconstructorargument isof typeListand it contains 2elements-areferencetoaBeanbeanandareferencetobBeanbean.The<ref>element’sbeanattributespecifiesthenameofthebeanreferencedbythe<ref>element.

Aswiththe<list>element,youcanuse<ref>elementsinside<set>elementtoaddbeanreferencestoaSet type constructor argument or beanproperty. In caseof<map> element, you can use<ref> elementinsidea<key>elementtospecifyabeanreferenceasakey,andusethe<ref>elementtospecifyabeanreferenceasavalueforthekey.ThefollowingexamplelistingshowsaMap typeconstructorargumentthatcontainsasinglekey-valuepairinwhichbothkeyandvaluearereferencestobeans:

Examplelisting3-31–Configurationexample:Mapcontainingbeanreferencesaskeysandvalues

<bean.....><constructor-argname="myMapWithBeanRef"><map><entry><key><refbean="aBean"/></key><refbean="bBean"/></entry></map></constructor-arg></bean>

Page 100: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="aBean"class="somepackage.ABean"/><beanid="bBean"class="somepackage.BBean"/>

Theaboveexample listing shows thatmyMapWithBeanRef constructor argument is of typeMap and itcontains a key-valuepair inwhich thekey is a reference to aBeanbean and correspondingvalue is areferencetobBeanbean.

Addingbeannamestocollectiontypes

Ifyouwanttoaddabeanname(asspecifiedbytheidattributeof<bean>element)toaList,MaporSettype constructor argument or bean property, you can use the<idref>element inside<map>, <set> and<list> elements.The followingexample listing showsaMap type constructor argument that contains asinglekey-valuepair,wherebeannameisthekeyandbeanreferenceisthevalue:

Examplelisting3-32–Configurationexample:Mapcontainingbeannameaskeyandbeanreferenceasvalue

<constructor-argname="myExample"><map><entry><key><idrefbean="sampleBean"/></key><refbean="sampleBean"/></entry></map></constructor-arg><beanid="sampleBean"class="somepackage.SampleBean"/>

TheaboveexamplelistingshowsthatthemyExampleconstructorargumentisoftypeMapwhosekeyisthestringvalue‘sampleBean’andvalueisthesampleBeanbean.Wecouldhaveused<value>elementtoset‘sampleBean’stringvalueasthekey,but<idref>element isusedbecauseSpringcontainerverifiesexistenceofthesampleBeanbeanwhentheapplicationisdeployed.

NOTEYoucanusethe<idref>elementinsidea<property>or<constructor-arg>elementtosetabeannameasthevalueofabeanpropertyorconstructorargument.

Addingnullvaluestocollectiontypes

YoucanaddanullvaluetocollectionsoftypeSetandListusing<null>element.ThefollowingexamplelistingshowshowtoaddanullvaluetoaSettypeconstructorargumentusing<null>element:

Examplelisting3-33–Configurationexample:Setcontaininganullelement

<constructor-argname="setWithNullElement"><set><value>Element1</value><value>Element2</value>

Page 101: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<null/></set></constructor-arg>

In theaboveexample listing,setWithNullElementconstructorargumentcontains3elements:Element1,Element2andnull.

ToaddanullkeytoaMaptypeconstructorargumentorproperty,youcanuse<null>elementinsidethe<key>element.And,toaddanullvalue,youcanadda<null>elementinsidethe<entry>element.Thefollowing example listing shows aMap type constructor argument that contains a null key and a nullvalue:

Examplelisting3-34–Configurationexample:Mapcontaininganullkeyandanullvalue

<constructor-argname="mapType"><map><entry><key><null/></key><null/></entry></map></constructor-arg>

Theaboveexamplelistingshowsthatanelementwithnullkeyandnullvalueisaddedto themapTypeconstructorargumentusing<null>element.

NOTEYoucanalsouse<null>elementinside<property>and<constructor-arg>elementstosetnullvaluesforpropertiesandconstructorarguments,respectively.

Let’snowlookathowtospecifyvaluesforarraytypepropertiesandconstructorarguments.

SpecifyingvaluesforarraysIf 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-elementof<constructor-arg>element.

Thefollowingexamplelistingshowshowyoucansetabeanpropertyoftypeint[]:

Examplelisting3-35–Configurationexample:Settingvalueofabeanpropertyoftypeint[]

<propertyname="numbersProperty"><array><value>1</value><value>2</value></array></property>

Intheaboveexamplelisting,each<value>sub-elementofthe<array>elementrepresentsanelementin

Page 102: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

thenumbersPropertyarray.ThepropertyeditorsregisteredwiththeSpringcontainerareusedtoconvertthestringvaluespecifiedbyeachofthe<value>elementtointtype.Youcanuse<array>elementinside<list>,<set>and<map>elements.Youcanalsouse<list>,<set>,<map>,<props>and<ref>elementsinsidean<array>elementtocreatearraysofList,Set,Map,Propertiesandbeanreferences,respectively.Ifyouwanttocreateanarrayofarrays,youcanuse<array>elementsinsidean<array>element.

Wediscussedthat<list>,<map>and<set>elementsareusedtosetpropertiesorconstructorargumentsof typeList,MapandSet, respectively.Let’snow lookat thedefault collection implementation that iscreatedbySpringforeachoftheseelements.

Defaultcollectionimplementationfor<list>,<set>and<map>elementsThe following table shows the default collection implementation that is created by Spring for <list>,<set>and<map>elements:

Collectionelement DefaultcollectionimplementationcreatedbySpring

<list> java.util.ArrayList

<set> java.util.LinkedHashSet

<map> java.util.LinkedHashMap

Theabovetablesuggests:

· ifaproperty’s (oraconstructorargument’s)value is specifiedusing<list> element,SpringcreatesaninstanceofArrayListandassignsittotheproperty(ortheconstructorargument).

· if aproperty’s (ora constructorargument’s)value is specifiedusing<set> element,SpringcreatesaninstanceofLinkedHashSetandassignsittotheproperty(ortheconstructorargument).

· ifaproperty’s(oraconstructorargument’s)valueisspecifiedusing<map>element,SpringcreatesaninstanceofLinkedHashMapandassignsittotheproperty(ortheconstructorargument).

It is likely that you may want to substitute a different implementation of List, Set orMap to a beanpropertyoraconstructorargument.Forinstance,insteadofjava.util.ArrayList,youmaywanttoassignaninstanceofjava.util.LinkedList toabeanpropertyof typeList. Insuchscenarios, it is recommended touse <list>, <map> and <set> elements of Spring’s util schema (explained in section 3-8). The <list>,<set>and<map>elementsofSpring’sutilschemaprovidetheoptiontospecifythefully-qualifiednameoftheconcretecollectionclassthatyouwanttoassigntothepropertyorconstructorargumentofthebean.

Let’snowlookatsomeofthebuilt-inpropertyeditorsprovidedbySpring.

Page 103: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-5Built-inpropertyeditorsSpring provides a couple of built-in property editors that are usefulwhen setting bean properties andconstructor arguments. Let’s take a quick look at CustomCollectionEditor, CustomMapEditor andCustomDateEditorbuilt-inpropertyeditors.Toviewthecompletelistofbuilt-inpropertyeditors,refertoorg.springframework.beans.propertyeditorspackage.

CustomCollectionEditorCustomCollectionEditor 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,CustomCollectionEditorisregisteredforSet,SortedSetandListtypes.

Consider the followingCollectionTypesExampleclass that defines attributes (and corresponding settermethods)oftypeSetandList:

Examplelisting3-36–CollectionTypesExampleclassProject–ch03-simple-types-examplesSourcelocation-src/main/java/sample/spring/chapter03/beanspackagesample.spring.chapter03.beans;importjava.util.List;importjava.util.Set;publicclassCollectionTypesExample{privateSetsetType;privateListlistType;.....//--settermethodsforattributespublicvoidsetSetType(SetsetType){this.setType=setType;}.....}

CollectionTypesExampleclassdefinessetTypeandlistTypeattributesoftypeSetandList, respectively.ThefollowingexamplelistingshowsthebeandefinitionforCollectionTypesExampleclass:

Examplelisting3-37–applicationContext.xml-BeandefinitionforCollectionTypesExampleclassProject–ch03-simple-types-examplesSourcelocation-src/main/resources/META-INF/spring

<beanclass="sample.spring.chapter03.beans.CollectionTypesExample"><propertyname="listType"><set><value>setelement1</value><value>setelement2</value>

Page 104: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

</set></property><propertyname="setType"><list><value>listelement1</value><value>listelement2</value></list></property>.....</bean>

Youmightthinkthattheaboveconfigurationisincorrectbecause<set>elementhasbeenusedtosetthevalueof listTypeproperty (of typeList), and<list> element has beenused to set thevalueof setTypeproperty(oftypeSet).

Theaboveconfigurationiscompletelylegal,andtheSpringcontainerdoesnotcomplain.ThisisbecauseCustomCollectionEditor converts the ArrayList instance (created corresponding to the <list> typeelement)toLinkedHashSettype(animplementationofSettype)beforesettingthesetTypeproperty.Also,CustomCollectionEditorconverts theLinkedHashSet instance (created corresponding to the <set> typeelement)toArrayListtype(animplementationofListtype)beforesettingthelistTypeproperty.

Figure3-4–CustomCollectionEditorconvertstheLinkedHashSettoArrayListtype

Figure3-4showsthattheCustomCollectionEditorconvertstheLinkedHashSettypetoArrayListtosetthevalueofCollectionTypesExample’s listType property.The figure shows the sequence of steps that areperformed by Spring to set the value of listType property. First, Spring creates an instance ofLinkedHashSetcorrespondingtothe<set>element.AsthelistTypepropertyisoftypeList(referexamplelisting3-36),theCustomCollectionEditorcomesintopictureforsettingthelistTypeproperty’svalue. Ifthe type of the bean property is List, CustomCollectionEditor creates an instance of ArrayList andpopulatesitwiththeelementsfromtheLinkedHashSet.Intheend,thevalueofthelistTypevariableissettotheArrayListimplementationcreatedbyCustomCollectionEditor.

Itisimportanttonotethatifapropertyorconstructorargumenttypeisaconcretecollectionclass(likeLinkedList),CustomCollectionEditorsimplycreatesaninstanceoftheconcretecollectionclassandaddselements to it from the source collection. The following figure shows a scenario in which the bean

Page 105: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

propertyisoftypejava.util.Vector(aconcretecollectionclass):

Figure3-5CustomCollectionEditorconvertstheArrayListtoVectortype

The above figure shows that the CustomCollectionEditor creates an instance of Vector (a concretecollectionclass)andaddselementstoitfromthesourcecollection,ArrayList.

Let’snowlookatCustomMapEditorpropertyeditor.

CustomMapEditorCustomMapEditorpropertyeditordealswithconvertingasourceMap type(likeHashMap) to a targetMaptype(likeTreeMap).Bydefault,CustomMapEditorisregisteredonlyforSortedMaptype.

Figure3-6showsascenarioinwhichCustomMapEditorconvertsLinkedHashMap(thesourceMaptype)toTreeMap(animplementationofSortedMaptype).

Figure3-6showsthesequenceofstepsperformedbySpringtosetthevalueofmapTypeproperty.First,Spring creates an instance of LinkedHashMap corresponding to the <map> element. As the mapTypepropertyisoftypeSortedMap,CustomMapEditorcomesintopicturewhilesettingthevalueofmapTypeproperty. CustomMapEditor creates an instance of TreeMap (a concrete implementation of SortedSetinterface),addskey-valuepairsfromLinkedHashMaptothenewlycreatedTreeMapinstanceandassignstheTreeMapinstancetothemapTypeproperty.

Page 106: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure3-6CustomMapEditorconvertstheLinkedHashMap(thesourceMaptype)toTreeMap(thetargetMaptype)type

CustomDateEditorCustomDateEditorisapropertyeditorforjava.util.Datetypebeanpropertiesandconstructorarguments.CustomDateEditorsupportsacustomjava.text.DateFormatthatisusedforformattingadate/timestringtoa java.util.Date type object, and parsing a java.util.Date type object to a date/time string. In the nextsection,we’llseehowCustomDateEditorisusedforsettingbeanpropertiesandconstructorargumentsoftype java.util.Date. Inch03-simple-types-examplesproject,CustomDateEditor converts the stringvalueofabeanproperty(referdateOfInceptionattributeofBankDetailsclass)orconstructorargument (referdateTypeconstructorargumentofDataTypesExampleclass)tojava.util.Datetype.

Inch03-simple-types-examples project, some of the other built-in property editors that are utilized bybeans include: ByteArrayPropertyEditor - for converting a string value to byte[] (referbankPrimaryBusinessattributeofBankDetailsclass),CurrencyEditor–forconvertingacurrencycodetoa java.util.Currency object (refer primaryCurrency attribute of BankDetails class),CharacterArrayPropertyEditor – for converting a string value to a char[] (refer headOfficeAddressattributeofBankDetailsclass),andsoon.

Let’snowlookathowtoregisterpropertyeditorswiththeSpringcontainer.

Page 107: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-6RegisteringpropertyeditorswiththeSpringcontainerSpring’sBeanWrapperImplclassregistersacoupleofbuilt-inpropertyeditorswiththeSpringcontainer.Forinstance,CustomCollectionEditor,CustomMapEditor,CurrencyEditor,ByteArrayPropertyEditorandCharacterArrayEditor property editors are registered by default with the Spring container. But,CustomDateEditor property editor is not registered by default with the Spring container. To registerpropertyeditorswith theSpringcontainer,youcanuseSpring’sCustomEditorConfigurerspecial bean.CustomEditorConfigurer class implements Spring’s BeanFactoryPostProcessor interface (explained indetailinsection5-4ofchapter5),anditisautomaticallydetectedandexecutedbytheSpringcontainer.

In ch03-simple-types-examples project, BankDetails class (refer example listing 3-24) defines adateOfInceptionpropertyoftypejava.util.Date.Thevaluespecifiedfor thedateOfInceptionproperty is‘30-01-2012’ (refer example listing 3-25). To convert the string value ‘30-01-2012’ to java.util.Datetype,youmustregisteracustompropertyeditorforjava.util.DatetypeoryoucanregisterSpring’sbuilt-inCustomDateEditorpropertyeditorwiththeSpringcontainer.

ToregisterpropertyeditorswiththeSpringcontainer,youneedtodothefollowing:

1. Create a class that implements Spring’s PropertyEditorRegistrar interface. This class isresponsibleforregisteringpropertyeditorswiththeSpringcontainer.

2.ConfigurethePropertyEditorRegistrarimplementationasaSpringbeanintheapplicationcontextXMLfile.

3.ConfigureSpring’sCustomEditorConfigurerspecialbeanintheapplicationcontextXMLfile,andprovideitwithreferencetothePropertyEditorRegistrarimplementation(thatyoucreatedinstep1andconfiguredinstep2).

Let’s now see how CustomDateEditor is registered with the Spring container in ch03-simple-types-examplesproject.

CreatingaPropertyEditorRegistrarimplementationThe following example listing shows the MyPropertyEditorRegistrar class that implementsPropertyEditorRegistrarinterface:

Examplelisting3-38–MyPropertyEditorRegistrarclassProject–ch03-simple-types-examplesSourcelocation-src/main/java/sample/spring/chapter03/beanspackagesample.spring.chapter03.beans;importjava.text.SimpleDateFormat;importjava.util.Date;importorg.springframework.beans.PropertyEditorRegistrar;importorg.springframework.beans.PropertyEditorRegistry;importorg.springframework.beans.propertyeditors.CustomDateEditor;

Page 108: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicclassMyPropertyEditorRegistrarimplementsPropertyEditorRegistrar{@OverridepublicvoidregisterCustomEditors(PropertyEditorRegistryregistry){registry.registerCustomEditor(Date.class,newCustomDateEditor(newSimpleDateFormat("dd-MM-yyyy"),false));}}

The above example listing shows that the MyPropertyEditorRegistrar class implements Spring’sPropertyEditorRegistrar interface, and provides implementation for registerCustomEditors methoddefined in the PropertyEditorRegistrar interface. The PropertyEditorRegistry instance passed to theregisterCustomEditors method is used for registering property editors. PropertyEditorRegistry’sregisterCustomEditor method is used for registering a PropertyEditor implementation with the Springcontainer. In the above example listing, PropertyEditorRegistry’s registerCustomEditor is used forregisteringaCustomDateEditorpropertyeditorwiththeSpringcontainer.

ConfiguringtheCustomEditorConfigurerclassThe following example listing shows how the CustomEditorConfigurer class is configured in theapplicationcontextXMLfile:

Examplelisting3-39–applicationContext.xml-CustomEditorConfigurerconfigurationProject–ch03-simple-types-examplesSourcelocation-src/main/resources/META-INF/spring

<beanid="myPropertyEditorRegistrar"class="sample.spring.chapter03.beans.MyPropertyEditorRegistrar"/><beanid="editorConfigurer"class="org.springframework.beans.factory.config.CustomEditorConfigurer"><propertyname="propertyEditorRegistrars"><list><refbean="myPropertyEditorRegistrar"/></list></property></bean>

In the above example listing, myPropertyEditorRegistrar bean definition configuresMyPropertyEditorRegistrarclassasaSpringbean.MyPropertyEditorRegistrarclassimplementsSpring’sPropertyEditorRegistrar interface, and is responsible for registering additional property editors withSpring container. CustomEditorConfigurer’s propertyEditorRegistrars property specifies a list ofPropertyEditorRegistrar implementations. In the above example listing, myPropertyEditorRegistrar isspecified as one of the values of propertyEditorRegistrars property. CustomEditorConfigurer bean isautomaticallydetectedandexecutedbytheSpringcontainer,resultinginregistrationofpropertyeditorsbytheMyPropertyEditorRegistrarinstance.

Let’s now look at how to use p-namespace (for bean properties) and c-namespace (for constructor

Page 109: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

arguments)towriteconcisebeandefinitionsinapplicationcontextXMLfiles.

Page 110: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-7ConcisebeandefinitionswithpandcnamespacesTo make bean definitions less verbose in application context XML files, Spring provides p and cnamespaces tospecifyvalues forbeanpropertiesandconstructorarguments, respectively.Thep and cnamespacesarealternativestousing<property>and<constructor-arg>elements,respectively.

Let’sfirstlookatp-namespace.

IMPORTchapter3/ch03-namespaces-example(ThisprojectshowsaSpringapplicationinwhichbeanproperties and constructor arguments are set using p- and c-namespaces, respectively. To run theapplication,executethemainmethodoftheSampleAppclassofthisproject)

p-namespaceTousep-namespacetosetbeanproperties,specifybeanpropertiesasattributesofthe<bean>element,andspecifyeachbeanpropertytobeinthep-namespace.

Thefollowingbeandefinitionshowshowtousep-namespacetosetbeanproperties:

Examplelisting3-40–applicationContext.xml-p-namespaceexampleProject–ch03-namespaces-exampleSourcelocation-src/main/resources/META-INF/spring

<beansxmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="....."><beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails"p:bankName="MyPersonalBank"p:bankPrimaryBusiness="Retailbanking"p:headOfficeAddress="Addressofheadoffice"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. ThebankDetailsbeandefinitionmakesuseofthepprefixforthep-namespacetospecifybeanproperties.Ifyou compare the above example listing with the example listing 3-25, you’ll notice that the aboveexample listing is lessverbose.Even though it ispossible touseamixof<property>elements andp-namespace to specifybeanproperties, it’s recommended thatyouchooseone style for specifyingbeanpropertiesanduseitconsistentlyinbeandefinitions.

NOTE As p-namespace is implemented as part of Spring, there is no schema corresponding to p-namespace. For this reason, you don’t see any schema reference corresponding to p-namespace inexample listing 3-40. If you want your IDE to autocomplete bean property names when using p-namespace,considerusingIntelliJIDEAorSpringSourceToolSuite(STS).

Ifabeanpropertyisnotareferencetoanotherbean,itisspecifiedusingthefollowingsyntax:

p:<property-name>="<property-value>"

Page 111: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

here,<property-name>isthenameofthebeanproperty,and<property-value>isthevalueofthebeanproperty.

Ifabeanpropertyisareferencetoanotherbean,itisspecifiedusingthefollowingsyntax:

p:<property-name>-ref="<bean-reference>"here,<property-name> isthenameofthebeanproperty,and<bean-reference> istheid (orname)ofthereferencedbean.Itisimportanttonotethatthenameofthebeanpropertyisfollowedby--ref.AsthebranchAddressespropertyofBankDetailsbeanrepresentsareferencetothebranchAddressesbean, thebranchAddressespropertyisspecifiedasp:branchAddresses-refinexamplelisting3-40.

Let’snowlookathowc-namespaceisusedforsettingconstructorarguments.

c-namespaceTo use c-namespace to supply values for constructor arguments, specify constructor arguments asattributesofthe<bean>element,andspecifyeachconstructorargumenttobeinthec-namespace.

ThefollowingexamplelistingshowstheBankStatementclassthatwe’llconfigureasaSpringbeanusingc-namespace.

Examplelisting3-41–BankStatementclassProject–ch03-namespaces-exampleSourcelocation-src/main/java/sample/spring/chapter03/beanspackagesample.spring.chapter03.beans;importjava.beans.ConstructorProperties;publicclassBankStatement{.....@ConstructorProperties({"transactionDate","amount","transactionType","referenceNumber"})publicBankStatement(DatetransactionDate,doubleamount,StringtransactionType,StringreferenceNumber){this.transactionDate=transactionDate;this.amount=amount;.....}.....}

ThefollowingbeandefinitionfortheBankStatementclassshowsusageofc-namespaceforsettingvaluesofconstructorarguments:

Examplelisting3-42–applicationContext.xml-c-namespaceexampleProject–ch03-namespaces-example

Page 112: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Sourcelocation-src/main/resources/META-INF/spring

<beansxmlns="http://www.springframework.org/schema/beans"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation=".....">.....<beanid="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 beandefinitionmakes use of the c prefix for the c-namespace to specify constructor arguments. The syntaxfollowedforspecifyingconstructorargumentsusingc-namespaceissimilartowhatwesawincaseofp-namespace.

NOTE As c-namespace is implemented as part of Spring, there is no schema corresponding to c-namespace. For this reason, you don’t see any schema reference corresponding to c-namespace inexample listing3-42. Ifyouwantyour IDE toautocompleteconstructorargumentnameswhenusingc-namespace,considerusingIntelliJIDEAorSpringSourceToolSuite(STS).

Ifaconstructorargumentisnotareferencetoanotherbean,itisspecifiedusingthefollowingsyntax:

c:<constructor-argument-name>="<constructor-argument-value>"here, <constructor-argument-name> is the name of the constructor argument, and <constructor-argument-value>isthevalueoftheconstructorargument.

Ifaconstructorargumentisareferencetoanotherbean,itisspecifiedusingthefollowingsyntax:

c:<constructor-argument-name>-ref="<bean-reference>"here,<constructor-argument-name>isthenameoftheconstructorargument,and<bean-reference> istheid(orname)ofthereferencedbean.Itisimportanttonotethatthenameoftheconstructorargumentisfollowedby--ref.Forinstance,ifaconstructorargumentnamedmyargumentrepresentsareferencetoabeanwithid‘x’,youspecifymyargumentconstructorargumentas:

c:myargument-ref="x"

Asmentioned earlier, if a class is compiledwith debug flag enabled, constructor argument names arepreserved in the generated .class file. If theBankStatement class isnot compiledwith the debug flagenabled,theconfigurationshowninexamplelisting3-42willnotwork.Insuchcases,yousupplyvaluesforconstructorargumentsusingtheirindex,asshownhere:

Examplelisting3-43–Supplyingvaluesforconstructorargumentsusingtheirindex

Page 113: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beansxmlns="http://www.springframework.org/schema/beans"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation=".....">.....<beanid="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 theBankStatement class,which uses constructorargument index insteadof constructor arguments name to supplyvalues. It is important to note that theindexoftheconstructorargumentisprefixedwithanunderscorebecauseattributenamesinXMLcannotbeginwithanumericvalue.Ifaconstructorargumentisareferencetoanotherbean,-refmustbeaddedtothe index of the constructor argument. For instance, if the constructor argument at index 0 representsreferencetoanotherbean, it isspecifiedasc:_0-ref.Even though it’spossible touseacombinationof<constructor-arg>elementsandc-namespacetospecifyconstructorarguments,it’srecommendedthatyouchooseonestyleofspecifyingconstructorargumentsanduseitconsistentlyinbeandefinitions.

Wesawearlierhow<list>,<map>and<set>elementsareusedtosetpropertiesorconstructorargumentsof typeList,MapandSet, respectively.Let’snow lookatSpring’sutil schema that simplifies creatingcollectiontypes,Propertiestype,constants,andsoon,andexposingthemasaSpringbeans.

Page 114: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-8Spring’sutilschemaSpring’s util schema simplifies configuring beans by providing a concise way to perform commonconfigurationtasks.Thefollowingtabledescribesthevariouselementsofutilschema:

Element Description

<list> Createsajava.util.Listtype,andexposesitasabean

<map> Createsajava.util.Maptype,andexposesitasabean

<set> Createsajava.util.Settype,andexposesitasabean

<constant> Exposesapublicstaticfieldonatypeasabean

<property-path> Exposesabeanpropertyasabean

<properties> Createsajava.util.Propertiesfromapropertiesfile,andexposesitasabean

NOTE All the elements of Spring’s util schema accept a scope attribute that identifies whether theexposedbeanisasingleton-orprototype-scoped.

SpringprovidesaFactoryBeaninterfacethatcanbeimplementedtocreateafactoryobjectresponsibleforcreatingbeaninstances.Insteadofusingutilschema’selementsmentionedintheabovetable,youcanuseanout-of-the-boxFactoryBeanimplementationprovidedbySpringtoperformthesamefunctionality.Inthissection,we’lllookattheutilschema’selementsandthebuilt-inFactoryBeanimplementationsthatyoucanuseinsteadofutilschema’selements.

IMPORTchapter3/ch03-util-schema-examples (This project shows a Spring application thatmakesuseofSpring’sutilschemaelementstocreatesharedinstancesofList,Set,Map,andsoon.Torun theapplication,executethemainmethodoftheSampleAppclassofthisproject)

Let’sfirstlookatthe<list>element.

<list>The<list>elementofSpring’sutil schema isused for creatingobjectsof type java.util.List, as shownhere:

Examplelisting3-44–applicationContext.xml-utilschema’s<list>elementProject–ch03-util-schema-examplesSourcelocation-src/main/resources/META-INF/spring

<beansxmlns="http://www.springframework.org/schema/beans"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation=".....http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="listType"ref="listType"/>.....</bean>

Page 115: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<util:listid="listType"list-class="java.util.ArrayList"><value>AsimpleStringvalueinlist</value><value>AnothersimpleStringvalueinlist</value></util:list></beans>

First,youneedto includeSpring’sutilschematoaccess itselements. In theaboveexample listing, the<list>elementofutilschemacreatesaninstanceofjava.util.ArrayListandexposesitasabean.Theidattribute specifies the bean id with which the java.util.ArrayList instance is exposed, and list-classattribute specifies the concrete implementation of java.util.List that you want to create. If you don’tspecify the list-class attribute, an instance of java.util.ArrayList is created by default. The <value>elementofSpring’sbeansschemaisusedtospecifyindividualelementsofthelist.

As util schema’s <list> element exposes a List instance as a bean, you can refer to the exposed Listinstancefromotherbeans.For instance, in theaboveexamplelisting, the listTypeconstructorargument(of type java.util.List)ofDataTypesExamplebeanspecifies listTypeas thevalueof the ref attribute torefertotheListinstancecreatedbytheutilschema’s<list>element.

If you compare the util schema’s <list> element shown in the above example listing with the beansschema’s<list>element(referexample listing3-27),you’llnotice that theutil schema’s<list>elementgivesyoucontrolover theList implementation to create. For instance, if youwant to create aVectorinsteadofanArrayListinstance,specifyjava.util.Vectorasthevalueofthelist-classattribute.

Let’snowlookatSpring’sListFactoryBeanwhichyoucanuseinsteadofutilschema’s<list>element.

ListFactoryBean

Analternativetousingutilschema’s<list>elementisSpring’sListFactoryBean–afactorythatisusedforcreatinginstancesofjava.util.ListandmakingthemavailableasSpringbeans.

ThefollowingexamplelistingshowshowtheListFactoryBeancanbeusedinsteadof theutil schema’s<list>element:

Examplelisting3-45–ListFactoryBeanexample<beans.....><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="listType"ref="listType"/>.....</bean><beanid="listType"class="org.springframework.beans.factory.config.ListFactoryBean"><propertyname="sourceList"><list><value>AsimpleStringvalueinlist</value><value>AnothersimpleStringvalueinlist</value>

Page 116: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

</list></property></bean></beans>

Intheaboveexamplelisting,thesourceListpropertyofListFactoryBeanspecifiestheelementsinthelist.Bydefault,ListFactoryBeancreatesaninstanceofjava.util.ArrayList.IfyouwanttheListFactoryBeantocreateaninstanceofanyotherListimplementation(likeVector),settheListFactoryBean’stargetListClassproperty.ThetargetListClasspropertyspecifiesthefully-qualifiednameoftheconcreteimplementationclassofjava.util.ListinterfacethatshouldbecreatedbytheListFactoryBean.

Ifyoucompareexamplelistings3-44and3-45,you’llnoticethatusingutilschema’s<list>elementisalotsimplerthanusingtheListFactoryBeantocreateaListinstanceandexposeitasabean.

<map>The <map> element of Spring’s util schema is used for creating an object of type java.util.Map andexposingitasabean,asshownhere:

Examplelisting3-46–applicationContext.xml-utilschema’s<map>elementProject–ch03-util-schema-examplesSourcelocation-src/main/resources/META-INF/spring

<beans.....xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation=".....http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="mapType"ref="mapType"/>.....</bean><util:mapid="mapType"map-class="java.util.TreeMap"><entrykey="mapkey1"value="mapkey1’svalue"/></util:map>.....</beans>

Intheaboveexamplelisting,utilschema’s<map>elementcreatesaninstanceofjava.util.TreeMapandexposes it as a bean.The id attribute specifies the idwithwhich the bean ismade available to otherbeans,andmap-classattributespecifiesthefully-qualifiednameoftheconcreteimplementationclassofjava.util.Map interface that should be created by the<map> element.The<entry> element of Spring’sbeansschemaspecifiesakey-valuepairinthecreatedMapinstance.

Asthe<map>elementexposesaMap instanceasabean, theexposedMap instancecanbereferencedfromotherbeans.Forinstance,intheaboveexamplelisting,DataTypesExample’smapTypeconstructor

Page 117: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

argument (of type java.util.Map) specifies value of ref attribute as mapType to refer to the TreeMapinstancecreatedbythe<map>element.

NOTEWesawearlierinthischapterthat<key>and<value>sub-elementsof<entry>areusedtospecifyakey-valuepaircontainedintheMapinstance.Theexamplelisting3-46showsthatyoucanalsospecifyakey-valuepaircontainedintheMapinstancebyusing<entry>element’skeyandvalueattributes.

If you compare the util schema’s <map> element shown in the above example listing with the beansschema’s <map> element in example listing 3-27, you’ll notice that the util schema’s <map> elementgives you control over the Map implementation to create. For instance, if you want to useLinkedHashMap instead of TreeMap, specify java.util.LinkedHashMap as the value of map-classattribute. If you don’t specify the map-class attribute, Spring container creates an instance ofjava.util.LinkedHashMapbydefault.

Let’snowlookatSpring’sMapFactoryBeanthatyoucanuseinsteadofutilschema’s<map>element.

MapFactoryBean

Insteadofusingutilschema’s<map>element,youcanuseSpring’sMapFactoryBean–afactorythat isusedforcreatinginstancesofjava.util.MapandmakingthemavailableasSpringbeans.

ThefollowingexamplelistingshowshowMapFactoryBeanisused:

Examplelisting3-47–MapFactoryBeanexample<beans.....><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="mapType"ref="mapType"/>.....</bean><beanid="mapType"class="org.springframework.beans.factory.config.MapFactoryBean"><propertyname="sourceMap"><map><entrykey="mapkey1"value="mapkey1’svalue"/></map></property></bean>.....</beans>

In the above example listing, MapFactoryBean’s sourceMap property specifies the key-value pairscontainedintheMap instancecreatedby theMapFactoryBean.Bydefault,MapFactoryBeancreatesaninstanceofjava.util.LinkedHashMap.Youcancontrol theMap instancecreatedbyMapFactoryBeanbysetting the targetMapClass property. The targetMapClass specifies the fully-qualified name of theconcreteimplementationclassofjava.util.Mapinterface.Forinstance,ifyouspecifyjava.util.HashMap

Page 118: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

asthevalueoftargetMapClass,MapFactoryBeancreatesaninstanceofjava.util.HashMap.

If you compare example listings 3-46 and 3-47, you’ll notice that using util schema’s <map> elementresultsinamoreconciseconfigurationthanMapFactoryBeanforcreatingMapinstances.

<set>The<set>elementofSpring’sutilschemaisusedforcreatinganobjectoftypejava.util.Setandexposingitasabean,asshownhere:

Examplelisting3-48–applicationContext.xml-utilschema’s<set>elementProject–ch03-util-schema-examplesSourcelocation-src/main/resources/META-INF/spring

<beans.....xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation=".....http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="setType"ref="setType"/></bean><util:setid="setType"set-class="java.util.HashSet"><value>Element1</value><value>Element2</value></util:set>.....</beans>

Intheaboveexamplelisting,utilschema’s<set>elementcreatesaninstanceofHashSetandexposesitasaSpringbeanwithidassetType.Theidattributespecifiestheidwithwhichthebeanismadeavailableto other beans, and the set-class attribute specifies the concrete implementation class of java.util.Setinterface that should be created by the <set> element.The<value> element of Spring’s beans schemaspecifiesanelementinthecreatedSetinstance.

TheSet instancecreatedby the<set>elementcanbe referenced fromotherbeans.For instance, in theaboveexamplelisting,DataTypesExample’ssetTypeconstructorargument(oftypejava.util.Set)referstotheHashSetinstancecreatedbythe<set>element.

Insteadofusingutilschema’s<set>element,youcanuseSpring’sSetFactoryBeantocreateaSetinstanceandexposeitasaSpringbean.

SetFactoryBean

Spring’sSetFactoryBeanisafactoryobjectforcreatinginstancesofjava.util.Settype.

ThefollowingexamplelistingshowshowyoucanuseSetFactoryBeantoperformthesamefunctionastheutilschema’s<set>element:

Page 119: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting3-49–SetFactoryBeanexample<beans.....><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="setType"ref="setType"/>.....</bean><beanid="setType"class="org.springframework.beans.factory.config.SetFactoryBean"><propertyname="sourceSet"><set><value>Element1</value><value>Element2</value></set></property></bean>.....</beans>

Intheaboveexamplelisting,SetFactoryBean’ssourceSetpropertyspecifiestheelementscontainedintheSetinstancecreatedbytheSetFactoryBean.SetFactoryBean’stargetSetClasspropertyspecifiesthefully-qualified name of the class that implements java.util.Set interface. If the targetSetClass property isspecified,SetFactoryBeancreatesan instanceof theclassspecifiedby the targetSetClass property andmakes it available as a Spring bean. For instance, if you specify java.util.HashSet as the value oftargetSetClass,SetFactoryBeancreatesaninstanceofjava.util.HashSet.IfthetargetSetClassproperty isunspecified,SetFactoryBeancreatesaninstanceofjava.util.LinkedHashSet.

The above example listing shows that using util schema’s <set> element results in a more conciseconfigurationthanusingSetFactoryBeanforcreatingSetinstances.

<properties>Theutilschema’s<properties>elementisusefulifyouwanttocreateaninstanceofjava.util.Propertiesobjectfromapropertiesfile,andexposethejava.util.Propertiesobjectasabean.

Thefollowingexamplelistingshowshowthe<properties>elementisused:

Examplelisting3-50–applicationContext.xml-utilschema’s<properties>elementProject–ch03-util-schema-examplesSourcelocation-src/main/resources/META-INF/spring

<beans.....xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation=".....http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd">

Page 120: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">.....<propertyname="branchAddresses"ref="branchAddresses"/></bean>.....<util:propertiesid="branchAddresses"location="classpath:META-INF/addresses.properties"/></beans>

Intheaboveexamplelisting,<properties>elementcreatesaninstanceofjava.util.Propertiescontainingpropertiesloadedfromtheaddresses.propertiesfile(specifiedbythelocationattribute),andexposesthejava.util.PropertiesinstanceasabeanwithbranchAddressesastheid(specifiedbytheidattribute).Theabove example listing also shows that the branchAddresses property (of type java.util.Properties) ofBankDetailsbeanreferstothebranchAddressesbeancreatedbytheutilschema’s<properties>element.

Analternativetousingthe<properties>elementisSpring’sPropertiesFactoryBean.

PropertiesFactoryBean

Spring’sPropertiesFactoryBeanisafactoryforcreatinginstancesofjava.util.Properties.

The following example listing shows how you can use PropertiesFactoryBean to perform the samefunctionastheutilschema’s<properties>element:

Examplelisting3-51–PropertiesFactoryBeanexample<beans.....><beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">.....<propertyname="branchAddresses"ref="branchAddresses"/></bean><beanid="branchAddresses"class="org.springframework.beans.factory.config.PropertiesFactoryBean"><propertyname="location"value="classpath:META-INF/addresses.properties"/></bean>.....</beans>

In theaboveexample listing,beandefinitionforSpring’sPropertiesFactoryBeancreatesan instanceofjava.util.Properties from the properties loaded from addresses.properties file (specified by locationproperty),andexposesthejava.util.PropertiesinstanceasabeanwithbranchAddressesastheid.

<constant>Theutilschema’s<constant>elementisusedforexposinganobject’spublicstaticfieldasaSpringbean.

Thefollowingexamplelistingshowsanexampleusageof<constant>element:

Page 121: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting3-52–applicationContext.xml-utilschema’s<constant>elementProject–ch03-util-schema-examplesSourcelocation-src/main/resources/META-INF/spring

<beans.....xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation=".....http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="booleanType"ref="booleanTrue"/>.....</bean><util:constantid="booleanTrue"static-field="java.lang.Boolean.TRUE"/>.....</beans>

Theutilschema’s<constant>elementexposesthevaluespecifiedbyitsstatic-fieldattributeasaSpringbean. In the above example listing, <constant> element exposes a bean whose value isjava.lang.Boolean.TRUEandidisbooleanTrue.Youcanspecifyanypublicstaticfieldasthevalueofthestatic-fieldattributeand refer to it fromotherbeans in theSpringcontainer.For instance, in theaboveexample listing, booleanType bean is referenced by DataTypesExample’s booleanType constructorargumentoftypeboolean.

A rather less concise way to expose public static fields as Spring beans is to use Spring’sFieldRetrievingFactoryBean.

FieldRetrievingFactoryBean

Spring’sFieldRetrievingFactoryBeanisafactoryforretrievingvalueofapublicstaticfieldspecifiedbythe FieldRetrievingFactoryBean’s staticField property. The value retrieved by theFieldRetrievingFactoryBean isexposedasabean.Youcanalsouse theFieldRetrievingFactoryBean toretrieveanon-staticfieldvalue.

ThefollowingexamplelistingshowsanexampleusageofFieldRetrievingFactoryBean:

Examplelisting3-53–FieldRetrievingFactoryBeanexample<beans.....><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<constructor-argname="booleanType"ref="booleanTrue"/>.....</bean><beanid="booleanTrue"

Page 122: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"><propertyname="staticField"value="java.lang.Boolean.TRUE"/></bean>.....</beans>

Intheaboveexamplelisting,FieldRetrievingFactoryBeanretrievesthevalueofjava.lang.Boolean.TRUEfield and exposes it as a bean.Thebean exposedby theFieldRetrievingFactoryBean is referenced byDataTypesExample’sbooleanTypeconstructorargumentoftypeboolean.

<property-path>Theutilschema’s<property-path>elementisusedtoexposeabeanpropertyvalueasabean.

Thefollowingexamplelistingshowsanexampleusageof<property-path>element:

Examplelisting3-54–applicationContext.xml-utilschema’s<property-path>elementProject–ch03-util-schema-examplesSourcelocation-src/main/resources/META-INF/spring

<beans.....xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation=".....http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">.....<propertyname="dateOfInception"ref="dateType"/>.....</bean><util:property-pathid="dateType"path="dataTypes.dateType"/><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<propertyname="dateType"value="30-01-2012"/>.....</bean></beans>

In the above example listing,DataTypesExample’s dateType property (of type java.util.Date) value isspecified as ‘30-01-2012’. The <property-path> element retrieves the DataTypesExample’s dateTypepropertyandexposesitasabeanwithidasdateType.Thepathattributeof<property-path>elementhasthefollowingsyntax:

<bean-name>.<bean-property>

Here,<bean-name>istheidornameofthebean,and<bean-property>isthenameoftheproperty.

Page 123: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

As<property-path>elementexposesabean, theexposedbeancanbe referencedbyotherbeans in theSpring container. For instance in the above example listing, dateType bean is referenced bydateOfInceptionpropertyofBankDetailsbean.

Instead of using <property-path> element, you can use Spring’s PropertyPathFactoryBean to expose abeanpropertyvalueasabean.

PropertyPathFactoryBean

PropertyPathFactoryBean is a factory used for creating bean instances that represent a bean propertyvalue.

ThefollowingexamplelistingshowshowtousePropertyPathFactoryBean:

Examplelisting3-55–PropertyPathFactoryBeanexample<beans.....xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation=".....http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><beanid="bankDetails"class="sample.spring.chapter03.beans.BankDetails">.....<propertyname="dateOfInception"ref="dateType"/>.....</bean><beanid="dataType"class="org.springframework.beans.factory.config.PropertyPathFactoryBean"><propertyname="targetBeanName"value="dataTypes"/><propertyname="propertyPath"value="dateType"/></bean><beanid="dataTypes"class="sample.spring.chapter03.beans.DataTypesExample">.....<propertyname="dateType"value="30-01-2012"/>.....</bean></beans>

In the above example listing, PropertyPathFactoryBean is used to create an instance of a bean thatrepresentsthevalueofdateTypepropertyofdataTypesbean.PropertyPathFactoryBean’stargetBeanNameattributespecifiestheidornameof thebeanthatcontains theproperty,andPropertyPathFactoryBean’spropertyPathattribute specifies thenameof thepropertywhosevalue is tobeexposedasabean.Thebean instance created by PropertyPathFactoryBean can be accessed by other beans in the Springcontainer. In the above example listing, the dataType bean created by PropertyPathFactoryBean isreferencedbydateOfInceptionproperty(oftypejava.util.Date)ofBankDetailsbean.

Page 124: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Now, thatwe have taken an in-depth look at util schema elements, let’s look at Spring’s FactoryBeaninterface.

Page 125: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-9FactoryBeaninterfaceSpring’sFactoryBeaninterfaceisimplementedbyclassesthatactasafactoryforcreatingbeaninstances.Intheprevioussection,wesawthattheclassesthatimplementtheFactoryBeaninterfaceareconfiguredintheapplicationcontextXMLfilelikeanyotherbean.FactoryBeanisparticularlyusefulifyouwanttoperformcomplicatedconditionalcheckstodecideonwhichbeantypetocreate,andtoexecutecomplexbeaninitializationlogic.

Let’snowlookatanapplicationscenarioinwhichwe’lluseFactoryBeanforselectingabeantype,andthencreatingit.

MyBankapplication–StoringeventsinthedatabaseInMyBank application, important events, like credit and debit transactions, open and liquidate fixeddeposits,andsoon,aresavedinthedatabase.MyBankmaydirectlysavetheseeventsinthedatabaseorindirectlybyfirstsendingtheeventstoamessagingmiddlewareorawebservice.ThefollowingtabledescribestheclassesthataredefinedbytheMyBankapplicationfordirectlyorindirectlysavingevents:

Class Description

DatabaseEventSender

Classthatcontainsthefunctionalityforsavingeventsinthedatabase

MessagingEventSender Classthatcontainsthefunctionalityforsendingeventstoamessagingmiddleware

WebServiceEventSender Classthatcontainsthefunctionalityforsendingeventstoaremotewebservice

Thedecisiontodirectlysavetheeventsinthedatabaseortosendthemtoamessagingmiddlewareoraweb service is based on configuration. For instance, if MyBank finds that there exists adatabase.properties file,MyBank reads the configuration information (like database url, username andpassword)fromthedatabase.propertiesfileandcreatestheDatabaseEventSenderinstance.Similarly,ifamessging.propertiesfileexists,MyBankcreatesaninstanceofMessagingEventSenderinstance,andifawebservice.propertiesfileexists,aninstanceofWebServiceEventSenderiscreated.

Initializing DatabaseEventSender, MessagingEventSender and WebServiceEventSender instances mayrequire 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 theMessagingEventSender instance so that the MessagingEventSender can send JMS messages to themessagingmiddleware.

The following class diagram shows that the FixedDepositServiceImpl class of MyBank uses eitherDatabaseEventSender or MessagingEventSender or WebServiceEventSender instance to directly orindirectlysaveeventsrelatedtofixeddepositsinthedatabase:

Page 126: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure3-7FixedDepositServiceImplclassusesoneoftheimplementationsofEventSenderinterface.

Intheaboveclassdiagram,sendEventmethodofEventSenderinterfacedefinesthecontractfordirectlyor indirectly saving events in the database. DatabaseEventSender, MessagingEventSender andWebServiceEventSender classes implement the EventSender interface and provide an appropriateimplementationforthesendEventmethod.

Let’snowlookathowFactoryBeansimplifieschoosingtherightimplementationofEventSenderinterfaceandinitializingit.

IMPORTchapter3/ch03-bankapp-factorybean(ThisprojectshowstheMyBankapplicationthatusesaFactoryBean implementation tocreateobjectsof typeEventSender.To run the application, execute themainmethodoftheBankAppclassofthisproject)

MyBank–FactoryBeanexampleIn MyBank, selecting the right EventSender implementation and initializing it is an involved task;therefore,itrepresentsanidealscenarioforusingaFactoryBeanimplementation.FactoryBean interfacedefinesthefollowingmethodsthatyouneedtoimplement:

· getObjectType:returnsthe typeoftheobjectmanagedbytheFactoryBean implementation. IncaseofMyBank,theFactoryBeanimplementationcreatesandreturnsobjectsoftypeEventSender.

·getObject:returnstheobjectmanagedbytheFactoryBeanimplementation.IncaseofMyBank,the getObject method returns an instance of DatabaseEventSender or MessagingEventSender orWebServiceEventSender.

· isSingleton: returns true if theFactoryBean implementation is a factory for singleton-scopedobjects.IftheisSingletonmethodreturnstrue,theobjectreturnedbythegetObjectmethodiscachedbytheSpringcontainerandthesameinstanceisreturnedonsubsequentrequests.IftheFactoryBeanimplementationisafactoryforprototype-scopedobjects,returnfalsefromtheisSingletonmethod.If the isSingletonmethod returns false, a fresh instance is created by getObjectmethod on everyrequest. In case of MyBank, FactoryBean implementation returns an instance ofDatabaseEventSenderorMessagingEventSender orWebServiceEventSenderclass.Once created,the same instance is used throughout the lifetime of the MyBank application; therefore, theisSingletonmethodreturnstrueincaseofMyBank.

ThefollowingexamplelistingshowstheEventSenderFactoryBean–theFactoryBeanimplementationthat

Page 127: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

createsandreturnsobjectsoftypeEventSender:

Examplelisting3-56–EventSenderFactoryBeanclassProject–ch03-bankapp-factorybeanSourcelocation-src/main/java/sample/spring/chapter03/bankapp/eventpackagesample.spring.chapter03.bankapp.event;importorg.springframework.beans.factory.FactoryBean;importorg.springframework.beans.factory.FactoryBeanNotInitializedException;importorg.springframework.core.io.ClassPathResource;.....publicclassEventSenderFactoryBeanimplementsFactoryBean<EventSender>{privateStringdatabasePropertiesFile;privateStringwebServicePropertiesFile;privateStringmessagingPropertiesFile;.....publicEventSendergetObject()throwsException{EventSendereventSender=null;Propertiesproperties=newProperties();ClassPathResourcedatabaseProperties=null;if(databasePropertiesFile!=null){databaseProperties=newClassPathResource(databasePropertiesFile);}.....if(databaseProperties!=null&&databaseProperties.exists()){InputStreaminStream=databaseProperties.getInputStream();properties.load(inStream);eventSender=newDatabaseEventSender(properties);}elseif(webServiceProperties!=null&&webServiceProperties.exists()){.....}elseif(messagingProperties!=null&&messagingProperties.exists()){.....}returneventSender;}publicClass<?>getObjectType(){returnEventSender.class;}publicbooleanisSingleton(){returntrue;}}

Page 128: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

The above example listing shows that theEventSenderFactoryBean implements FactoryBean interface.The EventSender parameter in FactoryBean<EventSender> indicates that the FactoryBean’s getObjectreturns objects of type EventSender. The databasePropertiesFile, webServicePropertiesFile andmessagingPropertiesFile are properties of the EventSenderFactoryBean class, and they represent thelocationofdatabase.properties,webservice.propertiesandmessaging.propertiesfilesintheclasspath.

ThegetObjectmethodusesSpring’sClassPathResourceclasstoverifywhetherthespecifiedpropertiesfile exists in the classpathornot. If theproperties file exists, properties from that file are loaded andpassed as to the EventSender implementation class’s constructor. For instance, in the above examplelisting,ifdatabase.propertiesfile(representedbydatabasePropertiesFileproperty)exists,propertiesareloaded from the database.properties file and passed as an argument to the DatabaseEventSender’sconstructor.ThegetObjectTypemethodreturnsEventSendertypebecausetheEventSenderFactoryBean’sgetObjectmethodreturnsobjectsoftypeEventSender.TheisSingletonmethodreturnstrue,whichmeansthattheobjectreturnedbygetObjectmethodiscachedbySpringandthesameinstanceisreturnedeverytimeEventSenderFactoryBean’sgetObjectmethodisinvoked.

Now, that you have seen howEventSenderFactoryBean class is implemented in theMyBank, you canguesshowSpring’sbuilt-inFactoryBeanimplementations,likeListFactoryBean(forcreatinginstancesofListtype),MapFactoryBean(forcreatinginstancesofMaptype),SetFactoryBean(forcreatinginstancesofSettype),andsoon,areimplemented.

The following example listing shows how EventSenderFactoryBean is configured in the applicationcontextXMLfile:

Examplelisting3-57–applicationContext.xml-EventSenderFactoryBeanconfigurationProject–ch03-bankapp-factorybeanSourcelocation-src/main/resources/META-INF/spring

<beans.....><beanid="service"class="sample.spring.chapter03.bankapp.service.FixedDepositServiceImpl">.....<propertyname="eventSender"ref="eventSenderFactory"/></bean>.....<beanid="eventSenderFactory"class="sample.spring.chapter03.bankapp.event.EventSenderFactoryBean"><propertyname="databasePropertiesFile"value="META-INF/config/database.properties"/></bean></beans>

Theaboveexample listing shows that theEventSenderFactoryBean is configured likeanyotherSpringbean.Even thoughaFactoryBean implementation isconfigured likeanyotherSpringbean, it is treateddifferentlybytheSpringcontainer.Oneofthemostimportantdifferencesisthatifabeanisdependentona FactoryBean implementation, the Spring container invokes the getObject method of the FactoryBeanimplementationandinjectsthereturnedobjectintothedependentbean.

Page 129: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

NOTEYoushouldnotethatFactoryBean’sgetObjectmethodisinvokedonlyoncebytheSpringcontaineriftheisSingletonmethodreturnstrue.

In the above example listing, bean definition for the FixedDepositServiceImpl class shows that it isdependent on the EventSenderFactoryBean – a FactoryBean implementation. So, the Spring containerinvokestheEventSenderFactoryBean’sgetObjectmethodandinjectsthereturnedEventSenderobjectintotheFixedDepositServiceImplinstance.

The following example listing shows the FixedDepositServiceImpl class that requires EventSenderinstancecreatedbyEventSenderFactoryBean:

Examplelisting3-58–FixedDepositServiceImplclassProject–ch03-bankapp-factorybeanSourcelocation-src/main/java/sample/spring/chapter03/bankapp/servicepackagesample.spring.chapter03.bankapp.service;importsample.spring.chapter03.bankapp.event.EventSender;publicclassFixedDepositServiceImplimplementsFixedDepositService{.....privateEventSendereventSender;publicvoidsetEventSender(EventSendereventSender){this.eventSender=eventSender;}.....publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....eventSender.sendEvent(event);}}

The above example listing shows that the FixedDepositServiceImpl class depends on an EventSenderinstanceandnotontheEventSenderFactoryBeaninstance.TheSpringcontainerobtainstheEventSenderinstancebyinvokingEventSenderFactoryBean’sgetObjectmethod,andinjectstheobtainedEventSenderinstanceintotheFixedDepositServiceImplinstance.

Let’snow lookathow toaccess theFactoryBean itself andnot thebean it creates and returnsvia thegetObjectmethod.

AccessingtheFactoryBeaninstanceIf youwant to obtain the FactoryBean itself from the Spring container, prefix the name (or id) of thefactorybeanwithampersand‘&’.

Let’ssaythat theFixedDepositServiceImplclass requiresaccess to theEventSenderFactoryBean itself,asshownhere:

Page 130: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Example listing 3-59 – FixedDepositServiceImpl class that depends on the EventSenderFactoryBeanitselfpackagesample.spring.chapter03.bankapp.service;importsample.spring.chapter03.bankapp.event.EventSenderFactoryBean;importsample.spring.chapter03.bankapp.event.EventSender;publicclassFixedDepositServiceImplimplementsFixedDepositService{.....privateEventSenderFactoryBeaneventSenderFactoryBean;publicvoidsetEventSenderFactoryBean(EventSenderFactoryBeaneventSenderFactoryBean){this.eventSenderFactoryBean=eventSenderFactoryBean;}.....publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){.....EventSendereventSender=eventSenderFactoryBean.getObject();evenSender.sendEvent(event);}}

Intheaboveexamplelisting,theFixedDepositServiceImplclassdependsontheEventSenderFactoryBeanitself,andusesitsgetObjectmethodtoobtainaninstanceofEventSenderobject.

Wesawinexamplelisting3-57thatwhenyoudefinetheEventSenderFactoryBeanbeanasadependencyof FixedDepositServiceImpl bean, the Spring container invokes the getObject method ofEventSenderFactoryBeanandinjects thereturnedEventSenderobject into theFixedDepositServiceImplbean.To instruct theSpring container to inject theEventSenderFactoryBean itself, add ampersand ‘&’prefixto the id(orname)of thebeanspecifiedbytherefattribute,asshownin thefollowingexamplelisting:

Examplelisting3-60–InjectingtheEventSenderFactoryBeaninstanceintotheFixedDepositServiceImplbean<beans.....><beanid="service"class="sample.spring.chapter03.bankapp.service.FixedDepositServiceImpl">.....<propertyname="eventSenderFactoryBean"ref="&amp;eventSenderFactory"/></bean>.....<beanid="eventSenderFactory"class="sample.spring.chapter03.bankapp.event.EventSenderFactoryBean"><propertyname="databasePropertiesFile"value="META-INF/config/database.properties"/>

Page 131: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

</bean></beans>

In the above example listing, the following <property> element specifies that theFixedDepositServiceImplbeanisdependentonEventSenderFactoryBean:

<propertyname="eventSenderFactoryBean"ref="&amp;eventSenderFactory"/>

Noticethattherefattribute’svalueis"&amp;eventSenderFactory".The&amp;prefixinstructstheSpringcontainertoinjecttheEventSenderFactoryBeaninstanceitselfintotheFixedDepositServiceImplbean.

The use of ampersand ‘&’ is also requiredwhen youwant to retrieve the FactoryBean instance itselfusingApplicationContext’sgetBeanmethod.ThefollowingexamplelistingshowstheBankAppclassofMyBankapplication that retrieves theEventSenderobjectcreatedby theEventSenderFactoryBean, andtheEventSenderFactoryBeaninstanceitself:

Examplelisting3-61–BankAppclassProject–ch03-bankapp-factorybeanSourcelocation-src/main/java/sample/spring/chapter03/bankapp

packagesample.spring.chapter03.bankapp;.....publicclassBankApp{privatestaticLoggerlogger=Logger.getLogger(BankApp.class);publicstaticvoidmain(Stringargs[]){ApplicationContextcontext=newClassPathXmlApplicationContext(.....logger.info("InvokinggetBean(\"eventFactory\")returns:"+context.getBean("eventSenderFactory"));logger.info("InvokinggetBean(\"&eventFactory\")returns:"+context.getBean("&eventSenderFactory"));}}

If you execute the main method of the BankApp class shown above, you’ll find that callinggetBean("eventSenderFactory") returns an instance of DatabaseEventSender class, andgetBean("&eventSenderFactory")returnsEventSenderFactoryBeaninstance.

Page 132: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3-10SummaryIn this chapter,we sawhowyou canuse beandefinition inheritance to create less verbose and easilymanageablebeandefinitions.Themajorityofthischapterfocusedonhowtosetdifferenttypesofbeanpropertiesandconstructorargumentsusingbuilt-inFactoryBean implementations,Spring’sutil schema,and p- and c-namespaces. We also looked at some of the built-in PropertyEditor implementations inSpringandhowtoregisteradditionalpropertyeditorswiththeSpringcontainer.Inthenextchapter,we’lltakeanin-depthlookatdependencyinjectionfeatureofSpring.

Page 133: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter4-Dependencyinjection

Page 134: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

4-1IntroductionIn the previous chapter, we looked at how to configure beans using Spring’s util schema, p- and c-namespaces,FactoryBeanimplementations,andsoon.Inthischapterwefocusondifferentdependencyinjection scenarioswhichwe typicallycomeacross in realworldapplicationdevelopment efforts andhowSpringaddressesthesescenarios.

We’llbeginthischapterwithalookatinnerbeans-analternativetousingtherefattributeof<property>and<constructor-arg> elements.We’ll then look at depends-on attribute of the <bean> element. In thesecond half of this chapter,we’ll look at issues thatmay arisewhen singleton- and prototype-scopedbeans collaborate to provide application behavior. We’ll wrap this chapter with an in-depth look atSpring’sautowiringfeature.

IMPORTchapter4/ch04-bankapp-dependencies(Thisprojectshowsusageofinnerbeansand<bean>element’sdepends-onattribute.Thisprojectalsoshowsimplicationsofdefiningdependenceofsingleton-scopedbeansonprototype-scopedbeans,andviceversa.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

Page 135: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

4-2InnerbeansIfadependencyofabeanisnotsharedbymultiplebeans,youcanconsiderdefiningthedependencyasaninner bean. An inner bean is defined inside a <property> or <constructor-arg> element by using the<bean>elementofSpring’sbeansschema.Youshouldnote thatan innerbean isonlyaccessible to thebeandefinitionenclosingit,andnottootherbeansregisteredwiththeSpringcontainer.

Thefollowingexamplelistingshowshowwegenerallyrepresentbeandependencies:

Examplelisting4-1–Dependencyspecifiedusing<property>element’srefattribute<beanid="service"class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl"><propertyname=“fixedDepositDao"ref="dao"/></bean><beanid="dao"class="sample.spring.chapter04.bankapp.dao.FixedDepositDaoImpl"/>

Theaboveexamplelistingshowsthattheservicebeanisdependentondaobean.Ifservicebeanistheonlybeanthatisdependentonthedaobean,thenyoucandefinethedaobeanasaninnerbeanofservicebean.

Examplelisting4-2–applicationContext.xml-InnerbeanexampleProject–ch04-bankapp-dependenciesSourcelocation-src/main/resources/META-INF/spring<beanid="service"class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl"><propertyname=“fixedDepositDao"><beanclass="sample.spring.chapter04.bankapp.dao.FixedDepositDaoImpl"/></property></bean>

In the above example listing, the bean definition for the FixedDepositDaoImpl class is inside the<property>elementofservicebean.Ifyoucomparetheaboveexamplelistingwith4-1,you’llnoticethatthe<property> element no longer specifies the ref attribute, and the <bean> element corresponding toFixedDepositDaoImplclassdoesn’thavetheidattributeanymore.

The<bean>elementcorrespondingtoaninnerbeandefinitiondoesn’tspecifyanidattributebecauseaninner bean isnot registeredwith the Spring container. If you specify an id attribute for an inner beandefinition,itisignoredbytheSpringcontainer.Aninnerbeanisalwaysprototype-scoped;therefore,ifthe <bean> element corresponding to an inner bean definition specifies the scope attribute, then it isignoredbytheSpringcontainer.Itisimportanttonotethataninnerbeanisanonymousinnature,andit’snot accessible to other beans (except the bean that contains the inner bean definition) in the Springcontainer.

NOTEAsincaseofnormalbeandefinition,youcanuse<property>,<constructor-arg>,andsoon,elementsinsidethe<bean>elementoftheinnerbeandefinition.

Page 136: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Inthepreviouschapter,wesawthatSpring’sutilschemaelementsareusedtocreatebeansthatrepresenta List, Set, Map, and so on. We saw that the beans created by Spring’s util schema elements arereferenced by other beans. The concept of inner beansmakes it possible to use Spring’s util schemaelements inside <property> and <constructor-arg> elements also, as shown in the following examplelisting:

Examplelisting4-3–utilschema’s<list>elementdefinesaninnerbean<beansxmlns="http://www.springframework.org/schema/beans"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation=".....http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><beanid="someBean"class="com.sample.SomeBean">.....<constructor-argname="listType"><util:listlist-class="java.util.ArrayList"><value>AsimpleStringvalueinlist</value><value>AnothersimpleStringvalueinlist</value></util:list></constructor-arg>.....</bean></beans>

Intheaboveexamplelisting,thelistTypeconstructorargumentisoftypejava.util.List.ThevaluepassedtothelistTypeconstructorargumentisspecifiedbytheutilschema’s<list>element.Notethatwedidn’tspecifytheidattributeofthe<list>elementbecauseSpringcontainerignoresidsofinnerbeans.

Let’snowlookatdepends-onattributeof<bean>element.

Page 137: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

4-3Explicitlycontrollingthebeaninitializationorderwithdepends-onattributeInsection1-4ofchapter1,wediscussedthatbeansarecreatedintheorderinwhichtheyaredefinedintheapplicationcontextXMLfile.Theorderinwhichbeansarecreatedisalsodecidedbasedontheinter-dependenciesofbeans.Forinstance,ifbeanAacceptsaninstanceofbeanBasaconstructorargument,theSpringcontainerwillcreatebeanBbeforebeanAirrespectiveoftheorderinwhichtheyaredefinedintheapplicationcontextXMLfile.ThisbehavioroftheSpringcontainerensuresthatthedependenciesofabean(beanBisadependencyinourexample)arecompletelyconfiguredbeforetheyareinjectedintothedependentbean(beanAisadependentbeaninourexample).

In some application scenarios, bean dependencies are not explicitly specified via <property> and<constructor-arg> elements. If the bean dependencies are not explicit, you can use <bean> element’sdepends-on attribute to explicitly specify dependencies of a bean. Spring container ensures that beandependencies specified by the depends-on attribute are initialized before the bean that specifies thedepends-onattribute.

Let’snowlookatanexamplescenarioinwhichdepends-onattributeisusedtocontroltheinitializationorderofbeans.

MyBank–implieddependenciesbetweenbeansIntheMyBankapplicationofthepreviouschapter,aFactoryBeanimplementationcreatedanEventSenderobjectthatwasusedbytheFixedDepositServiceImplinstancetodirectlyorindirectlystoreeventsinthedatabase (refer section 3-9 of chapter 3 for details). Let’s say that instead of using a FactoryBeanimplementation for creating an EventSender implementation, the approach shown in the followingdiagramisadopted:

Figure4-1–EventSenderSelectorServiceImplclasswritesthenameoftheEventSender implementationintheappConfig.propertiesfile,whichislaterreadbytheFixedDepositServiceImplinstance

Theabovediagramshowsthat:

·anEventSenderSelectorServiceImplclassisusedtodecideontheEventSenderimplementation(DatabaseEventSender orWebServiceEventSender orMessagingEventSender) to be used by theFixedDepositServiceImplclass

· EventSenderSelectorServiceImpl class stores the fully-qualified name of the EventSenderimplementationintheappConfig.propertiesfile

Page 138: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

· FixedDepositServiceImpl class reads the fully-qualified name of the EventSenderimplementationfromtheappConfig.properties file,creates theEventSenderobjectanduses it forstoringfixeddepositeventsinthedatabase

The above approach suggests that the FixedDepositServiceImpl instance won’t work correctly ifEventSenderSelectorServiceImpl fails to save the fully-qualified name of the EventSenderimplementation in the appConfig.properties file. Thismeans that theFixedDepositServiceImpl class isimplicitlydependentontheEventSenderSelectorServiceImplclass.

Let’s now look at the implication of implicit dependence of FixedDepositServiceImpl instance on theEventSenderSelectorServiceImplinstance.

ImplicitdependencyproblemConsider the following application context XML file that contains bean definitions forFixedDepositServiceImplandEventSenderSelectorServiceImplclasses:

Examplelisting4-4–applicationContext.xml-ImplicitdependencyexampleProject–ch04-bankapp-dependenciesSourcelocation-src/main/resources/META-INF/spring<beans.....><beanid="service"class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl">.....<constructor-argindex="0"value="META-INF/config/appConfig.properties"/></bean><beanid="eventSenderSelectorService"class="sample.spring.chapter04.bankapp.service.EventSenderSelectorServiceImpl"><constructor-argindex="0"value="META-INF/config/appConfig.properties"/></bean></beans>

The above application context XML file shows that both FixedDepositServiceImpl andEventSenderSelectorServiceImplclass’sconstructoracceptlocationoftheappConfig.propertiesfile.TheEventSenderSelectorServiceImplinstanceusestheappConfig.propertiesfileforcommunicatingthefully-qualifiednameoftheEventSenderimplementationclasstotheFixedDepositServiceImplinstance.Asanexplicit dependence doesn’t exist between service and eventSenderSelectorService beans, Springcontainercreates their instances in theorder inwhich theyaredefined in theapplicationcontextXMLfile. As the service bean is defined before the eventSenderSelectorService bean,FixedDepositServiceImpl instance is created before EventSenderSelectorServiceImpl instance. We’llsoon see that if FixedDepositServiceImpl instance is created before EventSenderSelectorServiceImplinstance,theFixedDepositServiceImpl instancewillnotbeable to read thenameof thefully-qualifiedEventSenderimplementationclassfromtheappConfig.propertiesfile.

Let’s now take an in-depth look at the EventSenderSelectorServiceImpl and FixedDepositServiceImplclasses,andtheappConfig.propertiesfile.

Page 139: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

EventSenderSelectorServiceImpl–thewriter

ThefollowingexamplelistingshowstheEventSenderSelectorServiceImplclass:

Examplelisting4-5–EventSenderSelectorServiceImplclassProject–ch04-bankapp-dependenciesSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;importorg.springframework.core.io.ClassPathResource;importsample.spring.chapter04.bankapp.Constants;publicclassEventSenderSelectorServiceImpl{publicEventSenderSelectorServiceImpl(StringconfigFile)throwsException{ClassPathResourceresource=newClassPathResource(configFile);OutputStreamos=newFileOutputStream(resource.getFile());Propertiesproperties=newProperties();properties.setProperty(Constants.EVENT_SENDER_CLASS_PROPERTY,"sample.spring.chapter04.bankapp.event.DatabaseEventSender");properties.store(os,null);.....}}

TheaboveexamplelistingshowsthatthelocationofappConfig.propertiesfileispassedasaconstructorargument to the EventSenderSelectorServiceImpl class’s constructor. TheEventSenderSelectorServiceImplclass’sconstructorwritesapropertynamedeventSenderClass (whichis thevalueofEVENT_SENDER_CLASS_PROPERTYconstant defined in theConstants class) to theappConfig.properties file. The eventSenderClass property specifies the fully-qualified name of theEventSender implementation to be used by the FixedDepositServiceImpl instance for directly orindirectly saving events in the database. For the sake of simplicity, EventSenderSelectorServiceImplclass’s constructor sets the fully-qualified name of the DatabaseEventSender class as the value ofeventSenderClassproperty.

appConfig.properties

The following is the entry that gets added to the appConfig.properties file byEventSenderSelectorServiceImplclass:

eventSenderClass=sample.spring.chapter04.bankapp.event.DatabaseEventSender

FixedDepositServiceImpl–thereader

TheeventSenderClasspropertywrittenby theEventSenderSelectorServiceImpl instance is read by the

Page 140: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

FixedDepositServiceImplinstance,asshowninthefollowingexamplelisting:

Examplelisting4-6–FixedDepositServiceImplclassProject–ch04-bankapp-dependenciesSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;importorg.springframework.core.io.ClassPathResource;importsample.spring.chapter04.bankapp.Constants;publicclassFixedDepositServiceImplimplementsFixedDepositService{privateFixedDepositDaofixedDepositDao;privateEventSendereventSender;publicFixedDepositServiceImpl(StringconfigFile)throwsException{ClassPathResourceconfigProperties=newClassPathResource(configFile);if(configProperties.exists()){InputStreaminStream=configProperties.getInputStream();Propertiesproperties=newProperties();properties.load(inStream);StringeventSenderClassString=properties.getProperty(Constants.EVENT_SENDER_CLASS_PROPERTY);if(eventSenderClassString!=null){Class<?>eventSenderClass=Class.forName(eventSenderClassString);eventSender=(EventSender)eventSenderClass.newInstance();logger.info("CreatedEventSenderclass");}else{logger.info("appConfig.propertiesfiledoesn'tcontaintheinformation"+"aboutEventSenderclass");}}}publicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{.....eventSender.sendEvent(event);}}

The above example listing shows following sequence of actions are performed by the constructor ofFixedDepositServiceImplclass:

Page 141: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

· loads properties from the appConfig.properties file. The configFile constructor argumentrepresentsthelocationoftheappConfig.propertiesfile.

· obtains property named eventSenderClass (represented byEVENT_SENDER_CLASS_PROPERTY constant defined in the Constants class) from theproperties loaded from theappConfig.properties file.Thevalueof eventSenderClass property isthe fully-qualified name of the EventSender implementation class that FixedDepositServiceImplneedstouse.ThevalueofeventSenderClasspropertyisstoredintheeventSenderClassStringlocalvariable.

· creates an instance of theEventSender implementation classwhose fully-qualified name isstored in the eventSenderClassString variable, and stores the newly created instance into aninstance variable named eventSender. The eventSender variable is later used by theFixedDepositServiceImpl’screateFixedDepositmethod(refertothecreateFixedDepositmethodintheaboveexamplelisting)todirectlyorindirectlystoreeventsinthedatabase.

YoushouldnotethatifapropertynamedeventSenderClassisnotfoundintheappConfig.propertiesfile,theeventSenderClassStringvariable isnot set. In this case, theFixedDepositServiceImpl’s constructorprintsthefollowingmessageontheconsole:‘appConfig.propertiesfiledoesn'tcontaintheinformationaboutEventSenderclass’.

In example listing 4-4, we looked at bean definitions for EventSenderSelectorServiceImpl andFixedDepositServiceImplclasses, and concluded that the FixedDepositServiceImpl instance is createdbeforeEventSenderSelectorServiceImplinstancebecauseSpringcontainerinitializesbeansintheorderinwhichtheyappearintheapplicationcontextXMLfile.Wesawinexamplelisting4-5thatthecreationof EventSenderSelectorServiceImpl instance results in writing an eventSenderClass property to theappConfig.properties file. So, if the FixedDepositServiceImpl instance is created before theEventSenderSelectorServiceImpl instance, the FixedDepositServiceImpl instance will not find anyeventSenderClasspropertyintheappConfig.propertiesfile.ThisshowsthattheFixedDepositServiceImplclass is implicitly dependent on the EventSenderSelectorServiceImpl class; therefore, theEventSenderSelectorServiceImplinstancemustbecreatedbeforetheFixedDepositServiceImplinstance.

Howtoaddressimplicitdependencyproblem?

Wecansolvetheimplicitdependencyproblemintwoways:

· we change the order in which bean definitions for EventSenderSelectorServiceImpl andFixedDepositServiceImpl classes are defined in the application context XML file. If the beandefinitionfortheEventSenderSelectorServiceImplclassappearsbeforethebeandefinitionfortheFixedDepositServiceImpl class, the EventSenderSelectorServiceImpl instance will be createdbeforetheFixedDepositServiceImplinstance.

· use <bean> element’s depends-on attribute to explicitly specify that the service bean(corresponding to the FixedDepositServiceImpl class) is dependent on theeventSenderSelectorServicebean(correspondingtotheEventSenderSelectorServiceImplclass).

Thefollowingexamplelistingshowstheusageof<bean>element’sdepends-onattribute:

Page 142: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting4-7–<bean>element’sdepends-onattribute<beans.....><beanid="service"class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl"depends-on="eventSenderSelectorService">.....</bean><beanid="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 isdependentontheeventSenderSelectorServicebean.Thedepends-onattributespecifiestheidsornamesof thebeansonwhich thebean isdependent.As the servicebean specifies that it is dependenton theeventSenderSelectorService bean, Spring container creates eventSenderSelectorService bean(corresponding to the EventSenderSelectorServiceImpl class) instance before service bean(correspondingtotheFixedDepositServiceImplclass)instance.

NOTE If you execute themainmethod of the BankApp class of ch04-bankapp-dependencies project,you’ll find that the FixedDepositServiceImpl instance is createdbefore EventSenderSelectServiceImplinstance. For this reason, the followingmessage is printed on the console: ‘appConfig.properties filedoesn'tcontaintheinformationaboutEventSenderclass’.

Multipleimplicitdependencies

Ifabeanhasmultipleimplicitdependencies,youcanspecifyidsornamesofallthosedependenciesasthevalueofdepends-onattribute,asshownhere:

Examplelisting4-8–depends-onattributeexample-multipleimplicitdependencies<beans.....><beanid="abean".....depends-on="bBean,cBean">.....</bean>.....</beans>

Theaboveexamplelistingshowsthatyoucanspecifymultiplebeanidsornamesasthevalueofdepends-onattribute.

depends-onattributeandbeandefinitioninheritance

It is important to note that the depends-on attribute is not inherited by child bean definitions. The

Page 143: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

following example listing shows an abstract serviceTemplate parent bean definition that uses thedepends-onattributetospecifybaseServicebeanasadependency:

Examplelisting4-9–depends-onattribute–beandefinitioninheritance<beanid="serviceTemplate"class=".....ServiceTemplate"depends-on="baseService"abstract="true"/><beanid="someService"class=".....SomeServiceImpl"parent="serviceTemplate"/><beanid="someOtherService"class=".....SomeOtherServiceImpl"parent="serviceTemplate"/><beanid="baseService"class=".....BaseServiceImpl"/>

Intheaboveexamplelisting,someServiceandsomeOtherServicechildbeandefinitionsdon’tinheritthedepends-on attribute from the serviceTemplate parent bean definition.As the Spring container createsbeansintheorderinwhichtheyaredefinedintheapplicationcontextXMLfile,thebaseServicebeaniscreatedafterthecreationofsomeServiceandsomeOtherServicebeans.

Let’s now look at how theSpring containermanages dependencies of singleton- andprototype-scopedbeans.

Page 144: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

4-4Singleton-andprototype-scopedbean’sdependenciesAsingleton-scopedbean(anditssingleton-scopeddependencies)iscreatedwhentheApplicationContextinstance is created.And, a prototype-scoped bean (and its prototype-scoped dependencies) is createdeachtimeApplicationContext’sgetBeanmethodisinvokedtoobtaintheprototype-scopedbean.

If a singleton-scoped bean is dependent on a prototype-scoped bean, or vice versa, things get a bitcomplicated.Forinstance,ifasingleton-scopedbeanisdependentonaprototype-scopedbean,youmightask the questionwhether the Spring containerwill create the prototype-scoped bean (the dependency)beforethesingleton-scopedbean(thedependentbean)?ortheSpringcontainerwillcreateandinjecttheprototype-scopedbeaninstanceonlywhenyoucalltheApplicationContext’sgetBeanmethodtoretrievethe singleton-scoped bean instance? The answers to these questions lies in the way singleton- andprototype-scopeddependenciesofabeanaremanagedbytheSpringcontainer,asexplainednext.

Singleton-scopedbean’sdependenciesThe following example listing shows the singleton-scoped customerRequestService bean of MyBankapplication,anditsdependencies:

Examplelisting4-10–applicationContext.xml-DependenciesofcustomerRequestServicebeanProject–ch04-bankapp-dependenciesSourcelocation-src/main/resources/META-INF/spring<beanid="customerRequestService"class="sample.spring.chapter04.bankapp.service.CustomerRequestServiceImpl"><constructor-argname="customerRequestDetails"ref="customerRequestDetails"/><constructor-argname="customerRequestDao"ref="customerRequestDao"/></bean><beanid="customerRequestDetails"class="sample.spring.chapter04.bankapp.domain.CustomerRequestDetails"scope="prototype"/><beanid="customerRequestDao"class="sample.spring.chapter04.bankapp.dao.CustomerRequestDaoImpl"/>

Theaboveexample listingshows that thecustomerRequestService (singleton-scoped)beandependsoncustomerRequestDetails (prototype-scoped) and customerRequestDao (singleton-scoped) beans.CustomerRequestServiceobject(representedbythecustomerRequestServicebean)representsaservicethat is invoked when a bank customer creates a new request, like a cheque book request.CustomerRequestServiceputs thedetailsof thecustomer request intoaCustomerRequestDetails object(represented by the customerRequestDetails bean) and saves it in the data store usingCustomerRequestDaoobject(representedbythecustomerRequestDaobean).

ThefollowingexamplelistingshowsthemainmethodofBankAppclass that loadsthebeandefinitionsshowninexamplelisting4-10:

Examplelisting4-11–BankAppclass

Page 145: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Project–ch04-bankapp-dependenciesSourcelocation-src/main/java/sample/spring/chapter04/bankapppackagesample.spring.chapter04.bankapp;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassBankApp{privatestaticLoggerlogger=Logger.getLogger(BankApp.class);publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");.....logger.info("BeginningwithaccessingCustomerRequestService");CustomerRequestServicecustomerRequestService_1=context.getBean(CustomerRequestService.class);.....CustomerRequestServicecustomerRequestService_2=context.getBean(CustomerRequestService.class);.....logger.info("DonewithaccessingCustomerRequestService");}}

The above example listing shows that after the ApplicationContext instance is created,ApplicationContext’sgetBeanmethodisinvokedtwicetoobtainreferencetothecustomerRequestServicebean.

IfyouexecutethemainmethodoftheBankAppclass,you’llseethefollowingoutput:CreatedCustomerRequestDetailsinstanceCreatedCustomerRequestDaoImplinstanceCreatedCustomerRequestServiceImplinstance.....BeginningwithaccessingCustomerRequestServiceDonewithaccessingCustomerRequestService

The‘Created.....’messagesshownin theaboveoutputareprintedby theconstructorsof therespectivebean classes. The above output shows that the customerRequestDetails (prototype-scoped) andcustomerRequestDao(singleton-scoped)dependenciesofthecustomerRequestService(singleton-scoped)bean are created and injected into the customerRequestService instance when the Spring container iscreated.Asno ‘Created .....’messagewasprintedon theconsolebetween ‘Beginning .....’ and ‘Done.....’ messages, no bean instances were created by the Spring container when ApplicationContext’sgetBeanmethodwasinvokedtoretrievethecustomerRequestServicebean.

Figure4-2showsthesequencediagramthatdepictsthesequenceofeventsthatoccurwhenBankApp’s

Page 146: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

mainmethod (refer example listing4-11) is executed.Figure 4-2 shows thatwhenSpring container iscreated, the customerRequestDetails (prototype-scoped) and customerRequestDao (singleton-scoped)beansarefirstcreated,followedbycreationofcustomerRequestService(singleton-scoped).Constructor-based DI is used to inject the customerRequestDetails and customerRequestDao beans into thecustomerRequestServicebean.Asasingleton-scopedbeaniscreatedonlyoncebytheSpringcontainer,theSpringcontainerhasonlyoneopportunitytoinjectcustomerRequestServicebean’sdependencies.Forthisreason,theSpringcontainerinjectsprototype-scopedcustomerRequestDetailsbeaninstanceintothecustomerRequestService bean only once. The implication of this behavior is that thecustomerRequestServicebeanendsupholdingreferencetothesamecustomerRequestDetailsbeanduringitslifetime.

Figure 4-2 - The sequence of events that occur when the Spring container is created and thecustomerRequestServicebeanisretrievedfromtheSpringcontainer

It is important to note that even if setter-based DI was used to inject the prototype-scopedcustomerRequestDetails dependency of the customerRequestService bean, the Spring container wouldhave called the settermethodonlyonce during the lifetime of the customerRequestService bean. Thismeansthatirrespectiveofwhethersetter-orconstructor-basedDIisused,asingletonbeaniscreatedandconfiguredonlyonceduringit’slifetime.

Now,oncetheSpringcontaineriscreated,anyrequestforthesingleton-scopedcustomerRequestServicebeanreturnsthesamecachedinstanceofthecustomerRequestServicebean.Forthisreason,no‘Created.....’messagewaswrittenouttotheconsolebetween‘Beginning.....’and‘Done.....’messageswhenweexecutedBankApp’smainmethod(referexamplelisting4-11).

As the singleton-scoped customerRequestService bean always holds reference to the same prototype-scopedcustomerRequestDetailsbean, itmayadverselyaffect thebehaviorofMyBankapplication.Forinstance, if multiple customers simultaneously submit request to the CustomerRequestServiceImplinstance,alltherequestswillresultinmodifyingthesameinstanceoftheCustomerRequestDetailsobjectheldbytheCustomerRequestService.Ideally,CustomerRequestServiceImplshouldcreateanewinstanceofCustomerRequestDetailsobjectoneveryrequest.Insection4-5,we’llseewhatmodificationsweneedtomaketothebeanclassofasingleton-scopedbeansothatitcanretrieveanewinstanceofaprototype-scopedbeanoneverymethodcall.

Page 147: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Let’snowlookathowtheSpringcontainermanagesprototype-andsingleton-scopeddependenciesofaprototype-scopedbean.

Prototype-scopedbean’sdependenciesInMyBank, a customer registers with theMyBank application by following a sequence of steps. Forinstance, a customer first enters personal information and his account details, and if the MyBankapplication finds a matching record, the customer is asked for his debit card details. TheCustomerRegistrationServiceImplclassofMyBankapplicationcontains thenecessarybusiness logic toregistercustomers.AsthecustomersfollowasequenceofstepstoregisterwiththeMyBankapplication,theCustomerRegistrationServiceImplobjectmaintainsconversationalstatebetweenmethodcalls.

The following example listing shows the prototype-scoped customerRegistrationService bean(representingtheCustomerRegistrationServiceImplclass)ofMyBankapplication,anditsdependencies:

Examplelisting4-12–applicationContext.xml-customerRegistrationServicebeananditsdependenciesProject–ch04-bankapp-dependenciesSourcelocation-src/main/resources/META-INF/spring<beanid="customerRegistrationService"class="sample.spring.chapter04.bankapp.service.CustomerRegistrationServiceImpl"scope="prototype"><constructor-argname="customerRegistrationDetails"ref="customerRegistrationDetails"/><constructor-argname="customerRegistrationDao"ref="customerRegistrationDao"/></bean><beanid="customerRegistrationDetails"class="sample.spring.chapter04.bankapp.domain.CustomerRegistrationDetails"scope="prototype"/><beanid="customerRegistrationDao"class="sample.spring.chapter04.bankapp.dao.CustomerRegistrationDaoImpl"/>

TheaboveexamplelistingshowsthatthecustomerRegistrationService(prototype-scoped)beandependson customerRegistrationDetails (prototype-scoped) and customerRegistrationDao (singleton-scoped)beans.

CustomerRegistrationServiceImpl instance maintains progress of the registration process, and storesinformation provided by the customer during the registration process in aCustomerRegistrationDetailsobject(representedbythecustomerRegistrationDetailsbean).AsbothCustomerRegistrationServiceImpland CustomerRegistrationDetails objects are stateful in nature, both customerRegistrationService andcustomerRegistrationDetailsbeansaredefinedasprototype-scopedbeans.

ThefollowingexamplelistingshowsthemainmethodofBankAppclassthatloadscustomerregistrationrelatedbeans(referexamplelisting4-12)andperformsregistrationsfor2customers:

Examplelisting4-13–BankAppclassProject–ch04-bankapp-dependenciesSourcelocation-src/main/java/sample/spring/chapter04/bankapp

Page 148: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

packagesample.spring.chapter04.bankapp;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassBankApp{privatestaticLoggerlogger=Logger.getLogger(BankApp.class);publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");.....logger.info("BeginningwithaccessingCustomerRegistrationService");CustomerRegistrationServicecustomerRegistrationService_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("registeredcustomerwithidaccount_1");CustomerRegistrationServicecustomerRegistrationService_2=context.getBean(CustomerRegistrationService.class);.....logger.info("registeredcustomerwithidaccount_2");logger.info("DonewithaccessingCustomerRegistrationService");}}

The above example listing shows that theBankApp’smainmethod callsApplicationContext’s getBeanmethod twice to obtain reference to customerRegistrationService bean. Once thecustomerRegistrationService bean instance is retrieved, the setAccountNumber, setAddress,setDebitCardNumber and registermethods are invoked on it. If you execute BankApp’smain method,you’llseethefollowingoutputontheconsole:

CreatedCustomerRegistrationDaoImplinstance.....BeginningwithaccessingCustomerRegistrationServiceCreatedCustomerRegistrationDetailsinstanceCreatedCustomerRegistrationServiceImplinstanceregisteredcustomerwithidaccount_1CreatedCustomerRegistrationDetailsinstanceCreatedCustomerRegistrationServiceImplinstance

Page 149: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

registeredcustomerwithidaccount_2DonewithaccessingCustomerRegistrationService

The‘Created.....’messagesshownin theaboveoutputareprintedby theconstructorsof therespectivebean classes. The above output shows that the singleton-scoped customerRegistrationDao bean(representingtheCustomerRegistrationDaoImplclass)iscreatedonlyoncewhentheApplicationContextinstance is created. The ‘Created.....’ messages between ‘Beginning.....’ and ‘Done.....’ messagesindicate thateach timeApplicationContext’sgetBeanmethod is invoked toobtain theprototype-scopedcustomerRegistrationService bean, a new instance of the customerRegistrationService bean and itsprototype-scopeddependency(thecustomerRegistrationDetailsbean)iscreatedbytheSpringcontainer.

Figure4-3showsthesequencediagramthatdepictsthesequenceofeventsthatoccurwhenBankApp’smain method (refer example listing 4-13) is executed. The figure shows that the singleton-scopedcustomerRegistrationDaobeaniscreatedonlyoncewhenApplicationContextinstanceiscreated.Whentheprototype-scopedcustomerRegistrationServicebeanisrequestedfromtheSpringcontainer,theSpringcontainer first creates an instance of customerRegistrationDetails bean (which is the prototype-scopeddependency of the customerRegistrationService bean), followed by the creation of thecustomerRegistrationServicebean.Thisshowsthatifaprototype-scopedbeanXisdependentonanotherprototype-scopedbeanY,SpringcontainerwillcreateanewinstanceofXandYeachtimeyourequestbeanXfromtheSpringcontainer.

Figure 4-3 – The sequence of events that occur when the Spring container is created and thecustomerRegistrationServicebeanisretrievedfromtheSpringcontainer

Earlierinthissection,wesawthatifasingleton-scopedbeanisdependentonaprototype-scopedbean,then throughout its lifetime the singleton-scoped bean is associated with the same instance of theprototype-scopedbean.Let’snowlookatdifferentwaysinwhichasingleton-scopedbeancanretrieveanewinstanceofaprototype-scopedbeanfromtheSpringcontainer.

Page 150: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

4-5ObtainingnewinstancesofprototypebeansinsidesingletonbeansIn the previous section, we saw that the prototype-scoped dependency of a singleton-scoped bean isinjectedat thetimeofcreationofthesingleton-scopedbean(referfigure4-2).Springcontainercreatesinstanceofasingleton-scopedbeanonlyonce;therefore,thesingleton-scopedbeanholdsreferencetothesameprototype-scopedbeaninstanceduringitslifetime.Asingleton-scopedbean’smethodscanretrievea new instance of their prototype-scoped dependency from the Spring container using any one of thefollowingapproaches:

·makethesingleton-scopedbean’sclassimplementSpring’sApplicationContextAwareinterface

·usethe<lookup-method>elementofSpring’sbeansschema

·usethe<replaced-method>elementofSpring’sbeansschema

NOTEItispossibletousethenewkeywordtocreateaninstanceoftheprototype-scopedbean’sclassinasingleton-scopedbean’smethodanduseit.AstheresponsibilityofcreatingabeaninstanceiswiththeSpringcontainer,weshouldnotattempttodirectlycreateabeaninstanceusingthenewkeyword.

IMPORTchapter4/ch04-bankapp-context-aware(Thisprojectshowsascenarioinwhichasingleton-scopedbeanimplementsSpring’sApplicationContextAwareinterfacetoobtaininstancesofaprototype-scopedbeanfromtheSpringcontainer.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

Let’sfirstbeginbylookingattheApplicationContextAwareinterface.

ApplicationContextAwareinterfaceSpring’s ApplicationContextAware interface is implemented by beans that require access to theApplicationContext instance in which they are running. ApplicationContextAware interface defines asinglemethod, setApplicationContext, which provides the implementing beans with an instance of theApplicationContextobject.

ApplicationContextAwareinterfaceisalifecycleinterface,whichmeansthat theSpringcontainercallsthebeansimplementingtheApplicationContextAwareinterfaceatappropriatetimesduringtheirlifetime.Forinstance,ApplicationContextAware’ssetApplicationContextmethodiscalledbytheSpringcontainerafterthebeaninstanceiscreatedbutbeforethebeaninstanceiscompletelyinitialized.Abeaninstanceisconsideredcompletelyinitializedonlyafterits initializationmethod (refersection5-2ofchapter5) iscalledbytheSpringcontainer.Itisimportanttonotethatafterabeaninstanceiscompletelyinitialized,itis injected into thedependentbean instancesby theSpringcontainer. In chapter5,we’ll lookat somemorelifecycleinterfacesinSpring.

AbeanthatimplementstheApplicationContextAwareinterfacecanaccessotherbeansregisteredwiththeApplicationContextinstancebycallingApplicationContext’sgetBeanmethod.Thismeansthatifthebeanclass of a singleton-scoped bean implements ApplicationContextAware interface, it can fetch a newinstanceofaprototype-scopedbeanfromtheSpringcontainerbycallingApplicationContext’sgetBeanmethod.Asthesingleton-scopedbeanexplicitlyobtainsitsprototype-scopeddependencyfromtheSpringcontainerbycallingApplicationContext’sgetBeanmethod,youdon’tneedtodefinetheprototype-scopedbeanasadependencyofthesingleton-scopedbeanintheapplicationcontextXMLfile.

Page 151: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

ThefollowingexamplelistingshowstheCustomerRequestServiceImplclassthatneedsanewinstanceofCustomerRequestDetails object each time CustomerRequestServiceImpl’s submitRequest method iscalled:

Examplelisting4-14–CustomerRequestServiceImplclassProject–ch04-bankapp-context-awareSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;importsample.spring.chapter04.bankapp.dao.CustomerRequestDao;importsample.spring.chapter04.bankapp.domain.CustomerRequestDetails;publicclassCustomerRequestServiceImplimplementsCustomerRequestService{privateCustomerRequestDetailscustomerRequestDetails;privateCustomerRequestDaocustomerRequestDao;@ConstructorProperties({"customerRequestDetails","customerRequestDao"})publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,CustomerRequestDaocustomerRequestDao){this.customerRequestDetails=customerRequestDetails;this.customerRequestDao=customerRequestDao;}publicvoidsubmitRequest(StringrequestType,StringrequestDescription){//--populateCustomerRequestDetailsobjectandsaveitcustomerRequestDetails.setType(requestType);customerRequestDetails.setDescription(requestDescription);customerRequestDao.submitRequest(customerRequestDetails);}}

TheaboveexamplelistingshowsthattheCustomerRequestDetailsandCustomerRequestDaoobjectsarepassedasargumentstotheCustomerRequestServiceImplclass’sconstructor.ThesubmitRequestmethodpopulates the CustomerRequestDetails instance and saves it into the database by callingCustomerRequestDao’ssubmitRequestmethod. Ifmultiplecustomerssimultaneouslysubmit request, thesubmitRequestmethodwill endupmodifying the same instanceof theCustomerRequestDetails object,resulting in undesired behavior ofMyBank application.To address this issue, the submitRequestmustobtainanewinstanceoftheCustomerRequestDetailsobjectfromtheSpringcontaineroneachinvocation.

The followingexample listing shows theCustomerRequestServiceContextAwareImpl class (amodifiedversionofCustomerRequestServiceImplclassthatwesawinexamplelisting4-14)thatimplementstheApplicationContextAwareinterface:

Example listing 4-15 – CustomerRequestServiceContextAwareImpl class that implements Spring’sApplicationContextAwareinterfaceProject–ch04-bankapp-context-aware

Page 152: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Sourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;publicclassCustomerRequestServiceContextAwareImplimplementsCustomerRequestService,ApplicationContextAware{privateCustomerRequestDaocustomerRequestDao;privateApplicationContextapplicationContext;@ConstructorProperties({"customerRequestDao"}) publicCustomerRequestServiceContextAwareImpl(CustomerRequestDaocustomerRequestDao){this.customerRequestDao=customerRequestDao;}publicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{this.applicationContext=applicationContext;}publicvoidsubmitRequest(StringrequestType,StringrequestDescription){CustomerRequestDetailscustomerRequestDetails=applicationContext.getBean(CustomerRequestDetails.class);customerRequestDetails.setType(requestType);customerRequestDetails.setDescription(requestDescription);customerRequestDao.submitRequest(customerRequestDetails);}}

In the above example listing, setApplicationContext method providesCustomerRequestServiceContextAwareImpl with an instance of ApplicationContext object. TheApplicationContext instance is later used by the submitRequest method to obtain an instance ofCustomerRequestDetailsobjectfromtheSpringcontainer.

As the CustomerRequestServiceContextAwareImpl class explicitly obtains CustomerRequestDetailsobject from the Spring container, you don’t need to use Spring’s DI mechanism to injectCustomerRequestDetails instance into theCustomerRequestServiceContextAwareImpl instance. For thisreason, CustomerRequestServiceContextAwareImpl class’s constructor (refer example listing 4-15)doesn’tspecifyCustomerRequestDetailsobjectasanargument.Ifyounowgotoch04-bankapp-context-awareprojectandexecuteBankApp’smainmethod,you’llfindthatoneachinvocationofsubmitRequestmethodanewinstanceofCustomerRequestDetailsobjectisfetchedfromtheSpringcontainer.

Page 153: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

InthecontextofMyBank,wesawthattheApplicationContextAwareinterfaceisusefulifabeanrequiresaccess to other beans.Thedownside of implementing theApplicationContextAware interface is that itcouples your bean class toSpringFramework.You can avoid couplingyour bean classeswithSpringFrameworkandstillaccessotherbeansfromtheSpringcontainerbyusingmethodinjection techniquesofferedby<lookup-method>and<replaced-method>elementsofSpring’sbeansschema.

Let’sfirstlookatthe<lookup-method>element.

IMPORT chapter 4/ch04-bankapp-lookup-method (This project shows theMyBank application thatuses<lookup-method>elementofSpring’sbeansschema.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

<lookup-method>elementIfabeanclassdefinesabeanlookupmethodwhosereturntyperepresentsabean,the<lookup-method>element instructs the Spring container to provide implementation for this method. The methodimplementationprovidedbytheSpringcontainerisresponsibleforretrievingthebeaninstancefromtheSpringcontainerandreturningit.

The <lookup-method> element’s bean attribute specifies the name of the bean to be looked-up andreturnedby themethod implementation,and thenameattribute specifies thenameof themethodwhoseimplementation is to be provided by the Spring container. It is important to note that the bean lookupmethoddefinedbythebeanclasscanbeanabstractoraconcretemethod.

NOTETheuseof<lookup-method>elementtoinstructtheSpringcontainertoprovideimplementationforabeanlookupmethodisreferredtoasa‘MethodInjectiontechinique’becausethe<lookup-method>elementinjectsabeanlookupmethodimplementationintothebeanclass.

The following example listing shows CustomerRequestServiceImpl’s getCustomerRequestDetailsabstractmethodthatreturnsaninstanceofCustomerRequestDetailsinstance:

Examplelisting4-16–CustomerRequestServiceImplclass–definingabeanlookupmethodProject–ch04-bankapp-lookup-methodSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;publicabstractclassCustomerRequestServiceImplimplementsCustomerRequestService{privateCustomerRequestDaocustomerRequestDao;@ConstructorProperties({"customerRequestDao"})publicCustomerRequestServiceImpl(CustomerRequestDaocustomerRequestDao){this.customerRequestDao=customerRequestDao;}publicabstractCustomerRequestDetailsgetCustomerRequestDetails();@Override

Page 154: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicvoidsubmitRequest(StringrequestType,StringrequestDescription){//--populateCustomerRequestDetailsobjectandsaveitCustomerRequestDetailscustomerRequestDetails=getCustomerRequestDetails();.....}}

The above example listing shows that the CustomerRequestServiceImpl class is defined as abstractbecauseitcontainsanabstractbeanlookupmethod,getCustomerRequestDetails.Insteadofabstract,wecould have very well defined the getCustomerRequestDetails method as a concrete method. ThesubmitRequest method invokes the getCustomerRequestDetails method to access aCustomerRequestDetailsinstance.

The following example listing shows bean definitions for CustomerRequestServiceImpl andCustomerRequestDetailsclasses:

Examplelisting4-17–applicationContext.xml-<lookup-method>elementusageProject–ch04-bankapp-lookup-methodSourcelocation-src/main/resources/META-INF/spring

<beanid="customerRequestService"class="sample.spring.chapter04.bankapp.service.CustomerRequestServiceImpl"><constructor-argname="customerRequestDao"ref="customerRequestDao"/><lookup-methodbean="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 classcontains a <lookup-method> element. The value of <lookup-method> element’s name attribute isgetCustomerRequestDetails, which instructs the Spring container to provide implementation for thegetCustomerRequestDetailslookupmethod(referexamplelisting4-16)ofCustomerRequestServiceImplclass.Thevalueof<lookup-method>element’sbeanattribute iscustomerRequestDetails,whichmeansthat the implementation of getCustomerRequestDetails method retrieves a bean with id (or name) ascustomerRequestDetails from the Spring container and returns it to the calling method. As thecustomerRequestDetails bean represents a CustomerRequestDetails object (refer to thecustomerRequestDetails bean definition in example listing 4-17), the implementation ofgetCustomerRequestDetailsmethodreturnsaCustomerRequestDetailsobject.

In example listing 4-16, the CustomerRequestService’s submitRequest method invokes thegetCustomerRequestDetails bean lookup method to obtain a CustomerRequestDetails instance. AsCustomerRequestDetailsclassisrepresentedasaprototype-scopedbeanintheapplicationcontextXMLfile (refer example listing4-17), each invocationof the submitRequestmethod results in retrievalof anewinstanceofCustomerRequestDetailsobjectfromtheSpringcontainer.

To check that the <lookup-method> element provides correct implementation for the

Page 155: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

CustomerRequestService’s getCustomerRequestDetails bean lookup method, the main method ofBankAppclassobtainsaninstanceofCustomerRequestServicefromtheSpringcontainerandinvokesitssubmitRequestmethodmultipletimes.IfeachinvocationofthesubmitRequestmethodresultsinretrievalof a fresh instance ofCustomerRequestDetails object from the Spring container, then itmeans that the<lookup-method> element provides correct implementation for the CustomerRequestService’sgetCustomerRequestDetailsmethod.

ThefollowingexamplelistingshowstheBankApp’smainmethodthatinvokesCustomerRequestService’ssubmitRequestmethodmultipletimes:

Examplelisting4-18–BankAppclassProject–ch04-bankapp-lookup-methodSourcelocation-src/main/java/sample/spring/chapter04/bankapppackagesample.spring.chapter04.bankapp;.....publicclassBankApp{privatestaticLoggerlogger=Logger.getLogger(BankApp.class);publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");.....logger.info("BeginningwithaccessingCustomerRequestService");CustomerRequestServicecustomerRequestService_1=context.getBean(CustomerRequestService.class);customerRequestService_1.submitRequest("checkBookRequest","Requesttosenda50-leafcheckbook");customerRequestService_1.submitRequest("checkBookRequest","Requesttosenda100-leafcheckbook");.....logger.info("DonewithaccessingCustomerRequestService");}}

IfyouexecutetheBankApp’smainmethod,you’llseethefollowingoutputontheconsole:BeginningwithaccessingCustomerRequestServiceCreatedCustomerRequestDetailsinstanceCreatedCustomerRequestDetailsinstance.....DonewithaccessingCustomerRequestService

The‘Created.....’messagesshownin theaboveoutputareprintedby theconstructorsof therespectivebeanclasses.TheaboveoutputshowsthateachinvocationofCustomerRequestService’ssubmitRequestmethodresultedinretrievalofanewCustomerRequestDetailsinstancefromtheSpringcontainer.

AstheimplementationofthebeanlookupmethodisprovidedbytheSpringcontainer,somerestrictions

Page 156: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

applytothesignatureofthebeanlookupmethods.Forinstance,thebeanlookupmethodmustbedefinedaspublicorprotected,anditmustnotacceptanyarguments.AsthebeanclasscontainingthebeanlookupmethodissubclassedatruntimebytheSpringcontainertoprovidetheimplementationforthebeanlookupmethod,thebeanclassandthebeanlookupmethodmustnotbedefinedasfinal.

NOTEAs thebeanclass containing thebean lookupmethodneeds tobe subclassed at runtimeby theSpringcontainertoprovideimplementationforthebeanlookupmethod,theSpringcontainerusesCGLIB(http://cglib.sourceforge.net/) librarytoperformsubclassingofthebeanclass.StartingwithSpring3.2,the CGLIB classes are packaged within the spring-core JAR file itself; therefore, you don’t need toexplicitlyspecifythatyourprojectisdependentonCGLIBJARfile.

The<lookup-method> element provides amethod injection technique inwhich a bean class defines abeanlookupmethodwhoseimplementationisprovidedbytheSpringcontainer.Insteadofusing<lookup-method> element, you can consider using <replaced-method> element of Spring’s beans schema toperformmethodinjection.

IMPORTchapter4/ch04-bankapp-replaced-method(ThisprojectshowstheMyBankapplicationthatuses <replaced-method> element of Spring’s beans schema. To run the application, execute the mainmethodoftheBankAppclassofthisproject)

<replaced-method>elementThe<replaced-method>elementallowsyoutoreplaceanyarbitrarymethodinabeanclasswith a different implementation. The following example listing shows theCustomerRequestServiceImpl class thatwe’ll be using as an example to demonstrate use of<replaced-method>element:

Examplelisting4-19–CustomerRequestServiceImplclassProject–ch04-bankapp-replaced-methodSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;.....publicclassCustomerRequestServiceImplimplementsCustomerRequestService{privateCustomerRequestDaocustomerRequestDao;.....publicObjectgetMyBean(StringbeanName){returnnull;}@OverridepublicvoidsubmitRequest(StringrequestType,StringrequestDescription){//--populateCustomerRequestDetailsobjectandsaveitCustomerRequestDetailscustomerRequestDetails=(CustomerRequestDetails)getMyBean("customerRequestDetails");customerRequestDetails.setType(requestType);customerRequestDetails.setDescription(requestDescription);

Page 157: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

customerRequestDao.submitRequest(customerRequestDetails);}}

The above example listing shows that the CustomerRequestServiceImpl class defines a getMyBeanmethod.ThegetMyBeanmethodacceptsnameofabeanasanargument,andinsteadofreturningthebeaninstance corresponding to the bean name argument, the getMyBean method returns null. ThesubmitRequestmethodpassescustomerRequestDetailsstringasargument to thegetMyBeanmethodandassumes that the getMyBean method returns an instance of customerRequestDetails bean. Using<replaced-method>element,youcanoverridethegetMyBeanmethodwithamethodthatreturnsthebeaninstancecorrespondingtothebeannameargument.

The <replaced-method> element needs information about the overridden method (which isCustomerRequestServiceImplgetMyBeanmethod in our example scenario) and theoverridingmethod.TheoverridingmethodisprovidedbytheclassthatimplementsSpring’sMethodReplacerinterface.Thefollowing example listing shows MyMethodReplacer class that implements the MethodReplacerinterface:

Examplelisting4-20–MyMethodReplacerclassProject–ch04-bankapp-replaced-methodSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;importorg.springframework.beans.factory.support.MethodReplacer;importorg.springframework.context.ApplicationContextAware;publicclassMyMethodReplacerimplementsMethodReplacer,ApplicationContextAware{privateApplicationContextapplicationContext;@OverridepublicObjectreimplement(Objectobj,Methodmethod,Object[]args)throwsThrowable{returnapplicationContext.getBean((String)args[0]);}@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{this.applicationContext=applicationContext;}}

Spring’sMethodReplacerinterfacedefinesareimplementmethodwhoseimplementationisprovidedbythe MyMethodReplacer class. The reimplement method represents the overriding method.MyMethodReplacer class also implements Spring’s ApplicationContextAware interface so that thereimplement method can access the ApplicationContext instance. The reimplement method uses theApplicationContext’sgetBeanmethodtoretrievebeansfromtheSpringcontainer.

Page 158: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Thereimplementmethodacceptsthefollowingarguments:

·Objectobj–identifiestheobjectwhosemethodweareoverriding.Inourexamplescenario,theobjobjectistheCustomerRequestServiceImplobject.

· Methodmethod – identifies the bean class’smethod that is overridden by the reimplementmethod.Inourexamplescenario,thisisCustomerRequestServiceImpl’sgetMyBeanmethod.

·Object[]args–identifiesargumentspassedtothemethodthatweareoverriding.Inourexamplescenario,args represents the arguments passed to theCustomerRequestServiceImpl’s getMyBeanmethod.Inexamplelisting4-20,args[0]inthereimplementmethodrefersthebeannameargumentpassedtotheCustomerRequestServiceImpl’sgetMyBeanmethod.

IfyounowlookatMyMethodReplacer’sreimplementmethodinexamplelisting4-20,youcaninferthatitusesargs argument to first obtain bean name passed to theCustomerRequestServiceImpl’s getMyBeanmethod,andthencallsApplicationContext’sgetBeanmethod toobtain thecorrespondingbean instance.As MyMethodReplacer’s reimplement method overrides CustomerRequestServiceImpl’s getMyBeanmethod,call togetMyBeanmethodat runtime returns thebean instancewhosenamewaspassed to thegetMyBeanmethod.

The <replaced-method> element informs the Spring container that MyMethodReplacer’s reimplementmethodoverridesCustomerRequestServiceImpl’sgetMyBeanmethod,asshowninthefollowingexamplelisting:

Examplelisting4-21–applicationContext.xml-<replaced-method>elementusageProject–ch04-bankapp-replaced-methodSourcelocation-src/main/resources/META-INF/spring

<beanid="customerRequestService"class="sample.spring.chapter04.bankapp.service.CustomerRequestServiceImpl"><constructor-argname="customerRequestDao"ref="customerRequestDao"/><replaced-methodname="getMyBean"replacer="methodReplacer"/></bean><beanid="methodReplacer"class="sample.spring.chapter04.bankapp.service.MyMethodReplacer"/>

The above example listing shows bean definitions for MyMethodReplacer andCustomerRequestServiceImplclasses.The<replace-method>element’snameattributespecifiesnameofthe method that you want to override, and the replacer attribute specifies reference to the bean thatimplementstheMethodReplacer interface.Themethodspecifiedbythenameattribute isoverriddenbythereimplementmethodofthebeanreferencedbythereplacerattribute.

As in case of <lookup-method> element, the main method of the BankApp class of ch04-bankapp-replaced-method project validates whether or not the <replaced-method> element overrides theCustomerRequestService’s getMyBean method with the MyMethodReplacer’s reimplement method.BankAppclassofch04-bankapp-replaced-methodprojectissameastheonewesawinexamplelisting4-18 for ch04-bankapp-lookup-methodproject. If you execute themainmethod of theBankApp class,you’llfindthat<replaced-method>elementoverridesCustomerRequestServiceImpl’sgetMyBeanmethod

Page 159: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

withMyMethodReplacer’s reimplementmethod; therefore, a fresh instance of CustomerRequestDetailsinstanceisretrievedfromtheSpringcontainereachtimeCustomerRequestServiceImpl’ssubmitRequestmethod(referexamplelisting4-19)isinvoked.

It is important to note that you can use <replaced-method> element to replace an abstract or concretemethod of a bean classwith a differentmethod implementation. For instance, we could have definedgetMyBeanmethodasanabstractmethodandused the<replaced-method>element in thesamewayasdescribedinthissection.

NOTEAsthebeanclassneedstobesubclassedatruntimebytheSpringcontainertoreplaceabeanmethodwithadifferentmethod,theSpringcontainerusesCGLIB(http://cglib.sourceforge.net/)librarytoperformsubclassingofthebeanclass.StartingwithSpring3.2,theCGLIBclassesarepackagedwithinthespring-coreJARfileitself;therefore,youdon’tneedtoexplicitlyspecifythatyourprojectisdependentonCGLIBJARfile.

Let’snowlookathow<replaced-method>elementuniquelyidentifiesthebeanmethodtobeoverridden.

Uniquelyidentifyingthebeanmethod

Youmay come across scenarios inwhich the beanmethod that youwant to replace using <replaced-method>elementcan’tbeuniquelyidentifiedbyname.Forinstance,thefollowingexamplelistingshowsabeanclassthatcontainsoverloadedperformmethods:

Examplelisting4-22–OverloadedmethodsinabeanclasspublicclassMyBean{publicvoidperform(Stringtask1,Stringtask2){.....}publicvoidperform(Stringtask){.....}publicvoidperform(my.Tasktask){.....}}

In theaboveexample listing, theMyBeanclasscontainsmultiplemethodsnamedperform.Touniquelyidentifythebeanmethodtobeoverridden,the<replaced-method>elementuses<arg-type>sub-elementsto specifymethod argument types. For instance, the following example listing shows how <replaced-method>elementspecifiesthattheperform(String,String)methodofMyBeanclassshouldbereplaced:

Examplelisting4-23–<replaced-method>elementwith<arg-type>sub-element<beanid="mybean"class="MyBean"><replaced-methodname="perform"replacer="....."><arg-type>java.lang.String</arg-type><arg-type>java.lang.String</arg-type></replaced-method></bean>

Insteadofusingthefully-qualifiednameasthevalueof<arg-type>element,youcanuseasubstringofthefully-qualifiednameasthevalue.Forinstance, insteadofusingjava.lang.String,youcanspecifyStrorStringasthevalueof<arg-type>elementintheaboveexamplelisting.

Page 160: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Let’snowlookatSpring’sautowiringfeaturethatsavesyoutheeffortofspecifyingbeandependenciesintheapplicationcontextXMLfile.

Page 161: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

4-6AutowiringdependenciesIn Spring, you have the option to either explicitly specify bean dependencies using <property> and<constructor-arg>elementsorletSpringautomaticallyresolvebeandependencies.TheprocessinwhichdependenciesareautomaticallyresolvedbySpringisreferredtoas‘autowiring’.

IMPORTchapter4/ch04-bankapp-autowiring (This project shows theMyBank application that usesSpring’sautowiringfeaturefordependencyinjection.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

The<bean>element’sautowireattributespecifieshowabean’sdependenciesareautomaticallyresolvedbySpring.The autowire attribute can take any one of the following values: default, byName, byType,constructorandno.Let’snowlookateachoftheseattributevaluesindetail.

NOTEYoushouldnotethatthe<bean>element’sautowireattributeisnotinheritedbychildbeandefinitions.

byTypeIfyouspecifyautowireattribute’svalueasbyType,Springautowiresbeanpropertiesbasedontheirtype.For instance, if a bean A defines a property of type X, Spring finds a bean of type X in theApplicationContextandinjectsitintobeanA.Let’slookatanexampleusageofbyTypeautowiringintheMyBankapplication.

ThefollowingexamplelistingshowstheMyBankapplication’sCustomerRegistrationServiceImplclass:

Examplelisting4-24–CustomerRegistrationServiceImplclassProject–ch04-bankapp-autowiringSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;publicclassCustomerRegistrationServiceImplimplementsCustomerRegistrationService{privateCustomerRegistrationDetailscustomerRegistrationDetails;privateCustomerRegistrationDaocustomerRegistrationDao;....publicvoidsetCustomerRegistrationDetails(CustomerRegistrationDetailscustomerRegistrationDetails){this.customerRegistrationDetails=customerRegistrationDetails;}publicvoidsetCustomerRegistrationDao(CustomerRegistrationDaocustomerRegistrationDao){this.customerRegistrationDao=customerRegistrationDao;}.....}

Page 162: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

The above example listing shows that the CustomerRegistrationServiceImpl class defines propertiesnamedcustomerRegistrationDetails (of typeCustomerRegistrationDetails)andcustomerRegistrationDao(of type CustomerRegistrationDao). This means that the CustomerRegistrationDetails andCustomerRegistrationDaoobjectsaredependenciesofCustomerRegistrationServiceImplobject.

The following example listing shows bean definitions for CustomerRegistrationServiceImpl,CustomerRegistrationDetails and CustomerRegistrationDaoImpl (an implementation ofCustomerRegistrationDaointerface)classes:

Examplelisting4-25–applicationContext.xml-autowiringbyTypeconfigurationProject–ch04-bankapp-autowiringSourcelocation-src/main/resources/META-INF/spring

<beanid="customerRegistrationService"class="sample.spring.chapter04.bankapp.service.CustomerRegistrationServiceImpl"scope="prototype"autowire="byType"/><beanid="customerRegistrationDetails"class="sample.spring.chapter04.bankapp.domain.CustomerRegistrationDetails"scope="prototype"/><beanid="customerRegistrationDao"class="sample.spring.chapter04.bankapp.dao.CustomerRegistrationDaoImpl"/>

Intheaboveexamplelisting,thecustomerRegistrationServicebeandefinitiondoesn’tcontain<property>elementsforsettingcustomerRegistrationDetailsandcustomerRegistrationDaoproperties(referexamplelisting4-24).Instead,the<bean>elementspecifiesautowireattribute’svalueasbyTypetoinstructSpringto automatically resolve dependencies of the customerRegistrationService bean based on their type.Spring looks for beans of types CustomerRequestDetails and CustomerRegistrationDao in theApplicationContext, and injects them into the customerRegistrationService bean. AscustomerRegistrationDetails and customerRegistrationDao beans represent beans of typesCustomerRegistrationDetails and CustomerRegistrationDao, the Spring container injectscustomerRegistrationDetailsandcustomerRegistrationDaobeansintocustomerRegistrationServicebean.

It may happen that Spring doesn’t find any bean registered with the ApplicationContext whose typematches theproperty type. In suchcases, noexception is thrownand thebeanproperty isnot set. Forinstance, if a bean defines a property x of typeY, and there is no bean of typeY registeredwith theApplicationContext instance, the property x is not set. If Spring finds multiple beans in theApplicationContextthatmatchthepropertytype,anexceptionisthrown.Insuchcases, insteadofusingautowiringfeature,use<property>elementstoexplicitlyidentifybeandependenciesorsetabeanastheprimarycandidateforautowiringbysettingthevalueofprimaryattributeof<bean>elementtotrue.

constructorIf you specify autowire attribute’s value as constructor, Spring autowires bean class’s constructorargumentsbasedontheirtype.Forinstance,ifbeanA’sconstructoracceptsargumentsoftypeXandY,SpringfindsbeansoftypesXandYintheApplicationContextandinjectsthemasargumentstobeanA’sconstructor.Let’slookatanexampleusageofconstructorautowiringintheMyBankapplication.

Page 163: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

ThefollowingexamplelistingshowstheMyBankapplication’sCustomerRequestServiceImplclass:

Examplelisting4-26–CustomerRequestServiceImplclassProject–ch04-bankapp-autowiringSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;publicclassCustomerRequestServiceImplimplementsCustomerRequestService{privateCustomerRequestDetailscustomerRequestDetails;privateCustomerRequestDaocustomerRequestDao;@ConstructorProperties({"customerRequestDetails","customerRequestDao"})publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,CustomerRequestDaocustomerRequestDao){this.customerRequestDetails=customerRequestDetails;this.customerRequestDao=customerRequestDao;}.....}

The CustomerRequestServiceImpl class defines a constructor that accepts arguments of typeCustomerRequestDetailsandCustomerRequestDao.

The following example listing shows bean definitions for CustomerRequestServiceImpl,CustomerRequestDetails and CustomerRequestDaoImpl (an implementation of CustomerRequestDaointerface)classes:

Examplelisting4-27–applicationContext.xml-constructorautowiringProject–ch04-bankapp-autowiringSourcelocation-src/main/resources/META-INF/spring

<beanid="customerRequestService"class="sample.spring.chapter04.bankapp.service.CustomerRequestServiceImpl"autowire="constructor"></bean><beanid="customerRequestDetails"class="sample.spring.chapter04.bankapp.domain.CustomerRequestDetails"scope="prototype"/><beanid="customerRequestDao"class="sample.spring.chapter04.bankapp.dao.CustomerRequestDaoImpl"/>

In theaboveexample listing, thecustomerRequestServicebeandefinitionspecifiesautowire attribute’svalue as constructor, which means that Spring locates beans of types CustomerRequestDetails andCustomerRequestDao in the ApplicationContext, and passes them as arguments toCustomerRequestServiceImpl class’s constructor.As customerRequestDetails and customerRequestDao

Page 164: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

beans are of type CustomerRequestDetails and CustomerRequestDao, Spring automatically injectsinstancesofthesebeansintocustomerRequestServicebean.

IfSpringdoesn’t findanybean in theApplicationContextwhose typematches theconstructorargumenttype, the constructor argument is not set. If Spring findsmultiple beans in theApplicationContext thatmatch 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 the primarycandidateforautowiringbysettingvalueofprimaryattributeof<bean>elementtotrue.

byNameIf you specify autowire attribute’s value as byName, Spring autowires bean properties based on theirnames. For instance, if a bean A defines a property named x, Spring finds a bean named x in theApplicationContextandinjectsitintobeanA.Let’slookatanexampleusageofbyNameautowiringintheMyBankapplication.

ThefollowingexamplelistingshowstheMyBankapplication’sFixedDepositServiceImplclass:

Examplelisting4-28–FixedDepositServiceImplclassProject–ch04-bankapp-autowiringSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;importsample.spring.chapter04.bankapp.dao.FixedDepositDao;importsample.spring.chapter04.bankapp.domain.FixedDepositDetails;publicclassFixedDepositServiceImplimplementsFixedDepositService{privateFixedDepositDaomyFixedDepositDao;publicvoidsetMyFixedDepositDao(FixedDepositDaomyFixedDepositDao){this.myFixedDepositDao=myFixedDepositDao;}.....}

The above example listing shows that FixedDepositServiceImpl class defines a property namedmyFixedDepositDaooftypeFixedDepositDao.

The following example listing shows bean definitions for FixedDepositServiceImpl andFixedDepositDaoImpl(animplementationofFixedDepositDaointerface)classes:

Examplelisting4-29–applicationContext.xml-byNameautowiringProject–ch04-bankapp-autowiringSourcelocation-src/main/resources/META-INF/spring

<beanid="FixedDepositService"class="sample.spring.chapter04.bankapp.service.FixedDepositServiceImpl"autowire="byName"/>

Page 165: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="myFixedDepositDao"class="sample.spring.chapter04.bankapp.dao.FixedDepositDaoImpl"/>

Intheaboveexamplelisting,FixedDepositServicebeandefinitionspecifiesautowireattribute’svalueasbyName, which means properties of FixedDepositService bean are automatically resolved by Springbasedontheirnames.Inlisting4-28,wesawthattheFixedDepositServiceImplclassdefinesapropertynamed myFixedDepositDao; therefore, Spring looks for a bean named myFixedDepositDao in theApplicationContext and injects it into FixedDepositService bean. In the above example listing,myFixedDepositDao bean definition represents the FixedDepositDaoImpl class, which means that aninstance of FixedDepositDaoImpl is injected for property named myFixedDepositDao in theFixedDepositServicebean.

default/noIfyouspecifyautowireattribute’svalueasdefaultorno,autowiringfeatureisdisabledforthebean.AsSpring’s default behavior is to use no autowiring for beans, specifying autowire attribute’s value asdefaultmeansnoautowiringwillbeperformedforthebean.YoucanexplicitlyspecifythatabeanmustnotuseSpring’sautowiringfeaturebyspecifyingautowireattribute’svalueasno.

NOTEYoucanchangethedefaultautowiringbehaviorofbeansbysettingthedefault-autowireattributeof<beans>element.For instance, ifyou setdefault-autowireattribute’svalue tobyType, it effectivelymeanssettingvalueofautowireattributeofallthe<bean>elementsintheapplicationcontextXMLfiletobyType.Youshouldnotethatifa<bean>element’sautowireattributespecifiesadifferentvaluethanthe<beans>element’sdefault-autowireattribute,the<bean>element’sautowireattributevalueappliestothebean.

The following example listing shows the bean definition for the MyBank application’sCustomerRegistrationServiceImplclassthatspecifiesautowireattribute’svalueasno:

Examplelisting4-30–applicationContext.xml-noautowiringProject–ch04-bankapp-autowiringSourcelocation-src/main/resources/META-INF/spring

<beanid="customerRegistrationService_"class="sample.spring.chapter04.bankapp.service.CustomerRegistrationServiceImpl"scope="prototype"autowire="no"/>

Example listing 4-24 showed that the CustomerRegistrationServiceImpl class definescustomerRegistrationDetails(oftypeCustomerRegistrationDetails)andcustomerRegistrationDao(oftypeCustomerRegistrationDao) properties. As the autowire attribute’s value is specified as no forcustomerRegistrationService_bean,autowiringisdisabledforcustomerRegistrationService_bean.Thismeans that the customerRegistrationDetails and customerRegistrationDao properties ofcustomerRegistrationService_beanarenotsetbySpring.

So far in this sectionwe have seen different ways inwhich bean dependencies can be autowired bySpring.Let’snowlookathowwecanmakeabeanunavailable forautowiringpurposesusing<bean>element’sautowire-candidateattribute.

Page 166: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

MakingbeansunavailableforautowiringThedefaultbehavioroftheSpringcontaineristomakebeansavailableforautowiring.Youcanmakeabeanunavailabletootherbeansforautowiringpurposesbysettingautowire-candidateattribute’svaluetofalse.

In MyBank application, the AccountStatementServiceImpl class defines a property of typeAccountStatementDao.ThefollowingexamplelistingshowstheAccountStatementServiceImplclass:

Examplelisting4-31–AccountStatementServiceImplclassProject–ch04-bankapp-autowiringSourcelocation-src/main/java/sample/spring/chapter04/bankapp/servicepackagesample.spring.chapter04.bankapp.service;importsample.spring.chapter04.bankapp.dao.AccountStatementDao;importsample.spring.chapter04.bankapp.domain.AccountStatement;publicclassAccountStatementServiceImplimplementsAccountStatementService{privateAccountStatementDaoaccountStatementDao;publicvoidsetAccountStatementDao(AccountStatementDaoaccountStatementDao){this.accountStatementDao=accountStatementDao;}.....}

The following example listing shows bean definitions for AccountStatementServiceImpl andAccountStatementDaoImpl(animplementationofAccountStatementDaointerface)classes:

Examplelisting4-32–applicationContext.xml-autowire-candidateattributeProject–ch04-bankapp-autowiringSourcelocation-src/main/resources/META-INF/spring

<beanid="accountStatementService"class="sample.spring.chapter04.bankapp.service.AccountStatementServiceImpl"autowire="byType"/><beanid="accountStatementDao"class="sample.spring.chapter04.bankapp.dao.AccountStatementDaoImpl"autowire-candidate="false"/>

In theaboveexample listing, theaccountStatementServicebeandefinitionspecifiesautowireattribute’svalueasbyType,whichmeansAccountStatementDaoproperty typeofaccountStatementServicebean isautowiredby type.AsaccountStatementDaobean isof typeAccountStatementDao,youmight think thatSpring will inject accountStatementDao bean instance into accountStatementService bean. But, Springwon’t consider accountStatementDao bean for autowiring purposes because the accountStatementDaobeandefinitionspecifiesautowire-candidateattribute’svalueasfalse.

Page 167: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

NOTEYoushouldnotethatabeanthatisunavailabletootherbeansforautowiringpurposescanitselfmakeuseofSpring’sautowiringfeaturetoautomaticallyresolveit’sdependencies.

As mentioned earlier, the default behavior of the Spring container is to make beans available forautowiring purposes. To make only only a select set of beans available for autowiring purposes, set<beans> element’s default-autowire-candidates attribute. The default-autowire-candidates attributespecifies a bean name pattern, and only beans whose names match the specified pattern are madeavailable for autowiring. The followingexample listing showsanexampleusageofdefault-autowire-candidatesattribute:

Examplelisting4-33–default-autowire-candidatesattributeexample

<beansdefault-autowire-candidates="*Dao">.....<beanid="customerRequestDetails"class="sample.spring.chapter04.bankapp.domain.CustomerRequestDetails"scope="prototype"autowire-candidate="true"/><beanid="customerRequestDao"class="sample.spring.chapter04.bankapp.dao.CustomerRequestDaoImpl"/><beanid="customerRegistrationDao"class="sample.spring.chapter04.bankapp.dao.CustomerRegistrationDaoImpl"/>.....</beans>

Intheaboveexamplelisting,default-autowire-candidatesvalue isset to*Dao,whichmeans thatbeanswhose names end with Dao (like customerRequestDao and customerRegistrationDao beans) will beavailable for autowiring purposes. If a bean name doesn’tmatch the pattern specified by the default-autowire-candidates attribute (like customerRequestDetails bean), you can still make it available forautowiringpurposesbysettingtheautowire-candidateattributeof thecorresponding<bean>element totrue.

Let’snowlookatlimitationsofusingautowiringinapplications.

AutowiringlimitationsWesawthatautowiringfeaturesavestheefforttoexplicitlyspecifybeandependenciesusing<property>and<constructor-arg>elements.Thedownsidesofusingautowiringfeatureare:

·Youcan’tuseautowiringtosetpropertiesorconstructorargumentsthatareofsimpleJavatypes(like int, long,boolean,String,Date, and soon).Youcanautowirearrays, typedcollectionsandmapsiftheautowireattribute’svalueissettobyTypeorconstructor.

· Asbeandependencies are automatically resolvedbySpring, it results inhiding theoverallstructureoftheapplication.Ifyouuse<property>and<constructor-arg>elementstospecifybeandependencies,itresultsinexplicitlydocumentingtheoverallstructureoftheapplication.Youcaneasily understand and maintain an application in which bean dependencies are explicitlydocumented.Forthisreason,itisnotrecommendedtouseautowiringinlargeapplications.

Page 168: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global
Page 169: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

4-7SummaryInthischapter,welookedathowSpringcaterstodifferentdependencyinjectionscenarios.Welookedathow you can use ApplicationContextAware interface, <replaced-method> and <lookup-method> sub-elementsof<bean>element toprogrammatically retrieveabean instance from theApplicationContext.We also looked at how Spring’s autowiring feature can save the effort for explicitly specifying beandependencies in the application contextXML file. In the next chapter,we’ll look at how to customizebeansandbeandefinitions.

Page 170: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter5-Customizingbeansandbeandefinitions

Page 171: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

5-1IntroductionSofarinthisbookwehaveseenexamplesinwhichtheSpringcontainercreatedabeaninstancebasedonthebeandefinitionspecifiedintheapplicationcontextXMLfile.Inthischapter,we’llgoastepfurtherandlookat:

·howtoincorporatecustominitializationanddestructionlogicforabean·howtointeractwithanewlycreatedbeaninstancebyimplementingSpring’sBeanPostProcessor

interface·howtomodifybeandefinitionsbyimplementingSpring’sBeanFactoryPostProcessorinterface

Page 172: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

5-2Customizingbean’sinitializationanddestructionlogicWe saw in earlier chapters that the Spring container is responsible for creating a bean instance andinjectingitsdependencies.Aftercreatingabeaninstancebyinvokingtheconstructorofthebeanclass,theSpringcontainersetsbeanpropertiesby invokingbean’ssettermethods. Ifyouwant toexecutecustominitialization logic (like opening a file, creating a database connection, and so on) after the beanpropertiesaresetbutbeforethebeaniscompletelyinitializedbytheSpringcontainer,youcandosobyspecifyingthenameoftheinitializationmethodasthevalueofinit-methodattributeof<bean>element.Similarly, ifyouwant to execute customcleanup logicbefore theSpringcontainer containing thebeaninstance is destroyed, you can specify the name of the cleanup method as the value of destroy-methodattributeof<bean>element.

IMPORT chapter 5/ch05-bankapp-customization (This project shows the MyBank application thatuses <bean> element’s init-method and destroy-method elements to specify custom initialization anddestructionmethods.Totestwhethertheinitializationmethodisexecuted,executethemainmethodoftheBankApp class of this project. To test whether the destruction method is executed, execute the mainmethodoftheBankAppWithHookclassofthisproject.)

The following example listing shows the MyBank’s FixedDepositDaoImpl class that defines aninitializationmethodnamedinitializeDbConnectionforobtainingconnectiontoMyBank’sdatabase,andadestructionmethodnamedreleaseDbConnectionforreleasingtheconnection:

Examplelisting5-1–FixedDepositDaoImplclass-CustominitializationanddestructionlogicProject–ch05-bankapp-customizationSourcelocation-src/main/java/sample/spring/chapter05/bankapp/daopackagesample.spring.chapter05.bankapp.dao;publicclassFixedDepositDaoImplimplementsFixedDepositDao{privatestaticLoggerlogger=Logger.getLogger(FixedDepositDaoImpl.class);privateDatabaseConnectionconnection;publicFixedDepositDaoImpl(){logger.info("FixedDepositDaoImpl'sconstructorinvoked");}publicvoidinitializeDbConnection(){logger.info("FixedDepositDaoImpl’sinitializeDbConnectionmethodinvoked");connection=DatabaseConnection.getInstance();}publicbooleancreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){logger.info("FixedDepositDaoImpl’screateFixedDepositmethodinvoked");//--savethefixeddepositsandthenreturntruereturntrue;}

Page 173: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicvoidreleaseDbConnection(){logger.info("FixedDepositDaoImpl’sreleaseDbConnectionmethodinvoked");connection.releaseConnection();}}

In theaboveexample listing, theDatabaseConnectionobject isused for interactingwith theMyBank’sdatabase. FixedDepositDaoImpl class defines an initializeDbConnection method that initializes theDatabaseConnection object, which is later used by the createFixedDeposit method for saving fixeddepositdetailsintheMyBank’sdatabase.

The following example listing shows the MyBank’s FixedDepositServiceImpl class that usesFixedDepositDaoImplinstancetocreatenewfixeddeposits:

Examplelisting5-2–FixedDepositServiceImplclassProject–ch05-bankapp-customizationSourcelocation-src/main/java/sample/spring/chapter05/bankapp/servicepackagesample.spring.chapter05.bankapp.service;publicclassFixedDepositServiceImplimplementsFixedDepositService{privatestaticLoggerlogger=Logger.getLogger(FixedDepositServiceImpl.class);privateFixedDepositDaomyFixedDepositDao;publicvoidsetMyFixedDepositDao(FixedDepositDaomyFixedDepositDao){logger.info("FixedDepositServiceImpl'ssetMyFixedDepositDaomethodinvoked");this.myFixedDepositDao=myFixedDepositDao;}@OverridepublicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{//--createfixeddepositmyFixedDepositDao.createFixedDeposit(fixedDepositDetails);}}

The above example listing shows that the FixedDepositDaoImpl instance is a dependency ofFixedDepositServiceImpl, and is passed as an argument to the setMyFixedDepositDao setter-method.And, if FixedDepositServiceImpl’s createFixedDeposit method is invoked, it results in invocation ofFixedDepositDaoImpl’screateFixedDepositmethod.

The following example listing shows bean definitions for FixedDepositDaoImpl andFixedDepositServiceImplclasses:

Examplelisting5-3–applicationContext.xml–usageofinit-methodanddestroy-methodattributesProject–ch05-bankapp-customizationSourcelocation-src/main/resources/META-INF/spring

Page 174: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beans.....><beanid="FixedDepositService"class="sample.spring.chapter05.bankapp.service.FixedDepositServiceImpl"><propertyname="myFixedDepositDao"ref="myFixedDepositDao"/></bean><beanid="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 FixedDepositDaoImplclass specifies initializeDbConnection and releaseDbConnection as the values of init-method anddestroy-methodattributes,respectively.

NOTEItisimportanttonotethattheinitializationanddestructionmethodsspecifiedbytheinit-methodanddestroy-methodattributesof<bean>elementmustnotacceptanyarguments,butcanbedefinedtothrowexceptions.

The following example listing shows BankApp class whose main method retrievesFixedDepositServiceImplinstancefromtheApplicationContextand invokesFixedDepositServiceImpl’screateFixedDepositmethod:

Examplelisting5-4–BankAppclassProject–ch05-bankapp-customizationSourcelocation-src/main/java/sample/spring/chapter05/bankapppackagesample.spring.chapter05.bankapp;publicclassBankApp{publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,12,"[email protected]"));}}

IfyounowexecutetheBankApp’smainmethod,you’llseethefollowingoutputontheconsole:FixedDepositDaoImpl'sconstructorinvokedFixedDepositDaoImpl’sinitializeDbConnectionmethodinvokedFixedDepositServiceImpl'ssetMyFixedDepositDaomethodinvokedFixedDepositDaoImpl’screateFixedDepositmethodinvoked

TheaboveoutputshowsthattheSpringcontainerfirstcreatesFixedDepositDaoImpl’sinstance,andthen

Page 175: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

invokes initializeDbConnection method. After the invocation of initializeDbConnection method, theFixedDepositDaoImplinstanceisinjectedintotheFixedDepositServiceImplinstance.ThisshowsthattheSpringcontainerinjectsadependency(theFixedDepositDaoImplinstance)intothedependentbean(theFixedDepositServiceImpl instance)after the initializationmethodof the dependency is invokedby theSpringcontainer.

YoumayhavenoticedthattheoutputfromexecutingBankApp’smainmethoddidn’tcontainthefollowingmessage:FixedDepositDaoImpl’sreleaseDbConnectionmethodinvoked(referFixedDepositDaoImpl’sreleaseDbConnection method in example listing 5-1). This means that the FixedDepositDaoImpl’sreleaseDbConnection method was not called by the Spring container when BankApp’s main methodexited.Inarealworldapplicationdevelopmentscenario,thismeansthatthedatabaseconnectionheldbyFixedDepositDaoImpl instance is never released. Let’s now see how you canmake Spring gracefullydestroysingleton-scopedbeaninstancesbycallingthecleanupmethodspecifiedbythe<bean>element’sdestroy-methodattribute.

MakingSpringinvokecleanupmethodspecifiedbythedestory-methodattributeThe web version of ApplicationContext implementation is represented by Spring’sWebApplicationContextobject.WebApplicationContextimplementationhasthenecessarylogictoinvokethecleanupmethod(specifiedbythedestroy-methodattribute)ofsingleton-scopedbeaninstancesbeforethewebapplicationisshutdown.

NOTETheapproachdescribedinthissectiononmakingSpringgracefullydestroysingleton-scopedbeaninstancesbycallingthecleanupmethodisspecifictostandaloneapplications.

ThefollowingexamplelistingshowstheBankAppWithHookclass(amodifiedversionofBankAppclassshown inexample listing5-4)whosemainmethod ensures that cleanupmethods (specifiedby<bean>element’sdestroy-methodattribute)ofallsingleton-scopedbeansregisteredwiththeSpringcontainerareinvokedwhenthemainmethodexits:

Examplelisting5-5–BankAppWithHookclass–registeringashutdownhookwithJVMProject–ch05-bankapp-customizationSourcelocation-src/main/java/sample/spring/chapter05/bankapppackagesample.spring.chapter05.bankapp;publicclassBankAppWithHook{publicstaticvoidmain(Stringargs[])throwsException{AbstractApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");context.registerShutdownHook();FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,12,"[email protected]"));}}

Page 176: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Spring’s AbstractionApplicationContext class implements ApplicationContext interface and defines aregisterShutdownHook method that registers a shutdown hook with the JVM. The shutdown hook isresponsibleforclosingtheApplicationContextwhentheJVMisshutdown.Intheaboveexamplelisting,you’ll notice that the ClassPathXmlApplicationContext instance is assigned toAbstractionApplicationContext type, and theAbstractionApplicationContext’s registerShutdownHook iscalledtoregisterashutdownhookwiththeJVM.WhentheBankAppWithHook’smainmethodexists,theshutdownhookdestroysallcachedsingletonbeaninstancesandclosestheApplicationContextinstance.

IfyouexecuteBankAppWithHook’smainmethodofch05-bankapp-customizationproject,you’llsee thefollowingoutputontheconsole:

FixedDepositDaoImpl'sconstructorinvokedFixedDepositDaoImpl’sinitializeDbConnectionmethodinvokedFixedDepositServiceImpl'ssetMyFixedDepositDaomethodinvokedFixedDepositDaoImpl'sreleaseDbConnectionmethodinvoked

Themessage ‘FixedDepositDaoImpl'sreleaseDbConnectionmethod invoked’on theconsoleconfirmsthat the FixedDepositDaoImpl’s releaseDbConnection method (refer FixedDepositDaoImpl’sreleaseDbConnection method in example listing 5-1) was invoked. As you can see, registering ashutdown hook with the JVM resulted in invocation of the cleanup method of the singleton-scopedmyFixedDepositDaobean(correspondingtotheFixedDepositDaoImplclass).

Let’snowlookattheimpactofshutdownhookonprototype-scopedbeans.

Cleanupmethodsandprototype-scopedbeansIn case of prototype-scoped beans, destroy-method attribute is ignored by the Spring container. Thedestroy-methodattribute is ignoredbecause theSpringcontainerexpects that theobject that fetches theprototype-scoped bean instance from the ApplicationContext is responsible for explicitly calling thecleanupmethodontheprototype-scopedbeaninstance.

NOTELifecyclesofprototype-andsingleton-scopedbeansaresame,exceptthattheSpringcontainerwillnotcallthecleanupmethod(specifiedbythedestroy-initattribute)oftheprototype-scopedbeaninstance.

Let’s now look at howyou can specify default initialization and destructionmethods for all the beanscontainedintheapplicationcontextXMLfile.

SpecifyingdefaultbeaninitializationanddestructionmethodsforallbeansYoucanusethedefault-init-methodanddefault-destroy-methodattributesof<beans>elementtospecifydefaultinitializationanddestructionmethodsforbeans,asshowninthefollowingexamplelisting:

Examplelisting5-6–default-init-methodanddefault-destroy-methodattributes<beans.....default-init-method="initialize"default-destroy-method="release"><beanid="A"class="....."init-method="initializeService"/><beanid="B"class="....."/></beans>

If multiple beans define initialization or cleanupmethods with the same name, it makes sense to use

Page 177: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

default-init-methodanddefault-destroy-methodattributes.Byspecifyinginit-methodanddestroy-methodattributes,a<bean>elementcanoverridethevaluesspecifiedby<beans>element’sdefault-init-methodanddefault-destroy-methodattributes.For instance, in theaboveexample listing,beanAspecifies init-method attribute value as initializeService, which means initializeService method (and not initializemethodspecifiedbythedefault-init-methodattributeof<beans>element) is theinitializationmethodofbeanA.

Instead of using init-method and destroy-method attributes of <bean> element to specify custominitialization and destruction methods, you can use Spring’s InitializingBean and DisposableBeanlifecycleinterfaces.

InitializingBeanandDisposableBeanlifecycleinterfacesAbeanthatimplementslifecycleinterfaces,likeApplicationContextAware(refersection4-5ofchapter4),InitializingBeanandDisposableBean,receivescallbacksfromtheSpringcontainertogiveachancetothe bean instance to perform some action, or to provide bean instance with some information. Forinstance, if a bean implements ApplicationContextAware interface, container invokessetApplicationContext method of the bean instance to provide the bean with a reference to theApplicationContextinwhichthebeanisdeployed.

InitializingBean interface defines an afterPropertiesSetmethod that is invoked by the Spring containerafterthebeanpropertiesareset.BeansperforminitializationworkintheafterPropertiesSetmethod,likeobtainingconnectiontoadatabase,openingaflatfileforreading,andsoon.DisposableBean interfacedefinesadestroymethodthatisinvokedbytheSpringcontainerwhenthebeaninstanceisdestroyed.

NOTE As with the ApplicationContextAware lifecycle interface, beans should avoid implementingInitializingBeanandDisposableBeaninterfacesbecauseitcouplesapplicationcodewithSpring.

Let’s now look at JSR 250’s @PostConstruct and @PreDestroy annotations for specifying beaninitializationanddestructionmethods.

JSR250’s@PostConstructand@PreDestroyannotationsJSR250(CommonAnnotationsfortheJavaPlatform)definesstandardannotationsthatareusedacrossdifferent Java technologies. JSR 250’s @PostConstruct and @PreDestroy annotations identifyinitialization and destruction methods of an object. A bean class in Spring can set a method as aninitializationmethodbyannotatingitwith@PostConstruct,andsetamethodasadestructionmethodbyannotatingitwith@PreDestroyannotation.

NOTEReferJSR250homepage(http://jcp.org/en/jsr/detail?id=250)formoredetails.

IMPORTchapter5/ch05-bankapp-jsr250 (Thisproject shows theMyBankapplication thatuses JSR250’s @PostConstruct and @PreDestroy annotations to identify custom initialization and destructionmethods,respectively.Totestwhethertheinitializationmethodisexecuted,executethemainmethodoftheBankAppclassof thisproject.Totestwhether thedestructionmethodisexecuted,execute themainmethodoftheBankAppWithHookclassofthisproject.)

ThefollowingexamplelistingshowstheFixedDepositDaoImplclassofch05-bankapp-jsr250projectthatuses@PostConstructand@PreDestroyannotations:

Page 178: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting5-7–FixedDepositDaoImplclass-@PostConstructand@PreDestroyannotationsProject–ch05-bankapp-jsr250Sourcelocation-src/main/java/sample/spring/chapter05/bankapp/daopackagesample.spring.chapter05.bankapp.dao;importjavax.annotation.PostConstruct;importjavax.annotation.PreDestroy;publicclassFixedDepositDaoImplimplementsFixedDepositDao{privateDatabaseConnectionconnection;.....@PostConstructpublicvoidinitializeDbConnection(){logger.info("FixedDepositDaoImplísinitializeDbConnectionmethodinvoked");connection=DatabaseConnection.getInstance();}.....@PreDestroypublicvoidreleaseDbConnection(){logger.info("FixedDepositDaoImpl'sreleaseDbConnectionmethodinvoked");connection.releaseConnection();}}

In the above example listing, the FixedDepositDaoImpl class uses@PostConstruct and @PreDestroyannotations to identify initializationanddestructionmethods.Youshouldnote that@PostConstruct and@PreDestroyannotationsarenotspecifictoSpring.

NOTEJavaSE6providesannotationsdefinedbyJSR250;ifyouareusingJavaSE6orlater,youdon’tneedtoincludeJSR250JARfileinyourapplication’sclasspath.IfyouareusingJavaSE5,youneedtoincludeJSR250JARfileandtherelatedJARfilesinyourapplication’sclasspath.

Touse@PostConstructand@PreDestroyannotationsinyourapplication,youneedtoconfigureSpring’sCommonAnnotationBeanPostProcessorclassintheapplicationcontextXMLfile,asshownhere:

Examplelisting5-8–applicationContext.xml–CommonAnnotationBeanPostProcessorconfigurationProject–ch05-bankapp-jsr250Sourcelocation-src/main/resources/META-INF/spring<beans.....><beanid="FixedDepositService"class="sample.spring.chapter05.bankapp.service.FixedDepositServiceImpl"><propertyname="myFixedDepositDao"ref="myFixedDepositDao"/></bean>

Page 179: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="myFixedDepositDao"class="sample.spring.chapter05.bankapp.dao.FixedDepositDaoImpl"/><beanclass="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/></beans>

CommonAnnotationBeanPostProcessor implements Spring’s BeanPostProcessor interface (explained inthenextsection),andisresponsibleforprocessingJSR250annotations.

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 atcreationanddestructionofFixedDepositDaoImplinstance,respectively.

We’llnowlookatSpring’sBeanPostProcessor interface thatallowsyouto interactwithnewlycreatedbeaninstancesbeforeoraftertheyareinitializedbytheSpringcontainer.

Page 180: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

5-3 Interacting with newly created bean instances usingBeanPostProcessorBeanPostProcessor is used to interact with newly created bean instances before and/or after theirinitialization method (refer section 5-2) is invoked by the Spring container. You can useBeanPostProcessortoexecutecustomlogicbeforeand/orafterbean’sinitializationmethodisinvokedbytheSpringcontainer.

NOTEAbeanthatimplementsSpring’sBeanPostProcessorinterfaceisaspecialbeantype;theSpringcontainerautomaticallydetectsandexecutesaBeanPostProcessorbean.

BeanPostProcessorinterfacedefinesthefollowingmethods:

· ObjectpostProcessBeforeInitialization(Object bean, String beanName) – thismethod isinvokedbeforetheinitializationmethodofabeaninstanceisinvoked

· Object postProcessAfterInitialization(Object bean, String beanName) – this method isinvokedaftertheinitializationmethodofabeaninstanceisinvoked

BeanPostProcessor’smethodsacceptnewlycreatedbeaninstanceanditsnameasarguments,andreturnthesameormodifiedbeaninstance.Forinstance,ifyouhaveconfiguredaFixedDepositDaoImplclassasabeanwithidvalueasmyFixedDepositDaointheapplicationcontextXMLfile(referexamplelisting5-8), the BeanPostProcessor’s methods receive an instance of FixedDepositDaoImpl class andmyFixedDepositDaostringvalueasarguments.TheBeanPostProcessor’smethodsmayreturntheoriginalbean instance as-is or theymaymodify the bean instance or theymay return an object thatwraps theoriginalbeaninstance.

You configure aBeanPostProcessor implementation in the application contextXML file like any otherSpringbean.Springcontainer automaticallydetectsbeans that implementBeanPostProcessor interface,andcreates their instancebefore creating instance of anyother beandefined in the application contextXML file. Once the BeanPostProcessor beans are created, the Spring container invokes eachBeanPostProcessor’spostProcessBeforeInitializationandpostProcessAfterInitializationmethodsforeachbeaninstancecreatedbytheSpringcontainer.

Let’s say that you have defined a singleton-scoped bean ABean and a BeanPostProcessor bean,MyBeanPostProcessor, in theapplicationcontextXMLfile.Figure5-1 showsa sequencediagram thatdepictsthesequenceinwhichMyBeanPostProcessor’smethodsareinvokedbytheSpringcontainer.

Theinitmethodcallinthesequencediagramrepresentsacalltotheinitializationmethodofthebean.Thesequence diagram shows that the MyBeanPostProcessor instance is created before the ABean beaninstance is created. As a BeanPostProcessor implementation is configured like any other bean, ifMyBeanPostProcessordefinesaninitializationmethod,containerinvokestheinitializationmethodoftheMyBeanPostProcessorinstance.AfterABean’sinstanceiscreated,settermethodsoftheABean instanceareinvokedbytheSpringcontainertosatisfyitsdependencies,andtoprovidethebeaninstancewiththerequiredconfigurationinformation.Afterpropertiesareset,butbeforeABean’s initializationmethod isinvoked, the Spring container invokesMyBeanPostProcessor’s postProcessBeforeInitializationmethod.AfterABean’s initialization method is invoked,MyBeanPostProcessor’s postProcessAfterInitializationmethodiscalledbytheSpringcontainer.

Page 181: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure 5-1 – The Spring container invokes MyBeanPostProcessor’s methods before and after theinitializationofABean’sinitializationmethod

It’s only after invocation of postProcessAfterInitialization method, a bean instance is consideredcompletely initialized by the Spring container. For instance, if aBBean bean is dependent onABean,container will inject ABean instance into BBean only after MyBeanPostProcessor’spostProcessAfterInitializationisinvokedforbothABeanandBBeaninstances.

YoushouldnotethatifthebeandefinitionforaBeanPostProcessorbeanspecifiesthatitshouldbelazilycreated (refer <bean> element’s lazy-init attribute or <beans> element’s default-lazy-init attribute insection 2-5 of chapter 2), the Spring container ignores lazy initialization configuration and creates theBeanPostProcessor bean instance before creating instances of singleton-scoped beans defined in theapplicationcontextXMLfile.Youshouldnote that thebeans that implementBeanFactoryPostProcessorinterface (explained in section 5-4) are created before the beans that implement BeanPostProcessorinterface.

Let’snowlookatsomeexamplescenariosinwhichyoucanuseSpring’sBeanPostProcessor.

IMPORT chapter 5/ch05-bankapp-beanpostprocessor (This project shows the MyBank applicationthat uses BeanPostProcessor implementations to validate bean instances and to resolve beandependencies.ToverifythattheBeanPostProcessorimplementationsfunctioncorrectly,executethemainmethodoftheBankAppclassofthisproject.)

BeanPostProcessorexample–ValidatingbeaninstancesInaSpringapplication,youmaywant toverify thatabeaninstanceisconfiguredcorrectlybeforeit isinjectedintodependentbeansoraccessedbyotherobjectsintheapplication.Let’sseehowwecanuseaBeanPostProcessor implementation to give an opportunity to each bean instance to validate itsconfigurationbeforethebeaninstanceismadeavailabletodependentbeansorotherapplicationobjects.

ThefollowingexamplelistingshowstheMyBank’sInstanceValidatorinterfacethatmustbeimplementedbybeanswhoseconfigurationwewanttovalidateusingaBeanPostProcessorimplementation:

Page 182: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting5-9–InstanceValidatorinterfaceProject–ch05-bankapp-beanpostprocessorSourcelocation-src/main/java/sample/spring/chapter05/bankapp/common

packagesample.spring.chapter05.bankapp.common;publicinterfaceInstanceValidator{voidvalidateInstance();}

InstanceValidatorinterfacedefinesavalidateInstancemethodthatverifieswhetherthebeaninstancewascorrectly initialized or not. We’ll soon see that the validateInstance method is invoked by aBeanPostProcessorimplementation.

Thefollowingexample listingshows theFixedDepositDaoImplclass that implements InstanceValidatorinterface:

Examplelisting5-10–FixedDepositDaoImplclassProject–ch05-bankapp-beanpostprocessorSourcelocation-src/main/java/sample/spring/chapter05/bankapp/dao

packagesample.spring.chapter05.bankapp.dao;importorg.apache.log4j.Logger;importsample.spring.chapter05.bankapp.common.InstanceValidator;publicclassFixedDepositDaoImplimplementsFixedDepositDao,InstanceValidator{privatestaticLoggerlogger=Logger.getLogger(FixedDepositDaoImpl.class);privateDatabaseConnectionconnection;publicFixedDepositDaoImpl(){logger.info("FixedDepositDaoImpl'sconstructorinvoked");}publicvoidinitializeDbConnection(){logger.info("FixedDepositDaoImplísinitializeDbConnectionmethodinvoked");connection=DatabaseConnection.getInstance();}@OverridepublicvoidvalidateInstance(){logger.info("ValidatingFixedDepositDaoImplinstance");if(connection==null){logger.error("FailedtoobtainDatabaseConnectioninstance");}}}

Page 183: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Intheaboveexamplelisting,theinitializeDbConnectionmethodistheinitializationmethodthatretrievesaninstanceofDatabaseConnectionbycallinggetInstancestaticmethodofDatabaseConnectionclass.Theconnection attribute is null if FixedDepositDaoImpl instance fails to retrieve an instance ofDatabaseConnection. If connection attribute is null, the validateInstancemethod logs an errormessageindicating that the FixedDepositDaoImpl instance is not correctly initialized. As theinitializeDbConnection initializationmethod sets the value of connection attribute, the validateInstancemethod must be invoked after the initializeDbConnection method. In a real world applicationdevelopmentscenario,ifabeaninstanceisnotconfiguredcorrectly,thevalidateInstancemethodmaytakesome corrective action or throw a runtime exception to stop the application from starting up. Forsimplicity, the validateInstance method logs an error message if a bean instance is not configuredcorrectly.

The following example listing shows the InstanceValidationBeanPostProcessor class that implementsSpring’sBeanPostProcessorinterface,andisresponsibleforinvokingvalidateInstancemethodofnewlycreatedbeans:

Examplelisting5-11–InstanceValidationBeanPostProcessorclassProject–ch05-bankapp-beanpostprocessorSourcelocation-src/main/java/sample/spring/chapter05/bankapp/postprocessor

packagesample.spring.chapter05.bankapp.postprocessor;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.config.BeanPostProcessor;importorg.springframework.core.Ordered;publicclassInstanceValidationBeanPostProcessorimplementsBeanPostProcessor,Ordered{privatestaticLoggerlogger=Logger.getLogger(InstanceValidationBeanPostProcessor.class);privateintorder;publicInstanceValidationBeanPostProcessor(){logger.info("CreatedInstanceValidationBeanPostProcessorinstance");}@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{logger.info("postProcessBeforeInitializationmethodinvoked");returnbean;}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{logger.info("postProcessAfterInitializationmethodinvoked");if(beaninstanceofInstanceValidator){

Page 184: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

((InstanceValidator)bean).validateInstance();}returnbean;}publicvoidsetOrder(intorder){this.order=order;}@OverridepublicintgetOrder(){returnorder;}}

The above example listing shows that the InstanceValidationBeanPostProcessor class implementsSpring’sBeanPostProcessorandOrderedinterfaces.ThepostProcessBeforeInitializationmethodsimplyreturnsthebeaninstancepassedtothemethod.InthepostProcessAfterInitializationmethod, if thebeaninstanceisfoundtobeoftypeInstanceValidator,thebeaninstance’svalidateInstancemethodisinvoked.Thismeans that if a bean implements InstanceValidator interface, InstanceValidationBeanPostProcessorcallsvalidateInstancemethodofthebeaninstanceafter theinitializationmethodofthebeaninstanceisinvokedbytheSpringcontainer.

The Ordered interface defines a getOrder method which returns an integer value. The integer valuereturned by the getOrdermethod determines the priority of a BeanPostProcessor implementation withrespect tootherBeanPostProcessor implementationsconfigured in theapplicationcontextXMLfile.ABeanPostProcessorwithhigherordervalueisconsideredata lowerpriority,and isexecutedafter theBeanPostProcessorimplementationswithlowerordervaluesareexecuted.Aswewanttheintegervaluereturnedby thegetOrdermethod tobe configured as abeanproperty, a setOrdermethod and anorderinstancevariablearedefinedintheInstanceValidationBeanPostProcessorclass.

ThefollowingexamplelistingshowsbeandefinitionsforInstanceValidationBeanPostProcessorclass:

Examplelisting5-12–InstanceValidationBeanPostProcessorbeandefinitionProject–ch05-bankapp-beanpostprocessorSourcelocation-src/main/resources/META-INF/spring<beanclass="…...bankapp.postprocessor.InstanceValidationBeanPostProcessor"><propertyname="order"value="1"/></bean>

In theabovebeandefinition,<bean>element’s idattribute isnot specifiedbecausewe typicallydon’twant InstanceValidationBeanPostProcessor to be a dependency of any other bean. The <property>elementsetsthevalueoforderpropertyto1.

Let’snowlookataBeanPostProcessorimplementationthatisusedforresolvingbeandependencies.

BeanPostProcessorexample–Resolvingbeandependencies

Page 185: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

In chapter 4, we saw that if a bean implements Spring’s ApplicationContextAware interface, it canprogrammatically obtain bean instances using ApplicationContext’s getBean method. ImplementingApplicationContextAwareinterfacecouplestheapplicationcodewithSpring,andforthatreasonitisnotrecommended to implement ApplicationContextAware interface. In this section, we’ll look at aBeanPostProcessorimplementationthatprovidesbeanswithanobjectthatwrapsanApplicationContextinstance, resulting in application code that isnot directly dependent onApplicationContextAware andApplicationContextinterfacesofSpring.

ThefollowingexamplelistingshowstheMyBank’sDependencyResolverinterfacethatisimplementedbybeanswhowanttoprogrammaticallyretrievetheirdependenciesfromtheApplicationContext:

Examplelisting5-13–DependencyResolverinterfaceProject–ch05-bankapp-beanpostprocessorSourcelocation-src/main/java/sample/spring/chapter05/bankapp/common

packagesample.spring.chapter05.bankapp.common;publicinterfaceDependencyResolver{voidresolveDependency(MyApplicationContextmyApplicationContext);}

DependencyResolverdefinesaresolveDependencymethodthatacceptsaMyApplicationContextobject–a wrapper around ApplicationContext object. We’ll soon see that the resolveDependency method isinvokedbyaBeanPostProcessorimplementation.

The following example listing shows the FixedDepositServiceImpl class that implementsDependencyResolverinterface:

Examplelisting5-14–FixedDepositServiceImplclassProject–ch05-bankapp-beanpostprocessorSourcelocation-src/main/java/sample/spring/chapter05/bankapp/service

packagesample.spring.chapter05.bankapp.service;importsample.spring.chapter05.bankapp.common.DependencyResolver;importsample.spring.chapter05.bankapp.common.MyApplicationContext;publicclassFixedDepositServiceImplimplementsFixedDepositService,DependencyResolver{privateFixedDepositDaofixedDepositDao;.....@OverridepublicvoidresolveDependency(MyApplicationContextmyApplicationContext){FixedDepositDao=myApplicationContext.getBean(FixedDepositDao.class);}}

TheFixedDepositServiceImplclassdefinesaFixedDepositDaoattributeoftypeFixedDepositDao.TheresolveDependency method is responsible for obtaining an instance of FixedDepositDao object from

Page 186: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

MyApplicationContext (a wrapper around Spring’s ApplicationContext object) and assigning it to theFixedDepositDaoattribute.

The following example listing shows that the DependencyResolutionBeanPostProcessor class invokesresolveDependencymethodonbeansthatimplementDependencyResolverinterface:

Examplelisting5-15–DependencyResolutionBeanPostProcessorclassProject–ch05-bankapp-beanpostprocessorSourcelocation-src/main/java/sample/spring/chapter05/bankapp/postprocessor

packagesample.spring.chapter05.bankapp.postprocessor;importorg.springframework.beans.factory.config.BeanPostProcessor;importorg.springframework.core.Ordered;importsample.spring.chapter05.bankapp.common.MyApplicationContext;publicclassDependencyResolutionBeanPostProcessorimplementsBeanPostProcessor,Ordered{privateMyApplicationContextmyApplicationContext;privateintorder;publicvoidsetMyApplicationContext(MyApplicationContextmyApplicationContext){this.myApplicationContext=myApplicationContext;}publicvoidsetOrder(intorder){this.order=order;}@OverridepublicintgetOrder(){returnorder;}@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{if(beaninstanceofDependencyResolver){((DependencyResolver)bean).resolveDependency(myApplicationContext);}returnbean;}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{

Page 187: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

returnbean;}}

The DependencyResolutionBeanPostProcessor class implements Spring’s BeanPostProcessor andOrdered interfaces. The myApplicationContext attribute (of type MyApplicationContext) represents adependency of DependencyResolutionBeanPostProcessor. The postProcessBeforeInitialization methodinvokes resolveDependency method on bean instances that implement DependencyResolver interface,passingtheMyApplicationContextobjectasargument.ThepostProcessAfterInitializationmethodsimplyreturnsthebeaninstancepassedtothemethod.

The following example listing shows the MyApplicationContext class that acts as a wrapper aroundSpring’sApplicationContextobject:

Examplelisting5-16–MyApplicationContextclassProject–ch05-bankapp-beanpostprocessorLocation-src/main/java/sample/spring/chapter05/bankapp/common

packagesample.spring.chapter05.bankapp.common;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;publicclassMyApplicationContextimplementsApplicationContextAware{privateApplicationContextapplicationContext;@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{this.applicationContext=applicationContext;}public<T>TgetBean(Class<T>klass){returnapplicationContext.getBean(klass);}}

The MyApplicationContext class implements Spring’s ApplicationContextAware interface to obtainreference to theApplicationContext object inwhich the bean is deployed. TheMyApplicationContextclass defines a getBean method that returns a bean instance with the given name from theApplicationContextinstance.

Thefollowingexample listingshowsthebeandefinitionsforDependencyResolutionBeanPostProcessorandMyApplicationContextclasses:

Examplelisting5-17–applicationContext.xmlProject–ch05-bankapp-beanpostprocessorSourcelocation-src/main/resources/META-INF/spring

Page 188: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanclass=".....postprocessor.DependencyResolutionBeanPostProcessor"><propertyname="myApplicationContext"ref="myApplicationContext"/><propertyname="order"value="0"/></bean><beanid="myApplicationContext"class=".....bankapp.common.MyApplicationContext"/>

The bean definition for DependencyResolutionBeanPostProcessor class shows that its order propertyvalue is set to 0. Example listing 5-12 showed that the InstanceValidationBeanPostProcessor’s orderpropertyvalueis1.As lowerorderpropertyvaluemeanshigherpriority, theSpringcontainerappliesDependencyResolutionBeanPostProcessor to a bean instance, followed by applying theInstanceValidationBeanPostProcessor.

ThefollowingexamplelistingshowsthemainmethodofBankAppclassthatchecksthefunctionalityofDependencyResolutionBeanPostProcessorandInstanceValidationBeanPostProcessor:

Examplelisting5-18–BankAppclassProject–bankapp-beanpostprocessorLocation-src/main/java/sample/spring/chapter05/bankapp

packagesample.spring.chapter05.bankapp;publicclassBankApp{publicstaticvoidmain(Stringargs[])throwsException{AbstractApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");context.registerShutdownHook();FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,12,"[email protected]"));.....}}

BankApp’smainmethodretrievesaninstanceofFixedDepositServicefromtheApplicationContextandexecutesFixedDepositService’screateFixedDepositmethod.WhenyouexecuteBankApp’smainmethod,you’llnoticethattheSpringcontainercreatesinstanceofDependencyResolutionBeanPostProcessorandInstanceValidationBeanPostProcessor beans before creating instance of any other bean defined in theapplication context XML file. And, the DependencyResolutionBeanPostProcessor (order value 0) isappliedtoanewlycreatedbeaninstancebeforetheInstanceValidationBeanPostProcessor(ordervalue1)isapplied.

You should note that the Spring container doesn’t apply a BeanPostProcessor implementation to otherBeanPostProcessor implementations. For instance, in the MyBank application,DependencyResolutionBeanPostProcessor’s postProcessBeforeInitialization andpostProcessAfterInitialization methods are not invoked by the Spring container when an instance of

Page 189: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

InstanceValidationBeanPostProcessoriscreated.

Let’s now look at the behavior of a BeanPostProcessor implementation for a bean that implementsFactoryBeaninterface.

BeanPostProcessorbehaviorforFactoryBeansIn section 3-9 of chapter 3,we discussed that a bean that implements Spring’s FactoryBean interfacerepresents a factory for creating bean instances. The question that youmight be asking at this time iswhether aBeanPostProcessor implementation applies to a FactoryBean implementation or to the beaninstances created by the FactoryBean implementation. Later in this section, we’ll see that aBeanPostProcessor’s postProcessBeforeInitialization and postProcessAfterInitialization methods areinvoked for a FactoryBean instance created by the Spring container. And, onlypostProcessAfterInitializationmethodisinvokedforbeaninstancescreatedbyaFactoryBean.

ThefollowingexamplelistingshowstheEventSenderFactoryBean(aFactoryBeanimplementation)classofMyBankapplicationthatcreatesinstancesofEventSenderbean:

Examplelisting5-19–EventSenderFactoryBeanclassProject–ch05-bankapp-beanpostprocessorLocation-src/main/java/sample/spring/chapter05/bankapp/factory

packagesample.spring.chapter05.bankapp.factory;importorg.springframework.beans.factory.FactoryBean;importorg.springframework.beans.factory.InitializingBean;publicclassEventSenderFactoryBeanimplementsFactoryBean<EventSender>,InitializingBean{.....@OverridepublicEventSendergetObject()throwsException{logger.info("getObjectmethodofEventSenderFactoryBeaninvoked");returnnewEventSender();}@OverridepublicClass<?>getObjectType(){returnEventSender.class;}@OverridepublicbooleanisSingleton(){returnfalse;}@OverridepublicvoidafterPropertiesSet()throwsException{

Page 190: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

logger.info("afterPropertiesSetmethodofEventSenderFactoryBeaninvoked");}}

EventSenderFactoryBean class implements Spring’s InitializingBean and FactoryBean interfaces. ThegetObject method returns an instance of EventSender object. As the isSingleton method returns false,EventSenderFactoryBean’s getObject method is invoked each time EventSenderFactoryBean receivesrequestforanEventSenderobject.

The following example listing shows the main method of BankApp class of ch05-bankapp-beanpostprocessorprojectthatretrievesEventSenderinstancesfromtheEventSenderFactoryBean:

Examplelisting5-20–BankAppclassProject–ch05-bankapp-beanpostprocessorLocation-src/main/java/sample/spring/chapter05/bankapp

packagesample.spring.chapter05.bankapp;publicclassBankApp{publicstaticvoidmain(Stringargs[])throwsException{AbstractApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");context.registerShutdownHook();.....context.getBean("eventSenderFactory");context.getBean("eventSenderFactory");}}

In the above example listing, theApplicationContext’sgetBeanmethod is called twice to retrieve twodistinct EventSender instances from the EventSenderFactoryBean. If you execute BankApp’s mainmethod,you’llseethefollowingmessagesprintedontheconsole:CreatedEventSenderFactoryBeanDependencyResolutionBeanPostProcessor'spostProcessBeforeInitializationmethodinvokedfor.....EventSenderFactoryBeanInstanceValidationBeanPostProcessor'spostProcessBeforeInitializationmethodinvokedfor.....EventSenderFactoryBeanafterPropertiesSetmethodofEventSenderFactoryBeaninvokedDependencyResolutionBeanPostProcessor'spostProcessAfterInitializationmethodinvokedfor.....EventSenderFactoryBeanInstanceValidationBeanPostProcessor'spostProcessAfterInitializationmethodinvokedforbean.....EventSenderFactoryBean

The above output shows that a BeanPostProcessor’s postProcessBeforeInitialization andpostProcessAfterInitializationmethodsareinvokedfortheEventSenderFactoryBeaninstancecreatedbytheSpringcontainer.

ExecutionofBankApp’smainmethodalsoshowsthefollowingoutputontheconsole:getObjectmethodofEventSenderFactoryBeaninvokedDependencyResolutionBeanPostProcessor'spostProcessAfterInitializationmethodinvokedfor.....EventSendergetObjectmethodofEventSenderFactoryBeaninvokedDependencyResolutionBeanPostProcessor'spostProcessAfterInitializationmethodinvokedfor.....EventSender

Page 191: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Theaboveoutput shows thatonly thepostProcessAfterInitializationmethodof aBeanPostProcessor isinvokedfortheEventSenderinstancecreatedbytheEventSenderFactoryBean.Ifyouwant,youcanmakemodificationstoanEventSenderinstanceinthepostProcessAfterInitializationmethod.Let’snowlookatSpring’sbuilt-inRequiredAnnotationBeanPostProcessorthatyoucanusetoensurethatrequired(ormandatory)beanpropertiesareconfiguredintheapplicationcontextXMLfile.

RequiredAnnotationBeanPostProcessorIf the setter-method for a bean property is annotated with Spring’s @Required annotation, Spring’sRequiredAnnotationBeanPostProcessor (a BeanPostProcessor implementation) checks if the beanpropertyisconfiguredintheapplicationcontextXMLfile.

NOTEYoushouldnotethattheRequiredAnnotationBeanPostProcessorisnotautomaticallyregisteredwiththeSpringcontainer,youneedtoregisteritexplicitlybydefiningitintheapplicationcontextXMLfile.

Thefollowingexamplelistingshowsanexampleusageof@Requiredannotation:

Examplelisting5-21–@Requiredannotationusageimportorg.springframework.beans.factory.annotation.Required;publicclassFixedDepositServiceImplimplementsFixedDepositService{privateFixedDepositDaofixedDepositDao;@RequiredpublicvoidsetFixedDepositDao(FixedDepositDaofixedDepositDao){this.fixedDepositDao=fixedDepositDao;}.....}

In the above example listing, the setFixedDepositDao setter-method for FixedDepositDao property isannotatedwith@Requiredannotation.IfyouhavedefinedRequiredAnnotationBeanPostProcessorintheapplicationcontextXMLfile,theRequiredAnnotationBeanPostProcessorwillcheckifyouhavespecifieda<property>element(orusedp-namespace)tosetthevalueofFixedDepositDaoproperty.Ifyouhaven’tconfiguredtheFixedDepositDaopropertyinthebeandefinitionfortheFixedDepositServiceImplclassinthe application context XML file, it’ll result in an exception. This shows that you can useRequiredAnnotationBeanPostProcessor to ensure that all bean instances in your application areconfiguredproperlyintheapplicationcontextXMLfile.

RequiredAnnotationBeanPostProcessor only ensures that a bean property is configured in the beandefinition.Itdoesn’tensurethattheconfiguredpropertyvalueiscorrect.Forinstance,youcanconfigureaproperty’s value as null, instead of a valid value. For this reason, beansmay still need to implementinitializationmethodstocheckifthepropertiesarecorrectlyset.

Let’s now look at Spring’s DestructionAwareBeanPostProcessor interface that is a sub-interface of

Page 192: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Spring’sBeanPostProcessorinterface.

DestructionAwareBeanPostProcessorSofarwehaveseenthataBeanPostProcessorimplementationisusedforinteractingwithnewlycreatedbean instances. In some scenarios you may also want to interact with a bean instance before it isdestroyed. To interact with a bean instance before it is destroyed, configure a bean that implementsSpring’s DestructionAwareBeanPostProcessor interface in the application context XML file.DestructionAwareBeanPostProcessor is a sub-interfaceofBeanPostProcessor interface and defines thefollowingmethod:

voidpostProcessBeforeDestruction(Objectbean,StringbeanName)

ThepostProcessBeforeDestructionmethodacceptsthebeaninstance,whichisabouttobedestroyedbythe Spring container, and its name as arguments. Spring container invokes thepostProcessBeforeDestructionmethodforeachsingleton-scopedbeaninstancebeforethebeaninstanceisdestroyedby theSpringcontainer.Usually, thepostProcessBeforeDestructionmethod isused to invokecustom destruction methods on the bean instances. It is important to note that thepostProcessBeforeDestructionmethodisnotcalledforprototype-scopedbeans.

We’llnowlookatSpring’sBeanFactoryPostProcessorinterface,whichallowsyoutomakemodificationstobeandefinitions.

Page 193: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

5-4ModifyingbeandefinitionsusingBeanFactoryPostProcessorSpring’sBeanFactoryPostProcessorinterfaceisimplementedbyclassesthatwanttomakemodificationsto bean definitions.ABeanFactoryPostProcessor is executedafter bean definitions are loaded by theSpringcontainer,butbeforeanybeaninstanceiscreated.ABeanFactoryPostProcessoriscreatedbeforeany other bean defined in the application context XML file, giving the BeanFactoryPostProcessor anopportunity to make modifications to bean definitions of other beans. You configure aBeanFactoryPostProcessorimplementationintheapplicationcontextXMLfilelikeanyotherSpringbean.

NOTEInsteadofbeandefinitions,ifyouwanttomodifyorinteractwithbeaninstances,useaBeanPostProcessor(refertosection5-3)andnotaBeanFactoryPostProcessor.

BeanFactoryPostProcessor interface defines a single method - postProcessBeanFactory. This methodacceptsanargumentoftypeConfigurableListableBeanFactorythatcanbeusedtoobtainandmodifybeandefinitions loaded by the Spring container. It is possible to create a bean instance insidepostProcessBeanFactorymethoditselfbycallingConfigurableListableBeanFactory’sgetBeanmethod,butbean creation inside postProcessBeanFactorymethod isnot recommended. It is important to note thatBeanPostProcessors (refer section 5-3) are not executed for bean instances created insidepostProcessBeanFactorymethod.

ItisimportanttonotethataConfigurableListableBeanFactoryprovidesaccesstotheSpringcontainerjustlike the ApplicationContext object. ConfigurableListableBeanFactory additionally allows you toconfigure the Spring container, iterate over beans, and modify bean definitions. For instance, usingConfigurableListableBeanFactoryobjectyoucanregisterPropertyEditorRegistrars (refersection3-6ofchapter 3), register BeanPostProcessors, and so on. Later in this section, we’ll see howConfigurableListableBeanFactoryobjectisusedtomodifybeandefinitions.

Let’snowlookathowwecanuseaBeanFactoryPostProcessortomodifybeandefinitions.

IMPORT chapter 5/ch05-bankapp-beanfactorypostprocessor (This project shows the MyBankapplication that uses a BeanFactoryPostProcessor implementation to disable autowiring across theapplication,andloganerrormessageifasingleton-scopedbeanisfoundtobedependentonaprototype-scopedbean.ToverifythattheBeanFactoryPostProcessorimplementationfunctionscorrectly,executethemainmethodoftheBankAppclassofthisproject.)

BeanFactoryPostProcessorexampleIn the previous chapter, we saw that autowiring hides the overall structure of the application (refersection4-6ofchapter4).Wealsodiscussed that insteadofusing<property>element to specify thatasingleton-scoped bean is dependent on a prototype-scoped bean, you should use <lookup-method> or<replaced-method>element(refersection4-4and4-5ofchapter4formoredetails)toprogrammaticallyobtain a prototype-scoped dependency of a singleton-bean. We’ll now look at aBeanFactoryPostProcessor implementation thatmakes beansunavailable for autowiring (refer <bean>element’sautowire-candidateattributedescribedinsection4-6ofchapter4)andlogsanerrormessageifitfindsasingleton-scopedbeanisdependentonaprototype-scopedbean.Forsimplicity,weassumethatasingleton-scopedbeanuses<property>element to specify that it isdependentonaprototype-scopedbean.

Page 194: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

NOTEAbeanthatimplementsSpring’sBeanFactoryPostProcessorinterfaceisaspecialbean type; theSpringcontainerautomaticallydetectsandexecutesaBeanFactoryPostProcessorbean.

The following example listing shows the MyBank’s ApplicationConfigurer class that implementsBeanFactoryPostProcessorinterface:

Examplelisting5-22–ApplicationConfigurerclass–aBeanFactoryPostProcessorimplementationProject–ch05-bankapp-beanfactorypostprocessorSourcelocation-src/main/java/sample/spring/chapter05/bankapp/postprocessor

packagesample.spring.chapter05.bankapp.postprocessor;importorg.springframework.beans.factory.config.BeanDefinition;importorg.springframework.beans.factory.config.BeanFactoryPostProcessor;importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;publicclassApplicationConfigurerimplementsBeanFactoryPostProcessor{publicApplicationConfigurer(){logger.info("CreatedApplicationConfigurerinstance");}@OverridepublicvoidpostProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory)throwsBeansException{String[]beanDefinitionNames=beanFactory.getBeanDefinitionNames();//--getallthebeandefinitionsfor(inti=0;i<beanDefinitionNames.length;i++){StringbeanName=beanDefinitionNames[i];BeanDefinitionbeanDefinition=beanFactory.getBeanDefinition(beanName);beanDefinition.setAutowireCandidate(false);//--obtaindependenciesofabeanif(beanDefinition.isSingleton()){if(hasPrototypeDependency(beanFactory,beanDefinition)){logger.error("Singleton-scoped"+beanName+"beanisdependentonaprototype-scopedbean.");}}}}.....}

ThefollowingsequenceofactionsisperformedbythepostProcessBeanFactorymethod:

Page 195: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

1. First, the postProcessBeanFactory method calls ConfigurableListableBeanFactory’sgetBeanDefinitionNamesmethod toobtainnamesofall thebeandefinitions loadedby theSpringcontainer.Youshouldnote that thenameofabeandefinition is thevalueof<bean>element’s idattribute.

2. Once the names of all the bean definitions are obtained, the postProcessBeanFactory methodinvokesConfigurableListableBeanFactory’sgetBeanDefinitionmethodtoobtaintheBeanDefinitionobject corresponding to each bean definition. The getBeanDefinition method accepts a beandefinitionname(obtainedinstep1)asargument.

3. A BeanDefinition object represents a bean definition, and can be used to modify beanconfiguration.ForeachbeandefinitionloadedbytheSpringcontainer,thepostProcessBeanFactorymethodinvokesBeanDefinition’ssetAutowireCandidatemethodtomakeall thebeansunavailableforautowiring.

4. BeanDefinition’s isSingletonmethod returns true if a bean definition is for a singleton-scopedbean. If a bean definition is for a singleton-scoped bean, the postProcessBeanFactory methodinvokeshasPrototypeDependencymethodtocheckifthesingleton-scopedbeanisdependentonanyprototype-scopedbean.And,ifthesingleton-scopedbeanisdependentonaprototype-scopedbean,thepostProcessBeanFactorymethodlogsanerrormessage.

The following example listing shows the implementation of ApplicationConfigurer’shasPrototypeDependencymethodthatreturnstrueifabeanisdependentonaprototype-scopedbean:

Examplelisting5-23–ApplicationConfigurer’shasPrototypeDependencymethodProject–ch05-bankapp-beanfactorypostprocessorSourcelocation-src/main/java/sample/spring/chapter05/bankapp/postprocessor

importorg.springframework.beans.MutablePropertyValues;importorg.springframework.beans.PropertyValue;importorg.springframework.beans.factory.config.RuntimeBeanReference;publicclassApplicationConfigurerimplementsBeanFactoryPostProcessor{.....privatebooleanhasPrototypeDependency(ConfigurableListableBeanFactorybeanFactory,BeanDefinitionbeanDefinition){booleanisPrototype=false;MutablePropertyValuesmutablePropertyValues=beanDefinition.getPropertyValues();PropertyValue[]propertyValues=mutablePropertyValues.getPropertyValues();for(intj=0;j<propertyValues.length;j++){if(propertyValues[j].getValue()instanceofRuntimeBeanReference){StringdependencyBeanName=((RuntimeBeanReference)propertyValues[j].getValue()).getBeanName();BeanDefinitiondependencyBeanDef=beanFactory.getBeanDefinition(dependencyBeanName);if(dependencyBeanDef.isPrototype()){isPrototype=true;

Page 196: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

break;}}}returnisPrototype;}}

The hasPrototypeDependency method checks if the bean represented by BeanDefinition argument isdependentonaprototype-scopedbean.TheConfigurableListableBeanFactoryargumentprovidesaccesstobeandefinitions loadedby theSpringcontainer.The following sequenceofactions isperformedbyhasPrototypeDependencymethod to find if the bean represented by theBeanDefinition argument has aprototype-scopeddependency:

1.First,hasPrototypeDependencymethodcallsBeanDefinition’sgetPropertyValuesmethodtoobtainbean properties defined by <property> elements. BeanDefinition’s getPropertyValues returns anobjectoftypeMutablePropertyValueswhichyoucanusetomodifybeanproperties.Forinstance,you can add additional properties to the bean definition by using addPropertyValue andaddPropertyValuesmethodsofMutablePropertyValues.

2. Aswewant to iterate over all the beanproperties and check if anybeanproperty refers to aprototype-scoped bean, the getPropertyValues method ofMutablePropertyValues is invoked toretrieveanarrayofPropertyValueobjects.APropertyValueobjectholdsinformationaboutabeanproperty.

3. If abeanproperty refers toaSpringbean, callingPropertyValue’sgetValuemethod returns aninstance of RuntimeBeanReference object that holds name of the referenced bean. As we areinterested in bean properties that reference Spring beans, the return value of PropertyValue’sgetValuemethodischeckedif it representsan instanceofRuntimeBeanReference type. If itdoes,theobjectreturnedbyPropertyValue’sgetValuemethodiscasttoRuntimeBeanReferencetype,andthenameofthereferencedbeanisobtainedbycallingtheRuntimeBeanReference’sgetBeanNamemethod.

4. Now, thatwe have the name of the bean referenced by the bean property, theBeanDefinitionobject for the referenced bean is obtained by calling ConfigurableListableBeanFactory’sgetBeanDefinitionmethod. You can check if the referenced bean is a prototype-scoped bean bycallingBeanDefinition’sisPrototypemethod.

ThefollowingsequencediagramsummarizeshowhasPrototypeDependencymethodworks:

Page 197: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure5-2–hasPrototypeDependencymethoditeratesoverbeandefinitionsofdependencies,andreturnstrueifaprototype-scopeddependencyisfound

In the above sequence diagram ConfigurableListableBeanFactory object has been depicted as ‘Beanfactory’object.

The following example listing shows the application context XML file of ch05-bankapp-beanfactorypostprocessor project that contains bean definitions for ApplicationConfigurer class (aBeanFactoryPostProcessor implementation), InstanceValidationBeanPostProcessor class (aBeanPostProcessorimplementation),alongwithbeandefinitionsforapplication-specificobjects:

Examplelisting5-24–applicationContext.xml-BeanFactoryPostProcessorbeandefinitionProject–ch05-bankapp-beanfactorypostprocessorSourcelocation-src/main/resources/META-INF/spring<beans.....>.....<beanid="FixedDepositDao"class="sample.spring.chapter05.bankapp.dao.FixedDepositDaoImpl".....><propertyname=“fixedDepositDetails"ref="FixedDepositDetails"/></bean><beanid="FixedDepositDetails"class="sample.spring.chapter05.bankapp.domain.FixedDepositDetails"scope="prototype"/><beanclass=".....postprocessor.InstanceValidationBeanPostProcessor"><propertyname="order"value="1"/></bean>

Page 198: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanclass="sample.spring.chapter05.bankapp.postprocessor.ApplicationConfigurer"/></beans>

In the bean definitions shown above, the singleton-scoped FixedDepositDao bean is dependent on theprototype-scopedFixedDepositDetailsbean.

If you execute themainmethod of BankApp class of ch05-bankapp-beanfactorypostprocessor project,you’llseethefollowingoutputontheconsole:CreatedApplicationConfigurerinstanceSingleton-scopedFixedDepositDaobeanisdependentonaprototype-scopedbean.CreatedInstanceValidationBeanPostProcessorinstance

The above output shows that the Spring container creates ApplicationConfigurer (aBeanFactoryPostProcessor) and executes ApplicationConfigurer’s postProcessBeanFactory methodbeforecreatingInstanceValidationBeanPostProcessor (aBeanPostProcessor) instance. It is important tonote that the beans that implement theBeanFactoryPostProcessor interface are processedbefore beansthat implement theBeanPostProcessor interface.For this reason,youcan’tuseaBeanPostProcessor tomakemodifications to aBeanFactoryPostProcessor instance.TheBeanFactoryPostProcessor gives youthe opportunity to modify bean definitions loaded by the Spring container, and theBeanFactoryPostProcessor gives you the opportunity to make modifications to newly created beaninstances.

Let’snowlookatsomeofthesimilaritiesbetweenBeanPostProcessorsandBeanFactoryPostProcessors:

· youcanconfiguremultipleBeanFactoryPostProcessors in theapplicationcontextXMLfile.Tocontrol the order in which BeanFactoryPostProcessors are executed by the Spring container,implementSpring’sOrderedinterface(refersection5-3toknowmoreaboutOrderedinterface).

· even ifyouspecify thataBeanFactoryPostProcessor implementation is lazily initializedby theSpring container, BeanFactoryPostProcessors are created when the Spring container instance iscreated.

Inchapter3,we lookedatCustomEditorConfigurer– aBeanFactoryPostProcessor implementation thatSpring provides out-of-the-box for registering custom property editors. Let’s now look at somemoreBeanFactoryPostProcessorimplementationsthatSpringprovidesout-of-the-box.

PropertySourcesPlaceholderConfigurerSofarwehaveseenbeandefinitionexamplesinwhich<property>or<constructor-arg>element’svalueattribute is used to specify the actual string value of a bean property or a constructor argument.PropertySourcesPlaceholderConfigurer (aBeanFactoryPostProcessor) let’syouspecify theactualstringvalueofbeanpropertiesandconstructorarguments inapropertiesfile.Inthebeandefinition,youonlyspecifyproperty 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 theSpringcontainer, thePropertySourcesPlaceholderConfigurerpulls theactualvalues from thepropertiesfileandreplacesthepropertyplaceholdersinthebeandefinitionswithactualvalues.

IMPORT chapter 5/ch05-propertySourcesPlaceholderConfigurer-example (This project shows a

Page 199: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

SpringapplicationthatusesSpring’sPropertySourcesPlaceholderConfigurertosetbeanpropertiesfromthe properties specified in external properties files. To verify that thePropertySourcesPlaceholderConfigurer functions correctly, execute themainmethod of the SampleAppclassofthisproject.)

The following example listing shows bean definitions for DataSource and WebServiceConfigurationclassesthatusepropertyplaceholders:

Examplelisting5-25–applicationContext.xml-BeandefinitionsthatusepropertyplaceholdersProject–ch05-propertySourcesPlaceholderConfigurer-exampleSourcelocation-src/main/resources/META-INF/spring<beanid="datasource"class="sample.spring.chapter05.domain.DataSource"><propertyname="url"value="${database.url}"/><propertyname="username"value="${database.username}"/><propertyname="password"value="${database.password}"/><propertyname="driverClass"value="${database.driverClass}"/></bean><beanid="webServiceConfiguration"class="sample.spring.chapter05.domain.WebServiceConfiguration"><propertyname="webServiceUrl"value="${webservice.url}"/></bean>

The above example listing shows that each <property> element’s value attribute specifies a propertyplaceholder. When bean definitions are loaded by the Spring container,PropertySourcesPlaceholderConfigurer replaces property placeholders with values from a propertiesfile. For instance, if a database.username property is defined in a properties file, the value ofdatabase.usernamepropertyreplacesthe${database.username}propertyplaceholderofdataSourcebean.

The bean definition for the PropertySourcesPlaceholderConfigurer specifies properties files to besearchedforfindingreplacementforapropertyplaceholder,asshowninthefollowingexamplelisting:

Examplelisting5-26–applicationContext.xml-PropertySourcesPlaceholderConfigurerbeandefinitionProject–ch05-propertySourcesPlaceholderConfigurer-exampleSourcelocation-src/main/resources/META-INF/spring<beanclass="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"><propertyname="locations"><list><value>classpath:database.properties</value><value>classpath:webservice.properties</value></list></property><propertyname="ignoreUnresolvablePlaceholders"value="false"/></bean>

Page 200: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

PropertySourcesPlaceholderConfigurer’slocationspropertyspecifiespropertiesfilestobesearchedforfinding the value for a property placeholder. In the above example listing,PropertySourcesPlaceholderConfigurer looks for the value of a property placeholder indatabase.properties and webservice.properties files. The ignoreUnresolvablePlaceholders propertyspecifieswhetherPropertySourcesPlaceholderConfigurersilentlyignoresorthrowsanexceptionincaseapropertyplaceholdervalueisnotfoundinanyofthepropertiesfilesspecifiedbythelocationsproperty.ThevaluefalseindicatesthatthePropertySourcesPlaceholderConfigurerwillthrowanexceptionifvalueforapropertyplaceholderisnotfoundindatabase.propertiesorwebservice.propertiesfiles.

The following example listing shows the properties defined in database.properties andwebservice.propertiesfiles:

Examplelisting5-27–Propertiesdefinedindatabase.propertiesandwebservice.propertiesfilesProject–ch05-propertySourcesPlaceholderConfigurer-exampleSourcelocation-src/main/resources/META-INF----------------database.propertiesfile------------------database.url=some_urldatabase.username=some_usernamedatabase.password=some_passworddatabase.driverClass=some_driverClass----------------webservice.propertiesfile------------------webservice.url=some_url

If you compare the properties defined in database.properties andwebservice.properties fileswith theproperty placeholders specified in datasource and webServiceConfiguration bean definitions (referexamplelisting5-25),you’llnoticethatforeachpropertyplaceholderapropertyisdefinedinoneofthepropertiesfiles.

Themainmethod of SampleApp class of ch05-propertySourcesPlaceholderConfigurer-example projectretrievesWebServiceConfigurationandDataSourcebeans from theApplicationContext and prints theirpropertiesontheconsole.IfyouexecuteSampleApp’smainmethod,you’llsee thefollowingoutputontheconsole:

DataSource [url=some_url,username=some_username,password=some_password,driverClass=some_driverClass]WebServiceConfiguration[webServiceUrl=some_url]

Theaboveoutputshows:

· DataSource’s url property is set to some_url, username to some_username, password tosome_passwordanddriverClasstosome_driverClass.

·WebServiceConfiguration’swebServiceUrlpropertyissettosome_url.

If you remove a property from either database.properties or webservice.properties file, executingSampleApp’smainmethodwillresultinanexception.

Let’snowlookatlocalOverridepropertyofPropertySourcesPlaceholderConfigurer.

Page 201: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

localOverrideproperty

Ifyouwantlocalproperties(setvia<props>element)tooverridepropertiesreadfrompropertiesfile,youcansetPropertySourcesPlaceholderConfigurer’slocalOverridepropertytotrue.

IMPORT chapter 5/ch05-localoverride-example (This project shows a Spring application that usesPropertySourcesPlaceholderConfigurer’slocalOverrideproperty.Toruntheapplication,executethemainmethodoftheSampleAppclassofthisproject.)

The following example listing shows bean definitions for DataSource and WebServiceConfigurationclasses:

Examplelisting5-28–applicationContext.xml-BeandefinitionsthatusepropertyplaceholdersProject–ch05-localOverride-exampleSourcelocation-src/main/resources/META-INF/spring<beanid="datasource"class="sample.spring.chapter05.domain.DataSource"><propertyname="url"value="${database.url}"/><propertyname="username"value="${database.username}"/><propertyname="password"value="${database.password}"/><propertyname="driverClass"value="${database.driverClass}"/></bean><beanid="webServiceConfiguration"class="sample.spring.chapter05.domain.WebServiceConfiguration"><propertyname="webServiceUrl"value="${webservice.url}"/></bean>

The bean definitions for DataSource and WebServiceConfiguration classes are same as we saw inexamplelisting5-25.

The following example listing shows the properties defined in database.properties andwebservice.propertiesfiles:

Examplelisting5-29–Propertiesdefinedindatabase.propertiesandwebservice.propertiesfilesProject–ch05-localOverride-exampleSourcelocation-src/main/resources/META-INF----------------database.propertiesfile------------------database.url=some_urldatabase.username=some_username----------------webservice.propertiesfile------------------webservice.url=some_url

If you compare the properties defined in database.properties andwebservice.properties fileswith theproperty placeholders specified in datasource and webServiceConfiguration bean definitions (referexample listing 5-28), you’ll notice that properties are not defined for ${database.password} and

Page 202: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

${database.driverClass}placeholdersinthedatabase.propertiesfile.

The following example listing shows the bean definition for PropertySourcesPlaceholderConfigurerclass:

Examplelisting5-30–applicationContext.xml-PropertySourcesPlaceholderConfigurerbeandefinitionProject–ch05-localOverride-exampleSourcelocation-src/main/resources/META-INF/spring<beanclass="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"><propertyname="locations"><list><value>classpath:database.properties</value><value>classpath:webservice.properties</value></list></property><propertyname="properties"><props><propkey="database.password">locally-set-password</prop><propkey="database.driverClass">locally-set-driverClass</prop><propkey="webservice.url">locally-set-webServiceUrl</prop></props></property><propertyname="ignoreUnresolvablePlaceholders"value="false"/><propertyname="localOverride"value="true"/></bean>

The properties property of PropertySourcesPlaceholderConfigurer defines local properties. Thedatabase.password, database.driverClass and webservice.url properties are local properties. ThelocalOverride property specifies whether local properties take precedence over properties read fromexternalpropertiesfiles.AsthevalueoflocalOverridepropertyistrue,localpropertiestakeprecedence.

The main method of SampleApp class in ch05-localOverride-example project retrievesWebServiceConfigurationandDataSourcebeansfromtheApplicationContextandprintstheirpropertiesontheconsole.IfyouexecuteSampleApp’smainmethod,you’llseethefollowingoutputontheconsole:

DataSource[url=some_url,username=some_username,password=locally-set-password,driverClass=locally-set-driverClass]WebServiceConfiguration[webServiceUrl=locally-set-webServiceUrl]

Theoutput shows that thevalueofDataSource’spassword anddriverClass properties are locally-set-password and locally-set-driverClass, respectively. This means that the values for DataSource’spassword and driverClass properties come from the local properties defined by thePropertySourcesPlaceholderConfigurer bean (refer example listing 5-30). This shows that if thePropertySourcesPlaceholderConfigurercan’tfindapropertyforaplaceholderintheexternalpropertiesfiles, it searches for the property in the local properties defined byPropertySourcesPlaceholderConfigurerbean.TheoutputalsoshowsthattheWebServiceConfiguration’swebServiceUrl property value comes from the local properties defined by the

Page 203: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

PropertySourcesPlaceholderConfigurer bean (refer example listing 5-30). The value ofPropertySourcesPlaceholderConfigurer’s localOverride property is set to true; therefore, the locallydefined webservice.url property takes precedence over the webservice.url property read from thewebservice.propertiesfile.

NOTEInsteadofusingPropertySourcesPlaceholderConfigurer’spropertiesproperty,youcanuse<properties>elementofSpring’sutilschema(refersection3-8ofchapter3)orPropertiesFactoryBean(refersection3-8ofchapter3)todefinelocalproperties.

Instead of directly configuring the PropertySourcesPlaceholderConfigurer bean in your applicationcontext XML file, you can use the <property-placeholder> element of Spring’s context schema. The<property-placeholder>elementconfiguresaPropertySourcesPlaceholderConfigurerinstance.Let’snowlookatthe<property-placeholder>elementindetail.

IMPORT chapter 5/ch05-property-placeholder-element-example (This project shows a Springapplicationthatusesthe<property-placeholder>element.Toruntheapplication,executethemainmethodoftheSampleAppclassofthisproject.)

<property-placeholder>element

The following example listing shows how the <property-placeholder> element is used to configure aPropertySourcesPlaceholderConfigurerinstancewiththesameconfigurationastheoneweconfiguredinexamplelisting5-30:

Examplelisting5-31–applicationContext.xml-<property-placeholder>elementProject–ch05-property-placeholder-element-exampleSourcelocation-src/main/resources/META-INF/spring<beansxmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:util="http://www.springframework.org/schema/util".....>…..<context:property-placeholderignore-unresolvable="false"location="classpath:database.properties,classpath:webservice.properties"local-override="true"order="1"properties-ref="localProps"/><util:propertiesid="localProps"><propkey="database.password">locally-set-password</prop><propkey="database.driverClass">locally-set-driverClass</prop><propkey="webservice.url">locally-set-webServiceUrl</prop></util:properties></beans>

In the above example listing, reference toSpring’s context schema is included so that its elements areaccessible.Theaboveexamplelistingshowsthattheuseof<property-placeholder>elementresultsinalessverboseconfigurationofPropertySourcesPlaceholderConfigurer.The ignore-unresolvable, locationandlocal-overrideattributescorrespondtoignoreUnresolvablePlaceholders,locationsandlocalOverrideproperties of PropertySourcesPlaceholderConfigurer. As the PropertySourcesPlaceholderConfigurer

Page 204: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

classimplementsSpring’sOrderedinterface,theorderattribute’svalueisusedtosettheorderpropertyof PropertySourcesPlaceholderConfigurer instance. The properties-ref attribute refers to ajava.util.Properties object that represents the local properties. In the above example listing, the<properties> element of Spring’s util schema (refer section 3-8 of chapter 3) creates an instance ofjava.util.Propertiesobject,whichisreferencedbytheproperties-refattributeof<property-placeholder>element.

Let’snowlookatSpring’sPropertyOverrideConfigurer(aBeanFactoryPostProcessor)whichallowsyoutospecifyvaluesforbeanpropertiesinexternalpropertiesfiles.

PropertyOverrideConfigurerPropertyOverrideConfigurer is similar to PropertySourcesPlaceholderConfigurer in the sense that itallows you to specify a bean property value in external properties file. When usingPropertyOverrideConfigurer, bean property value is specified in the following format in externalpropertiesfiles:

<bean-name>.<bean-property-name>=<value>

here,<bean-name> is thenameof thebean,<bean-property-name> is thenameof thebeanproperty,and<value>isthevaluethatyouwanttoassigntothebeanproperty.

ThenotabledifferencesbetweenPropertyOverrideConfigurerandPropertySourcesPlaceholderConfigurerclassesare:

·YoucanusePropertyOverrideConfigureronlyforexternalizingvaluesofbeanproperties,thatis,youcan’tusePropertyOverrideConfigurertoexternalizevaluesofconstructorarguments.

· PropertySourcesPlaceholderConfigurerdoesn’tprovideyouwithanoption tospecifydefaultvalues for properties. But, PropertyOverrideConfigurer allows you to specify default values forbeanproperties.

Let’snowlookatanexampleusageofPropertyOverrideConfigurer.

IMPORT chapter 5/ch05-propertyOverrideConfigurer-example (This project shows a Springapplication that uses Spring’s PropertyOverrideConfigurer. To run the application, execute the mainmethodoftheSampleAppclassofthisproject.)

PropertyOverrideConfigurerexample

The following example listing shows bean definitions for DataSource and WebServiceConfigurationclasseswhosepropertieswe’llsetusingPropertyOverrideConfigurer:

Example listing 5-32 – applicationContext.xml - Bean definitions for DataSource andWebServiceConfigurationProject–ch05-propertyOverrideConfigurer-exampleSourcelocation-src/main/resources/META-INF/spring<beanid="datasource"class="sample.spring.chapter05.domain.DataSource"><propertyname="url"value="testurlvalue"/><propertyname="username"value="testusernamevalue"/>

Page 205: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<propertyname="password"value="testpasswordvalue"/><propertyname="driverClass"value="testdriverClassvalue"/></bean><beanid="webServiceConfiguration"class="sample.spring.chapter05.domain.WebServiceConfiguration"><propertyname="webServiceUrl"value="thiswebserviceurlneedstobereplaced"/></bean>

In the above example listing, the <bean> element’s value attribute specifies default value of a beanproperty.

The followingexample listing shows thebeandefinition for thePropertyOverrideConfigurerclass thatreplaces the default values of bean properties (shown in example listing 5-32)with values read fromdatabase.propertiesandwebservice.propertiesfiles:

Examplelisting5-33–applicationContext.xml-PropertyOverrideConfigurerconfigurationProject–ch05-propertyOverrideConfigurer-exampleSourcelocation-src/main/resources/META-INF/spring<beanclass="org.springframework.beans.factory.config.PropertyOverrideConfigurer"><propertyname="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 propertiesfilesthatcontainvaluesforbeanproperties.

NOTE Instead of directly configuring PropertyOverrideConfigurer, you can use <property-override>elementofSpring’scontextschematoconfigureaPropertyOverrideConfigurerinstance.

The following example listing shows database.properties andwebservice.properties files that containvaluesofbeanproperties:

Examplelisting5-34–Propertiesdefinedindatabase.propertiesandwebservice.propertiesProject–ch05-propertyOverrideConfigurer-exampleSourcelocation-src/main/resources/META-INF----------------database.propertiesfile------------------datasource.url=some_urldatasource.username=some_usernamedatasource.password=some_password

Page 206: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

----------------webservice.propertiesfile------------------webServiceConfiguration.webServiceUrl=some_url

The entries in the database.properties and webservice.properties files show that the property namefollows thepattern:<bean-name>.<property-name>.Whenbeandefinitionsare loadedby theSpringcontainer,PropertyOverrideConfigurerreplacesthedefaultvalueofabeanpropertywiththevaluereadforthatbeanpropertyfromthedatabase.propertiesandwebservice.propertiesfiles.Forinstance,theurlproperty of datasource bean is set to the value of datasource.url property defined in thedatabase.properties file.Similarly,webServiceUrl property ofwebServiceConfiguration bean is set tothevalueofwebServiceConfiguration.webServiceUrlpropertydefinedinthewebservice.propertiesfile.

If no value is found for a bean property in the external properties files, the bean property retains itsdefaultvalue.Examplelisting5-32showsthatthedriverClasspropertyofdatasourcebeanhasthedefaultvalue ‘test driverClass value’. Example listing 5-34 shows that there is no property nameddatasource.driverClass defined in the database.properties orwebservice.properties file; therefore, thedriverClassbeanpropertyretainsitsdefaultvalue.

Themainmethod of SampleApp class of ch05-propertyOverrideConfigurer-example project retrievesWebServiceConfigurationandDataSourcebeansfromtheApplicationContextandprintstheirpropertiesontheconsole.IfyouexecuteSampleApp’smainmethod,you’llseethefollowingoutputontheconsole:DataSource[url=some_url,username=some_username,password=some_password,driverClass=testdriverClassvalue]WebServiceConfiguration[webServiceUrl=some_url]

The above output shows that the default values of all bean properties, except that of driverClass, arereplacedbythepropertyvaluesspecifiedintheexternalpropertiesfiles.

As PropertyOverrideConfigurer and PropertySourcesPlaceholderConfigurer inherit from Spring’sPropertyResourceConfigurer class, you’ll notice that both of these classes share many commonconfigurationoptions.Forinstance,youcansetPropertyOverrideConfigurer’slocalOverridepropertytocontrolwhetherthelocalpropertiesgetprecedenceoverpropertiesreadfromexternalpropertiesfiles,youcansetPropertyOverrideConfigurer’spropertiespropertytodefinelocalproperties,andsoon.

Page 207: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

5-5SummaryInthischapter,wesawhowtoaddcustominitializationanddestructionlogictoabeaninstance.WealsolookedathowyoucanmodifynewlycreatedbeaninstancesusingBeanPostProcessor implementations,andmodifybeandefinitionsusingBeanFactoryPostProcessor implementations. Spring internallymakesuseofBeanPostProcessorsandBeanFactoryPostProcessors toprovidemanyframeworkfeatures. In thenextchapter,we’lllookatSpring’ssupportforannotation-drivendevelopment.

Page 208: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter6-Annotation-drivendevelopmentwithSpring

Page 209: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-1IntroductionInpreviouschapters,wesawthatthebeandefinitionscontainedintheapplicationcontextXMLfileareused as a blueprint by the Spring container to create bean instances. A bean definition specifiesinformation about bean dependencies, initialization and destruction methods of a bean, lazy or eagerinitialization strategy for the bean instance, bean scope, and so on. In this section, we’ll look atannotations thatyoucanuse tospecify thesame information in thebeanclass itself, therebysaving theeffort toexplicitlyconfigureabean in theapplicationcontextXMLfile.We’ll also touchuponSpringExpressionLanguage(SpEL)andhowtovalidateobjectsusingSpring’sValidatorinterfaceandthroughJSR303annotations.We’llendthischapterwithaquicklookathowtoprogrammaticallydefineSpringbeansusingSpring’s@Configurationand@Beanannotations.

Let’s first beginwith looking at Spring’s@Component annotation that indicates that a particular classrepresentsaSpringcomponent.

Page 210: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-2IdentifyingSpringcomponentswith@ComponentSpring’s@Component annotation is a type-level annotation, which indicates that a class represents aSpringcomponent.Itisrecommendedthatyouusemorespecializedformsof@Componentannotationtoannotatecontrollers,servicesanddataaccessobjects(DAOs)ofyourapplication.Forinstance,annotatecontrollerswith@Controller,serviceswith@Service,andDAOswith@Repositoryannotation.

IMPORTchapter6/ch06-bankapp-annotations (Thisprojectshows theMyBankapplication thatusesannotationsforregisteringbeanswiththeSpringcontainerandforautowiringdependencies.Torun theapplication,executethemainmethodoftheBankAppclassofthisproject.)

The following example listing shows theMyBank’s FixedDepositServiceImpl class thatmakes use of@Serviceannotation:

Examplelisting6-1–FixedDepositServiceImplclass-@ServiceannotationusageProject–ch06-bankapp-annotationsSourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;importorg.springframework.stereotype.Service;@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{.....}

As FixedDepositSerivceImpl class is annotated with @Service annotation, FixedDepositServiceImplclass represents a Spring component.@Service annotation accepts a value attribute that specifies thename 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 nameFixedDepositService.Thevalueattributeservesthesamepurposeasthe<bean>element’sidattribute.

Like@Serviceannotation,@Component,@Repositoryand@Controllerannotationsspecifythenameofthe component via value attribute.You can specify the nameof a Spring componentwithout explicitlyspecifying the value attribute. This means that @Service(value="FixedDepositService") is same as@Service("FixedDepositService").Ifyoudon’tspecifyanameforthecomponent,Springassumesnameof the component is same as the nameof the component class.Only difference is that the nameof thecomponentbeginswithalowercaseletter.Youshouldspecifyacustomnameforacomponentbecauseit’sparticularlyhelpfulwhenautowiringdependencies‘byname’.

If you enable classpath-scanning feature of Spring, bean classes annotated with @Component,@Controller, @Service or @Repository annotations are automatically registered with the Springcontainer.You enable classpath scanning feature of Spring by using the <component-scan> element ofSpring’scontextschema.

Thefollowingexamplelistingshowsusageof<component-scan>element:

Examplelisting6-2–applicationContext.xmlProject–ch06-bankapp-annotations

Page 211: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Sourcelocation-src/main/resources/META-INF/spring<beansxmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation=".....http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsd"><context:component-scanbase-package="sample.spring"/></beans>

In the above example listing, reference toSpring’s context schema is included so that its elements areaccessible.The<component-scan> element’s base-package attribute specifies comma-separated list ofpackages that should be searched for Spring components. As the base-package attribute’s value issample.spring,Springcomponentsare searched insidesample.springpackageand its sub-packages.AstheFixedDepositServiceImplclassshowninexamplelisting6-1isannotatedwith@Serviceannotationandislocatedinpackagesample.spring.chapter06.bankapp.service,the<component-scan>elementintheaboveexamplelistingautomaticallyregistersFixedDepositServiceImplclassasabeanwith theSpringcontainer.ThisisequivalenttothefollowingbeandefinitionfortheFixedDepositServiceImplclassintheapplicationcontextXMLfile:

Examplelisting6-3–BeandefinitionfortheFixedDepositServiceImplclass<beanid="FixedDepositService"class="sample.spring.chapter06.bankapp.service.FixedDepositServiceImpl"/>

IfyouwanttofilterthecomponentclassesthatshouldbeconsideredforautomaticregistrationwiththeSpring container, use the resource-patternattributeof<component-scan>element. The default value ofresource-pattern attribute is **/*.class, which means all the component classes under the package(s)specifiedbythebase-packageattributewillbeconsideredforautomaticregistration.The<include-filter>and<exclude-filter>sub-elementsof<component-scan>elementprovideamoreconcisewaytospecifycomponent classes that should be considered for automatic registration, and the classes that should beignored. For instance, the following example listing shows an example usage of <include-filter> and<exclude-filter>elements:

Examplelisting6-4–<include-filter>and<exclude-filter>elements<beans.....><context:component-scanbase-package="sample.example"><context:include-filtertype="annotation"expression="example.annotation.MyAnnotation"/><context:exclude-filtertype="regex"expression=".*Details"/></context:component-scan></beans>

The<exclude-filter>and<include-filter>elementsdefineatypeattributethatspecifiesthestrategyusedforfilteringcomponentclasses,andtheexpressionattributespecifiesthecorrespondingfilterexpression.In theaboveexample listing, the<include-filter>element specifies that the component classes that areannotatedwithMyAnnotationtype-levelannotationareautomaticallyregisteredwiththeSpringcontainer,

Page 212: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

andthe<exclude-filter>elementspecifiesthatthecomponentclasseswhosenamesendwithDetailsareignoredbythe<component-scan>element.

The following table describes the possible values that the type attributes of <include-filter> and<exclude-filter>elementscanaccept:

Valueoftypeattribute Description

annotation

If the type attribute’s value is annotation, the expression attribute specifies the fully-qualifiedclassnameoftheannotationthatacomponentclassmustbeannotatedwith.Forinstance, if the expression attribute’s value is example.annotation.MyAnnotation,componentclasses thatareannotatedwithMyAnnotationannotationareconsidered forinclusion (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-qualifiednameofaclassorinterfacetowhichacomponentclassmustbeassignable.

aspectj If the type attribute’s value is aspectj, the expression attribute specifies an AspectJexpressionthatisusedforfilteringthecomponentclasses.

regex Ifthetypeattribute’svalueisregex,theexpressionattributespecifiesaregularexpressionthatisusedforfilteringcomponentclassesbytheirnames.

customIf the type attribute’s value is custom, an implementation oforg.springframework.core.type.TypeFilter interface is specified by the expressionattributeforfilteringthecomponentclasses.

NOTE In this section, we looked at an example usage of @Service annotation. @Component,@Controller and@Repository annotations are specified the sameway as@Service annotation. ReferCustomerRegistrationDetailsandCustomerRequestDetailsclassesof ch06-bankapp-annotationsprojectto see usage of @Component annotation. Refer DAO classes contained in ch06-bankapp-annotationsprojecttoseeusageof@Repositoryannotation.

AsSpringcomponentsarenotdefinedintheapplicationcontextXMLfile,youdon’thavetheoptiontouse <property> or <constructor-arg> element to specify their dependencies. For this reason, Springcomponentsmakeuseofannotationslike@Autowired,@Inject,andsoon,tospecifytheirdependencies.

Let’snowlookatSpring’s@Autowiredannotation.

Page 213: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-3@Autowired-autowiringdependenciesbytype@Autowired annotation is used to autowire dependencies ‘by type’. Spring’s@Autowired annotationprovides the same functionality as the Spring’s autowiring feature thatwe discussed in chapter 4, but@Autowiredannotationoffers amorecleaner and flexible approach to autowiringbeandependencies.@Autowiredannotationcanbeusedatconstructor-level,method-levelandfield-level.

ThefollowingexamplelistingshowstheAccountStatementServiceImplclass thatuses the@Autowiredannotationatthefield-level:

Examplelisting6-5–AccountStatementServiceImplclass -@Autowiredannotationusageat thefield-levelProject–ch06-bankapp-annotationsSourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;@Service(value="accountStatementService")publicclassAccountStatementServiceImplimplementsAccountStatementService{@AutowiredprivateAccountStatementDaoaccountStatementDao;@OverridepublicAccountStatementgetAccountStatement(Datefrom,Dateto){returnaccountStatementDao.getAccountStatement(from,to);}}

Intheaboveexamplelisting,theaccountStatementDaofield(oftypeAccountStatementDao)isannotatedwith@Autowired annotation. When an instance ofAccountStatementServiceImpl is created, Spring’sAutowiredAnnotationBeanPostProcessor (a BeanPostProcessor implementation) is responsible forautowiringaccountStatementDaofield.TheAutowiredAnnotationBeanPostProcessor retrieves referencetoanAccountStatementDaotypebeanfromtheSpringcontainerandassignsittotheaccountStatementDaofield.It is importanttonotethatthefieldannotatedwith@Autowiredannotationneednotbepublicorhaveacorrespondingpublicsettermethod.

NOTESpring’sAutowiredAnnotationBeanPostProcessorperformsautowiringoffields,methodsandconstructorsthatareannotatedwithSpring’s@AutowiredorJSR330’s@Inject(explainedinsection6-5)annotation.

Page 214: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

The following example listing shows the CustomerRegistrationServiceImpl class that uses the@Autowiredannotationatthemethod-level:

Example listing 6-6 – CustomerRegistrationServiceImpl class - @Autowired annotation usage at themethod-levelProject–ch06-bankapp-annotationsSourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;@Service("customerRegistrationService")@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)publicclassCustomerRegistrationServiceImplimplementsCustomerRegistrationService{privateCustomerRegistrationDetailscustomerRegistrationDetails;.....@AutowiredpublicvoidobtainCustomerRegistrationDetails(CustomerRegistrationDetailscustomerRegistrationDetails){this.customerRegistrationDetails=customerRegistrationDetails;}.....@OverridepublicvoidsetAccountNumber(StringaccountNumber){customerRegistrationDetails.setAccountNumber(accountNumber);}.....}

Intheaboveexamplelisting,obtainCustomerRegistrationDetailsmethod isannotatedwith@Autowiredannotation. If a method is annotated with @Autowired annotation, the arguments of the method areautowired.AsobtainCustomerRegistrationDetailsmethod isannotatedwith@Autowiredannotation, itsCustomerRegistrationDetailsargumentisautowiredbytype. It is important tonote thatan@Autowiredannotatedmethodneednotbepublic.

NOTE A method annotated with @Autowired annotation is invoked after the component instance iscreated,andthefieldsannotatedwith@Autowiredannotationareinjectedwithmatchingbeaninstances.

The following example listing shows theCustomerRequestServiceImpl class that defines a constructorannotatedwith@Autowiredannotation:

Examplelisting6-7–CustomerRequestServiceImplclass-@Autowiredannotationusageatconstructor-levelProject–ch06-bankapp-annotationsSourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;

Page 215: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@Service(value="customerRequestService")publicclassCustomerRequestServiceImplimplementsCustomerRequestService{privateCustomerRequestDetailscustomerRequestDetails;privateCustomerRequestDaocustomerRequestDao;@AutowiredpublicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,CustomerRequestDaocustomerRequestDao){this.customerRequestDetails=customerRequestDetails;this.customerRequestDao=customerRequestDao;}.....}

In the above example listing, the CustomerRequestServiceImpl’s constructor is annotated [email protected]@Autowiredannotation,theargumentsoftheconstructorareautowired.AsCustomerRequestServiceImpl’sconstructorisannotatedwith@Autowiredannotation,itsCustomerRequestDetailsandCustomerRequestDaoargumentsareautowiredbytype. It isimportanttonotethatan@Autowiredannotatedconstructorneednotbepublic.

Whenusingthe@Autowiredannotation,exceptionisthrownifabeanmatchingtherequiredtypeisnotfound. For instance, in example listing 6-7, if a bean of type CustomerRequestDetails orCustomerRequestDaoisnotfoundtoberegisteredwiththeSpringcontainer,anexceptionisthrownwhilecreatingtheCustomerRequestServiceImplinstance.@Autowired’srequiredattributespecifieswhetheritismandatoryoroptionaltoautowiredependencies.Ifyouset@Autowired’srequiredattributevalue tofalse,autowiringofdependenciesisconsideredoptional.Thismeansthatiftherequiredattribute’svalueis set to false, exception is not thrown if no bean matching the required type is found in the Springcontainer.Bydefault, value of required attribute is true; dependenciesmust be satisfied by the Springcontainer.

Ifacomponentclassdefinesan@Autowiredannotatedconstructorwithrequiredattribute’svaluesettotrue, it can’t have another @Autowired annotated constructor. For instance, consider the followingexamplelistingthatdefines2constructorsannotatedwiththe@Autowiredannotation:

Examplelisting6-8–Acomponentclassthatdefines2@Autowiredannotatedconstructors

@Service(value="customerRequestService")publicclassCustomerRequestServiceImplimplementsCustomerRequestService{.....@Autowired(required=false)publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails){.....}@AutowiredpublicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,CustomerRequestDaocustomerRequestDao){.....}}

Asautowiringofdependenciesisrequired(@Autowired’srequiredattributeissettotrue)foroneofthe

Page 216: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

constructors and optional (@Autowired’s required attribute is set to false) for the other in the aboveexamplelisting,itresultsinanexceptionthrownbySpring.

A component class can define multiple @Autowired annotated constructors with required attribute’svaluesettofalse.Insuchacase,oneoftheconstructorswillbeinvokedbySpringtocreateaninstanceof the component class. The following example listing shows a component class that defines 2constructorsannotatedwith@Autowired(required=false),andadefaultconstructor:

Examplelisting6-9–Acomponentclassthatdefinesmultiple@Autowiredannotatedconstructorswithrequiredattributevaluesettofalse

@Service(value="customerRequestService")publicclassCustomerRequestServiceImplimplementsCustomerRequestService{publicCustomerRequestServiceImpl(){.....}@Autowired(required=false)publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails){.....}@Autowired(required=false)publicCustomerRequestServiceImpl(CustomerRequestDetailscustomerRequestDetails,CustomerRequestDaocustomerRequestDao){.....}}

Intheaboveexamplelisting,boththe@AutowiredannotatedconstructorsarecandidatesforautowiringbySpringtocreateaninstanceoftheCustomerRequestServiceImplclass.Theconstructorwiththelargestnumberof satisfieddependencies is chosen. In caseofCustomerRequestServiceImpl class, if beansoftypesCustomerRequestDetailsandCustomerRequestDaoareregisteredwiththeSpringcontainer,SpringinvokesCustomerRequestServiceImpl(CustomerRequestDetails, CustomerRequestDao) constructor. If abean of type CustomerRequestDetails is registered with container but no bean of typeCustomerRequestDao is registered, CustomerRequestServiceImpl(CustomerRequestDetails) constructoris invoked. In case none of the dependencies are found, the default constructor ofCustomerRequestServiceImplclassisinvoked.

Let’snowlookathowyoucanuseSpring’s@Qualifierannotationalongwith@Autowiredannotationtoautowiredependenciesbyname.

Page 217: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-4@Qualifier–autowiringdependenciesbynameYoucanuseSpring’s@Qualifierannotationalongwith@Autowiredannotationtoautowiredependenciesbyname.The@Qualifierannotationcanbeusedatfield-level,method-parameter-levelandconstructor-argument-level.

ThefollowingexamplelistingshowstheFixedDepositServiceImplclassthatuses@Qualifierannotation:

Examplelisting6-10–FixedDepositServiceImplclass-@QualifierannotationusageProject–ch06-bankapp-annotationsSourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.annotation.Qualifier;@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{@Autowired@Qualifier(value="myFixedDepositDao")privateFixedDepositDaomyFixedDepositDao;.....}

In theaboveexample listing,myFixedDepositDaofield isannotatedwith@Autowired and@Qualifierannotations.@Qualifierannotation’svalueattributespecifiesthenameofthebeantobeassignedtothemyFixedDepositDaofield.

Spring first finds autowiring candidates ‘by type’ for the fields, constructors and methods that areannotated with @Autowired annotation. Then, Spring uses the bean name specified by @Qualifierannotationtolocateauniquebeanfromthelistofautowiringcandidates.Forexample,inexamplelisting6-10,SpringfirstfindsbeansoftypeFixedDepositDaoformyFixedDepositDaofield,andthenlocatesthebean named myFixedDepositDao from the list of autowiring candidates. If a bean namedmyFixedDepositDaoisfound,SpringassignsittothemyFixedDepositDaofield.

NOTE @Qualifier(value="myFixedDepositDao") is same as @Qualifier("myFixedDepositDao"); youdon’tneedtousethevalueattributetospecifythenameofthebeantobeautowired.

The following example listing shows usage of @Qualifier annotation at method-parameter-level andconstructor-argument-level:

Examplelisting6-11–@Qualifierusageatmethod-parameter-levelandconstructor-argument-level

publicclassSample{@Autowired

Page 218: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicSample(@Qualifier("aBean")ABeanbean){....}@AutowiredpublicvoiddoSomething(@Qualifier("bBean")BBeanbean,CBeancBean){.....}}

Intheaboveexamplelisting,@Qualifierannotationisspecifiedforaconstructorargumentandamethodargument.WhencreatinganinstanceofSampleclass,SpringfindsabeanoftypeABeanwithnameaBeanand passes it as an argument to the Sample class’s constructor. When calling Sample’s doSomethingmethod,SpringfindsabeanoftypeBBean(whosenameisbBean)andanotherbeanoftypeCBean,andpassesboththesebeansasargumentstothedoSomethingmethod.It is important tonotethat theBBeandependencyisautowiredbyname,andCBeandependencyisautowiredbytype.

Let’s now look at JSR 330’s@Inject and@Named annotations that you can use instead of Spring’s@Autowiredand@Qualifierannotations.

Page 219: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-5JSR330’s@Injectand@NamedannotationsJSR 330 (Dependency Injection for Java) standardizes dependency injection annotations for the Javaplatform.JSR330defines@Injectand@NamedannotationsthataresimilartoSpring’s@Autowiredand@Qualifierannotations,respectively.Springprovidessupportfor@Injectand@Namedannotations.

IMPORTchapter6/ch06-bankapp-jsr330 (Thisproject shows theMyBankapplication thatuses JSR330’s@Injectand@Namedannotationsforautowiringdependencies.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject.)

The following example listing shows the FixedDepositServiceImpl class thatmakes use of JSR 330’s@Injectand@Namedannotations:

Examplelisting6-12–FixedDepositServiceImplclassProject–ch06-bankapp-jsr330Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;importjavax.inject.Inject;importjavax.inject.Named;@Named(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{@Inject@Named(value="myFixedDepositDao")privateFixedDepositDaomyFixedDepositDao;.....}

If you compare the FixedDepositServiceImpl class shown in the above example listing with theFixedDepositServiceImplclassinexamplelisting6-10,you’llnoticethatJSR330’s@Namedannotationhasbeenusedinplaceof@Serviceand@Qualifierannotations,andJSR330’s@Injectannotationhasbeenusedinplaceof@Autowiredannotation.

@Autowired and @Inject annotations have the same semantics; they are used for autowiringdependenciesby type.Like@Autowiredannotation,@Injectcanbeusedatmethod-level, constructor-level and field-level.Dependency injection of constructors is performed first, followedby fields, andthenmethods.We saw earlier that@Autowired annotation’s required attribute specifies whether it ismandatoryor optional to autowire dependencies.@Inject doesn’t have any equivalent of@Autowiredannotation’srequiredattribute.

If@Named annotation is used at the type-level, it acts like Spring’s@Component annotation.And, if@Named annotation is used at the method-parameter-level or constructor-argument-level, it acts likeSpring’s @Qualifier annotation. If a class is annotated with @Named annotation, <component-scan>element of Spring’s context schema treats it like a component class annotated with @Componentannotation.

Page 220: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Touse@Named and@Inject annotations, youneed to include JSR330 JAR file in your project.Thech06-bankapp-jsr330projectincludesJSR330JARfilethroughthefollowing<dependency>elementinthepom.xmlfile:

<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 toidentify initialization and destruction methods of a bean. Let’s now look at JSR 250’s @Resourceannotationthatyoucanuseforautowiringdependenciesbyname.

Page 221: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-6JSR250’s@ResourceannotationSpring supports autowiring ‘by name’ of fields and methods via JSR 250’s @Resource annotation.@Resourceannotation’snameattributespecifiesthenameofthebeantobeautowired.Itisimportanttonotethatyoucan’tuse@Resourceannotationforautowiringconstructorarguments.

ThefollowingexamplelistingshowshowFixedDepositServiceImplclassfromexamplelisting6-12canberewrittenusing@Resourceannotation:

Examplelisting6-13–@Resourceannotationusageatfield-levelimportjavax.annotation.Resource;@Named(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{@Resource(name="myFixedDepositDao")privateFixedDepositDaomyFixedDepositDao;.....}

In theaboveexample listing,@Resourceannotationhasbeenused for autowiringmyFixedDepositDaofield. As the value of name attribute is myFixedDepositDao, Spring locates a bean namedmyFixedDepositDaointheSpringcontainerandassignsittomyFixedDepositDaofield.

Instead of using@Autowired and@Qualifier annotations, you should use @Resource annotation forautowiring dependencies ‘by name’. As mentioned earlier, if you are using @Autowired-@Qualifiercombinationtoperformautowiring‘byname’,Springfirstfindsbeansbasedonthetypeofthefield(orthetypeofthemethodargumentorconstructorargument)tobeautowired,followedbynarrowingdowntoa 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 uniquebean.Thismeansthatwhenyouuse@Resourceannotation,typeofthefield(orsettermethodargument)tobeautowiredisnottakenintoconsiderationbySpring.

NOTEAs@Autowired,@Injectand@ResourceannotationsareprocessedbyBeanPostProcessors,youshould not use these annotations in component classes that implement BeanFactoryPostProcessor orBeanPostProcessorinterface.

Let’snowlookat@Scope,@Lazy,@DependsOnand@Primaryannotations.

Page 222: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-7@Scope,@Lazy,@DependsOnand@PrimaryannotationsYouspecifythescope(prototypeorsingleton)ofaSpringcomponentusingSpring’[email protected], Spring components are singleton-scoped. If youwant aSpring component to be prototype-scoped,youhave to specify sovia@Scopeannotation.@Scope annotationplays the same role as the<bean>element’sscopeattribute(refersection2-5ofchapter2toknowmoreaboutthescopeattribute).

ThefollowingexamplelistingshowstheCustomerRequestDetailsclassthatuses@Scopeannotation:

Examplelisting6-14–@ScopeannotationusageProject–ch06-bankapp-jsr330Sourcelocation-src/main/java/sample/spring/chapter06/bankapp/domain

packagesample.spring.chapter06.bankapp.domain;importjavax.inject.Named;importorg.springframework.beans.factory.config.ConfigurableBeanFactory;importorg.springframework.context.annotation.Scope;@Named(value="customerRequestDetails")@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)publicclassCustomerRequestDetails{.....}

The@Scopeannotationacceptsavalueattributethatspecifiesthescopeofthecomponent.Youcansetvalueattribute’svaluetoprototypeorsingletontoindicatewhetherthecomponentissingleton-scopedorprototype-scoped, or you can set value attribute’s value to ConfigurableBeanFactory’sSCOPE_SINGLETON(valueissingleton)orSCOPE_PROTOTYPE(valueisprototype)constants.

Bydefault,singleton-scopedSpringcomponentsareeagerlyinitialized,thatis,theyareinstantiatedwhentheSpringcontaineriscreated.Ifyouwantasingleton-scopedcomponenttobelazilycreated,annotatethecomponentclassofasingleton-scopedcomponentwith@Lazyannotation.

NOTE @Lazy annotation serves the same purpose as the <bean> element’s lazy-initattribute.Refersection2-5ofchapter2toknowmoreaboutlazy-initattribute.Thefollowingexamplelistingshowsusageof@Lazyannotation:Examplelisting6-15–@Lazyannotationusage

@Lazy(value=true)@ComponentpublicclassSample{.....}

@Lazyannotation’svalueattributespecifieswhetherthecomponentislazilyoreagerlyinitialized.Ifthevalueattribute’svalueistrue,itmeansthatthecomponentislazilyinitialized.

You specify implicit beandependencies using@DependsOn annotation.The following example listingshowsusageof@DependsOnannotation:

Page 223: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting6-16–@DependsOnannotationusage

@DependsOn(value={"beanA","beanB"})@ComponentpublicclassSample{.....}

Intheaboveexamplelisting,@DependsOnannotationontheSampleclassinstructstheSpringcontainertocreatebeanAandbeanBbeansbeforecreatinganinstanceofSampleclass.

NOTE@DependsOnannotationservesthesamepurposeasthe<bean>element’sdepends-onattribute.Refersection4-3ofchapter4toknowmoreaboutdepends-onattribute.

Ifmultipleautowiringcandidatesareavailableforadependency,@Primaryannotationdesignatesabeanas a primary candidate for autowiring. The following example listing shows usage of @Primaryannotation:

Examplelisting6-17–@Primaryannotationusage

@Primary@ComponentpublicclassSample{.....}

NOTE@Primaryannotationserves thesamepurposeas the<bean>element’sprimaryattribute.Refersection4-6ofchapter4toknowmoreaboutprimaryattribute.

Let’snowlookatSpring’s@Valueannotationthatsimplifiesconfiguringcomponentclasses.

Page 224: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-8Simplifyingcomponentconfigurationusing@ValueannotationIn previous chapters, we saw examples in which configuration information required by beans wasspecifiedviavalueattributeof<property>and<constructor-arg>elements.AsSpringcomponentsarenotdefined in the application context XML file, Spring’s @Value annotation is used to serve the samepurpose 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 Spring’[email protected],executethemainmethodoftheSampleAppclassofthisproject.)

Thefollowingexamplelistingshowsanexampleusageof@Valueannotationatfield-level:

Examplelisting6-18–Sampleclass-@ValueannotationusageProject–ch06-value-annotationSourcelocation-src/main/java/sample/spring/chapter06/beans

packagesample.spring.chapter06.beans;importorg.springframework.beans.factory.annotation.Value;@Component(value="sample")publicclassSample{@Value("Somecurrency")privateStringcurrency;.....}

In the above example listing, currency field is annotated with @Value annotation. The @Valueannotation’svalue attribute specifies the default value for the field. It is optional to specify the valueattribute;therefore,@Value(value="Somecurrency")issameas@Value("Somecurrency").

YoucanalsouseaSpringExpressionLanguage(SpEL)[email protected] is an expression language that you can use to query and manipulate objects at runtime. Thefollowingexamplelistingshows@ValueannotationsthatmakeuseofSpELexpressions:

Examplelisting6-19–Sampleclass-@ValueannotationthatusesSpELexpressionsProject–ch06-value-annotationSourcelocation-src/main/java/sample/spring/chapter06/beans

packagesample.spring.chapter06.beans;importorg.springframework.beans.factory.annotation.Value;@Component(value="sample")publicclassSample{

Page 225: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@Value("#{configuration.environment}")privateStringenvironment;.....@Value("#{configuration.getCountry()}")privateStringcountry;@Value("#{configuration.state}")privateStringstate;.....}

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 aBeanPostProcessor.TheSpELexpressionscanmakeuseof<beanName>.<fieldorpropertyormethod>formattoobtainitsvalue.Forinstance,#{configuration.environment}meansobtainvalueofenvironmentproperty of bean named configuration, and #{configuration.getCountry()} means invoke getCountrymethodofbeannamedconfiguration.

The following example listing shows the Java class of the configuration bean referenced by SpELexpressionsshowninexamplelisting6-19:

Examplelisting6-20–ConfigurationcomponentclassProject–ch06-value-annotationSourcelocation-src/main/java/sample/spring/chapter06/beans

packagesample.spring.chapter06.beans;importorg.springframework.stereotype.Component;@Component("configuration")publicclassConfiguration{publicstaticStringenvironment="DEV";publicStringgetCountry(){return"Somecountry";}publicStringgetState(){return"Somestate";}publicString[]splitName(Stringname){returnname.split("");

Page 226: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

}publicStringgetCity(){return"Somecity";}}

TheaboveexamplelistingshowsthattheConfigurationclassrepresentsaSpringcomponentthatdefinesfields and methods. If you compare example listing 6-19 with 6-20, you’ll notice that #{configuration.environment} expression refers to the static environment variable defined in theConfiguration class, #{configuration.getCountry()} expression refers to Configuration’s getCountrymethod,and#{configuration.state}expressionreferstoConfiguration’sgetStatemethod.

ThemainmethodofSampleAppclassinch06-value-annotationproject retrievesan instanceofSamplebeanfromtheApplicationContextandprints thevalueofvariousattributesofSamplebean instance. IfyouexecuteSampleApp’smainmethod,you’llseethefollowingoutput:Sample[environment=DEV,currency=Somecurrency,country=Somecountry,state=Somestate ,splitName=[FirstName,LastName],city=Somecity]

Theaboveoutputshows:

· #{configuration.environment} expression results inSample’senvironment field value set toDEV,whichisthevaluespecifiedbypublicstaticfieldenvironmentofConfigurationclass.

· #{configuration.getCountry()}expressionresults inSample’scountryfieldvalueset toSomecountry,whichisthevaluereturnedbyinvokingConfiguration’sgetCountrymethod.

·#{configuration.state}expressionresultsinSample’sstatefieldvaluesettoSomestate,whichisthevaluereturnedbyinvokingConfiguration’sgetStatemethod.

TheaboveexampleshowsthatyoucanuseSpELtoretrieveconfigurationinformationfromotherbeans.

NOTESpELisaverypowerfulexpressionlanguage,anditoffersmanymorecapabilitiesthandescribedinthisbook.ItisrecommendedthatyourefertoSpringreferencedocumentationtoknowaboutSpEL.

Thefollowingexamplelistingshowsusageof@Valueannotationatmethod-levelandmethod-parameter-level:

Examplelisting6-21–Sampleclass-@Valueannotationusageatmethod-levelandmethod-parameter-levelProject–ch06-value-annotationSourcelocation-src/main/java/sample/spring/chapter06/beans

packagesample.spring.chapter06.beans;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.annotation.Value;@Component(value="sample")publicclassSample{

Page 227: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....privateString[]splitName;privateStringcity;@AutowiredpublicvoidsplitName(@Value("#{configuration.splitName(FirstNameLastName')}")String[]splitName){this.splitName=splitName;}@Autowired@Value("#{configuration.getCity()}")publicvoidcity(Stringcity){this.city=city;}.....}

Theaboveexamplelistingshowsthatthemethodsthatareannotatedwith@Autowiredannotationmakeuseof@Valueannotationatmethod-levelandmethod-parameter-level.Youshouldnotethatthe@Valueannotationcanbeusedatmethod-levelandmethod-parameter-levelonlyifthemethodisannotatedwith@Autowired or @Resource or @Inject annotation. SpEL expression #{configuration.splitName('FirstName LastName')} results in invocation of Configuration’s splitNamemethodwith‘FirstNameLastName’asargument.ThisshowsthatSpELexpressionscanbeusedtoinvokemethodsthatacceptarguments.

NOTE@ValueannotationisprocessedbyaBeanPostProcessor; therefore,youshouldnotuse@Valueannotation in component classes that implement BeanFactoryPostProcessor or BeanPostProcessorinterface.

UsageofSpELisnotlimitedto@Valueannotations,youcanalsouseSpELinbeandefinitionscontainedintheapplicationcontextXMLfile.

IMPORTchapter6/ch06-spel-example(ThisprojectshowsanapplicationthatusesSpELexpressionsin bean definitions. To run the application, execute the main method of the SampleApp class of thisproject.)

ThefollowingexamplelistingshowshowSpELisusedinbeandefinitions:

Examplelisting6-22–applicationContext.xml–SpELexpressionsinbeandefinitionsProject–ch06-spel-exampleSourcelocation-src/main/resources/META-INF/spring<beans.....><beanid="sample"class="sample.spring.chapter06.beans.Sample"><propertyname="environment"value="#{configuration.environment}"/><propertyname="currency"value="Somecurrency"/><propertyname="country"value="#{configuration.getCountry()}"/>

Page 228: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<propertyname="state"value="#{configuration.state}"/></bean><beanid="configuration"class="sample.spring.chapter06.beans.Configuration"/></beans>

The above example listing shows that the bean definition for the Sample class makes use of SpELexpressions(thatrefertoConfigurationbean)tosetdefaultvaluesforenvironment,currency,countryandstateproperties.

Let’s now look at how you can perform validation of objects in Spring applications using Spring’sValidatorinterface.

Page 229: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-9ValidatingobjectsusingSpring’sValidatorinterfaceSpring’sValidator interface is part of SpringValidationAPI that allows you to perform validation ofobjects.YoucanusetheValidatorinterfaceforperformingvalidationofobjectsinanyoftheapplicationlayers.Forinstance,youcanusetheValidatorinterfacetovalidateobjectsintheweblayeraswellasinthepersistencelayer.

NOTEAnalternativetousingtheValidatorinterfaceistouseJSR303annotationstospecifyconstraintsthatapplyonanobject.JSR303annotationsareexplainedinthenextsection.

IMPORT chapter 6/ch06-validator-interface (This project shows the MyBank application that usesSpring’sValidator interface tovalidateFixedDepositDetailsobject.To run theapplication, execute themainmethodoftheBankAppclassofthisproject.)

The FixedDepositDetails object of MyBank application represents details of a fixed deposit. ThefollowingexamplelistingshowstheFixedDepositDetailsclass:

Examplelisting6-23–FixedDepositDetailsclassProject–ch06-validator-interfaceSourcelocation-src/main/java/sample/spring/chapter06/bankapp/domain

packagesample.spring.chapter06.bankapp.domain;publicclassFixedDepositDetails{privatelongid;privatefloatdepositAmount;privateinttenure;privateStringemail;publicFixedDepositDetails(longid,floatdepositAmount,inttenure,Stringemail){this.id=id;this.depositAmount=depositAmount;this.tenure=tenure;this.email=email;}.....//--gettersandsettersforinstancevariablespublicfloatgetDepositAmount(){returndepositAmount;}…..}

Theaboveexample listing shows that theFixedDepositDetails classdefines id,depositAmount, tenureandemailinstancevariables.Let’ssaythatbeforethefixeddepositdetailsaresavedinthesystem,weneedtomakesurethatthefixeddepositamount(representedbythedepositAmountinstancevariable)is

Page 230: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

not0.

To validate the FixedDepositDetails object’s depositAmount property, we need to create animplementation of Spring’s Validator interface. The following example listing shows a validator forobjectsoftypeFixedDepositDetails:

Examplelisting6-24–FixedDepositValidatorclass–Spring’sValidatorinterfaceimplementationProject–ch06-validator-interfaceSourcelocation-src/main/java/sample/spring/chapter06/bankapp/validator

packagesample.spring.chapter06.bankapp.validator;importorg.springframework.validation.Errors;importorg.springframework.validation.Validator;publicclassFixedDepositValidatorimplementsValidator{@Overridepublicbooleansupports(Class<?>clazz){returnFixedDepositDetails.class.isAssignableFrom(clazz);}@Overridepublicvoidvalidate(Objecttarget,Errorserrors){FixedDepositDetailsfixedDepositDetails=(FixedDepositDetails)target;if(fixedDepositDetails.getDepositAmount()==0){errors.reject("zeroDepositAmount");}}}

The Validator interface defines supports and validate methods. The supports method checks if thesupplied object instance (represented by the clazz attribute) can be validated. If the supports methodreturns true, the validate method is used to validate the object. In the above example listing, theFixedDepositValidator’s supports method checks if the supplied object instance is of typeFixedDepositDetails. If the supportsmethod returns true, the FixedDepositValidator’s validate methodvalidates the object. The validate method accepts the object instance to be validated, and an Errorsinstance.TheErrorsinstance’srejectmethodisusedtostoreerrorsthatoccurduringvalidation.YoucanlaterinspecttheErrorsinstancetoknowmoreaboutvalidationerrors.

The following example listing shows that the FixedDepositServiceImpl’s createFixedDeposit methodusestheFixedDepositValidator(referexamplelisting6-24)tovalidateFixedDepositDetailsobjects:

Examplelisting6-25–FixedDepositServiceImplclass–ValidatingFixedDepositDetailsobjectProject–ch06-validator-interfaceSourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;

Page 231: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importorg.springframework.validation.BeanPropertyBindingResult;importsample.spring.chapter06.bankapp.validator.FixedDepositValidator;@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{@Autowired@Qualifier(value="myFixedDepositDao")privateFixedDepositDaomyFixedDepositDao;@OverridepublicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{BeanPropertyBindingResultbindingResult=newBeanPropertyBindingResult(fixedDepositDetails,"Errors");FixedDepositValidatorvalidator=newFixedDepositValidator();validator.validate(fixedDepositDetails,bindingResult);if(bindingResult.getErrorCount()>0){logger.error("ErrorswerefoundwhilevalidatingFixedDepositDetailsinstance");}else{myFixedDepositDao.createFixedDeposit(fixedDepositDetails);logger.info("Createdfixeddeposit");}}}

FixedDepositServiceImpl’s createFixedDeposit method validates the FixedDepositDetails object(representedbyfixedDepositDetailsargument)beforeitissavedintothedatastorebyFixedDepositDao.ThecreateFixedDepositmethodshownintheaboveexamplelistingperformsthefollowingtasks:

· creates an instance of FixedDepositValidator and Spring’s BeanPropertyBindingResult - adefaultimplementationofErrorsinterfaceprovidedout-of-the-boxbySpring

·invokesFixedDepositValidator’svalidatemethod,passingFixedDepositDetailsobjectandtheBeanPropertyBindingResultinstance

· invokesBeanPropertyBindingResult’sgetErrorCountmethod tocheck ifanyvalidationerrorswerereported.Ifnovalidationerrorsarereported,FixedDepositDao’screateFixedDepositmethodiscalledtosavefixeddepositdetailsinthedatastore.

The followingexample listing showsBankApp’smainmethod that invokesFixedDepositServiceImpl’screateFixedDepositmethod(referexamplelisting6-25)tocheckifthevalidationisperformedcorrectlybyFixedDepositValidator’svalidatemethod:

Examplelisting6-26–BankAppclassProject–ch06-validator-interfaceSourcelocation-src/main/java/sample/spring/chapter06/bankapp

Page 232: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

packagesample.spring.chapter06.bankapp;publicclassBankApp{publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,0,12,"[email protected]"));FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,12,"[email protected]"));}}

First, FixedDepositService’s createFixedDeposit method is passed a FixedDepositDetails object withdepositAmountvalueas0,followedbyaFixedDepositDetailsobjectwithdepositAmountvalueas1000.

IfyouexecuteBankApp’smainmethod,you’llseethefollowingoutputontheconsole:ErrorswerefoundwhilevalidatingFixedDepositDetailsinstanceCreatedfixeddeposit

The output ‘Errors were found while validating FixedDepositDetails instance’ shows thatFixedDepositValidator reported errors when the FixedDepositDetails instance with 0 as thedepositAmountvaluewasvalidated.Theoutput‘Createdfixeddeposit’showsthatthenoerrorswerereportedwhentheFixedDepositDetailsinstancewith1000asthedepositAmountvaluewasvalidated.

NOTE Spring’s Validator interface is typically used in Spring MVC based web applications whilebindinginformationenteredbyauserintheHTMLformtothecorrespondingform-backingobject.

Let’snowlookathowyoucanspecifyconstraintsonbeanpropertiesusingJSR303annotations,andletSpringperformthevalidation.

Page 233: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-10SpecifyingconstraintsusingJSR303annotationsJSR 303 (Bean Validation API) allows you to use annotations to specify constraints on JavaBeanscomponents.WhenusingJSR303withSpring,youannotatebeanpropertieswithJSR303annotations,andSpringtakescareofvalidatingthebeanandprovidingthevalidationresult.

IMPORTchapter6/ch06-jsr303-validation(ThisprojectshowstheMyBankapplicationthatusesJSR303annotations.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject.)

The following example listing shows the FixedDepositDetails class that makes use of JSR 303annotations:

Examplelisting6-27–FixedDepositDetailsclass–JSR303annotationsProject–ch06-jsr303-validationSourcelocation-src/main/java/sample/spring/chapter06/bankapp/domain

packagesample.spring.chapter06.bankapp.domain;importjavax.validation.constraints.*;importorg.hibernate.validator.constraints.NotBlank;publicclassFixedDepositDetails{@NotNullprivatelongid;@Min(1000)@Max(500000)privatefloatdepositAmount;@Min(6)privateinttenure;@NotBlank@Size(min=5,max=100)privateStringemail;publicFixedDepositDetails(longid,floatdepositAmount,inttenure,Stringemail){this.id=id;this.depositAmount=depositAmount;this.tenure=tenure;this.email=email;}.....}

@NotNull,@Min,@Max,@NotBlankand@SizearesomeoftheannotationsdefinedbyJSR303BeanValidationAPI.TheaboveexamplelistingshowsthatbyusingJSR303annotationsFixedDepositDetails

Page 234: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

classclearlyspecifiestheconstraintsthatapplyonitsfields.Ontheotherhand,ifyouareusingSpringValidationAPItovalidateanobject,constraintinformationiscontainedintheValidator implementation(referexamplelisting6-24).

The following table describes the constraints enforced by JSR 303 annotations on theFixedDepositDetailsobjectshowninexamplelisting6-27:

JSR303annotation Constraintdescription

@NotNull

Theannotatedfieldmustnotbenull.

Forinstance,FixedDepositDetails’idfieldmustnotbenull.

@MinTheannotatedfield’svaluemustbegreaterthanorequaltothespecifiedminimumvalue.

Forinstance,@Min(1000)annotationondepositAmountfieldofFixedDepositDetailsobjectmeansthatdepositAmount’svaluemustbegreaterthanorequalto1000.

@MaxTheannotatedfield’svaluemustbelessthanorequaltothespecifiedvalue.

For instance, @Max(500000) annotation on depositAmount field of FixedDepositDetailsobjectmeansthatthedepositAmount’svaluemustbelessthanorequalto500000.

@NotBlankTheannotatedfield’svaluemustnotbenullorempty.

Forinstance,FixedDepositDetails’emailfieldmustnotbeemptyornull.

@Size

Theannotatedfield’ssizemustbebetweenthespecifiedminandmaxattributes.

Forinstance,@Size(min=5,max=100)annotationonemailfieldofFixedDepositDetailsobjectmeansthatthesizeoftheemailfieldmustbegreaterthanorequalto5andlessthanorequalto100.

NOTETouseJSR303annotations,ch06-jsr303-validationprojectspecifiesdependencyonJSR303APIJARfile(validation-api-1.0.0.GA)andHibernateValidatorframework(hibernate-validation-4.3.0.Final).TheHibernateValidatorframeworkprovidesthereferenceimplementationforJSR303.

Ifyoulookattheimportstatementsinexamplelisting6-27,you’llnoticethatthe@NotBlankannotationisdefinedbyHibernateValidatorframework,andnotbyJSR303.HibernateValidatorframeworkprovidesadditionalannotationsthatyoucanusealongwithJSR303annotations.

Now, that we have specified JSR 303 constraints on FixedDepositDetails class, let’s look at how tovalidateFixedDepositDetailsobjectusingSpring.

JSR303supportinSpringSpring supports validating objects that make use of JSR 303 constraints. Spring’sLocalValidatorFactoryBeanclass is responsible fordetecting thepresenceofaJSR303provider (likeHibernate Validator) in the application’s classpath and initializing it. It is important to note that theLocalValidatorFactoryBean implements JSR 303’s Validator andValidatorFactory interfaces, and alsoSpring’sValidatorinterface.

The following example listing shows the configuration of LocalValidatorFactoryBean class in theapplicationcontextXMLfile:

Examplelisting6-28–applicationContext.xml–Spring’sLocalValidatorFactoryBeanconfigurationProject–ch06-jsr303-validationSourcelocation-src/main/resources/META-INF/spring

<beanid="validator"

Page 235: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

Asyoucansee,LocalValidatorFactoryBeanisconfiguredlikeanyotherSpringbean.NowthatwehaveconfiguredLocalValidatorFactoryBean,let’sseehowitisusedtoperformvalidation.

The following example listing shows the FixedDepositServiceImpl class which requires that theFixedDepositDetailsobjectisvalidatedbeforefixeddepositdetailsaresavedinthedatastore:

Examplelisting6-29–FixedDepositServiceImplclass–validatingFixedDepositDetailsobjectProject–ch06-jsr303-validationSourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;importorg.springframework.validation.BeanPropertyBindingResult;importorg.springframework.validation.Validator;.....@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{@AutowiredprivateValidatorvalidator;@Autowired@Qualifier(value="myFixedDepositDao")privateFixedDepositDaomyFixedDepositDao;@OverridepublicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{BeanPropertyBindingResultbindingResult=newBeanPropertyBindingResult(fixedDepositDetails,"Errors");validator.validate(fixedDepositDetails,bindingResult);if(bindingResult.getErrorCount()>0){logger.error("ErrorswerefoundwhilevalidatingFixedDepositDetailsinstance");}else{myFixedDepositDao.createFixedDeposit(fixedDepositDetails);logger.info("Createdfixeddeposit");}}}

Theaboveexample listingshows thatSpring’sValidator implementation is referencedby thevalidatorfield. As LocalValidatorFactoryBean implements Spring’s Validator interface,LocalValidatorFactoryBean instance is assigned to the validator field. FixedDepositServiceImpl’screateFixedDeposit method invokes Validator’s validate method to perform validation ofFixedDepositDetailsobject.

Page 236: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Oneoftheinterestingthingstonoticeinexamplelisting6-29isthatwearenotdealingwithJSR303APIto perform validation of FixedDepositDetails object. Instead, we have used Spring Validation API toperformvalidation.ThisispossiblebecauseLocalValidatorFactoryBeanimplementsvalidatemethodofSpring’sValidator interface touseJSR303API toperformvalidationofobjects,shieldingdevelopersfromJSR303-specificAPIdetails.

As LocalValidatorFactoryBean implements JSR 303’s Validator and ValidatorFactory interfaces, youhavetheoptiontouseJSR303APItoperformvalidationofFixedDepositDetailsobject.ThefollowingexamplelistingshowsanalternativeimplementationofFixedDepositServiceImplclassthatmakesuseofJSR303’sValidatortoperformvalidation:

Examplelisting6-30–FixedDepositServiceImplJsr303class-validatingFixedDepositDetailsobjectProject–ch06-jsr303-validationSourcelocation-src/main/java/sample/spring/chapter06/bankapp/service

packagesample.spring.chapter06.bankapp.service;importjavax.validation.ConstraintViolation;importjavax.validation.Validator;@Service(value="FixedDepositServiceJsr303")publicclassFixedDepositServiceJsr303ImplimplementsFixedDepositService{.....@AutowiredprivateValidatorvalidator;@Autowired@Qualifier(value="myFixedDepositDao")privateFixedDepositDaomyFixedDepositDao;@OverridepublicvoidcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{Set<ConstraintViolation<FixedDepositDetails>>violations=validator.validate(fixedDepositDetails);Iterator<ConstraintViolation<FixedDepositDetails>>itr=violations.iterator();if(itr.hasNext()){logger.error("ErrorswerefoundwhilevalidatingFixedDepositDetailsinstance");}else{myFixedDepositDao.createFixedDeposit(fixedDepositDetails);logger.info("Createdfixeddeposit");}}}

TheaboveexamplelistingshowsthatJSR303’sValidatorimplementationisreferencedbythevalidator

Page 237: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

field. As LocalValidatorFactoryBean implements JSR 303’s Validator interface,LocalValidatorFactoryBean instance is assigned to the validator field. The createFixedDepositmethodvalidatesFixedDepositDetailsobjectbycallingValidator’svalidatemethod.Thevalidatemethodreturnsajava.util.SetobjectthatcontainstheconstraintviolationsreportedbyJSR303provider.Youcancheckthejava.util.Setobjectreturnedbythevalidatemethodtoknowifanyconstraintviolationswerereported.For instance, in the above example listing, the createFixedDeposit method calls FixedDepositDao’screateFixedDepositmethodonlyifjava.util.Setdoesn’tcontainanyconstraintviolations.

Inthissection,wesawhowtouseSpring’ssupportforJSR303toperformvalidationofobjects.Weonlylookedatconstraints,like@NotNull,@Size,andsoon,thatareprovidedout-of-the-boxbyJSR303.ItisimportanttonotethatJSR303allowsyoutocreatecustomconstraintsandusetheminyourapplication.Forinstance,youcancreatea@MyConstraintcustomconstraintandacorrespondingvalidatortoenforcethatconstraintonobjects.

Let’snowlookatannotationsthatyoucanusetoprogrammaticallyconfigureSpringbeans.

Page 238: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-11 Programmatically configuring Spring beans using@Configurationand@BeanannotationsYoucanuse@Configurationand@BeanannotationstoprogrammaticallyconfigureSpringbeans.Ifyouannotate a classwith@Configuration annotation, it indicates that the class contains@Bean annotatedmethodsthatreturnbeaninstancesmeanttoberegisteredwiththeSpringcontainer.NOTETouse@Configurationannotatedclassesfordefiningbeans,CGLIBlibraryisrequiredbecauseSpringextends@Configurationannotatedclassestoaddbehaviortothe@Beanannotatedmethods.StartingwithSpring3.2,theCGLIBclassesarepackagedwithinthespring-coreJARfileitself;therefore,youdon’tneedtoexplicitlyspecifythatyourprojectisdependentonCGLIBJARfile.

IMPORTchapter6/ch06-bankapp-configuration(ThisprojectshowstheMyBankapplicationthatuses@Configuration and@Bean annotations to programmatically configure beans. To run the application,executethemainmethodoftheBankAppclassofthisproject.)

The following example listing shows the BankAppConfiguration class that is annotated with@Configurationannotation:Examplelisting6-31–BankAppConfigurationclass-@Configurationand@BeanannotationsProject–ch06-bankapp-configurationSourcelocation-src/main/java/sample/spring/chapter06/bankapppackagesample.spring.chapter06.bankapp;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Scope;.....@ConfigurationpublicclassBankAppConfiguration{.....@Bean(name="customerRegistrationService")@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)publicCustomerRegistrationServicecustomerRegistrationService(){returnnewCustomerRegistrationServiceImpl();}.....}

BankAppConfigurationclassdefines@Beanannotatedmethodsthatreturnbeaninstances.@Bean’snameattributespecifiesthenamewithwhichthereturnedbeaninstanceisregisteredwiththeSpringcontainer.@Scopeannotationspecifiesthescope(singletonorprototype)ofthereturnedbeaninstance.

NOTE@Scope annotation is also used at the type-level to specify the scope of a Spring component.

Page 239: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Referexamplelisting6-14thatshowsusageof@Scopeannotationattype-level.

In example listing 6-31, the customerRegistrationService method returns an instance ofCustomerRegistrationServicebeanthatisregisteredwiththeSpringcontainerasaprototype-scopedbeannamedcustomerRegistrationService.ThecustomerRegistrationServicemethodhasthesameeffectasthefollowingbeandefinitionintheapplicationcontextXMLfile:

<beanid="customerRegistrationService"scope="prototype”class="sample.spring.chapter06.bankapp.service.CustomerRegistrationServiceImpl"/>

Thefollowingtabledescribestheattributesof@Beanannotationthatyoucanusetoconfigurethebeaninstance:

Valueoftypeattribute Description

Autowire

Sameas<bean>element’sautowireattribute(refersection4-6ofchapter4toknowmoreabout autowire attribute). If the bean returned by the @Bean annotated method isdependentonotherbeans,youcanuseautowire attribute to instructSpring to performautowiringofdependenciesbynameortype.

initMethod Sameas<bean>element’sinit-method attribute (refer section 5-2 of chapter 5 to knowmoreaboutinit-methodattribute)

destroyMethod Same as <bean> element’s destroy-method attribute (refer section 5-2 of chapter 5 toknowmoreaboutdestroy-methodattribute)

Itisimportanttonotethat@Beanannotatedmethodsmayalsobeannotatedwith@Lazy,@DependsOn,@Primaryand@Scopeannotations.Theseannotationsapplytotheobjectinstancereturnedbythe@Beanannotatedmethod.Forinstance,@DependsOnannotationspecifiestheimplicitdependenciesoftheobjectinstance returned by the @Bean annotated method. Also, if the bean instance returned by @Beanannotated method implements lifecycle interfaces (like InitializingBean and DisposableBean), andSpring’s*Aware interfaces (likeApplicationContextAware,BeanNameAware, and so on), it’ll receivecallbacksfromtheSpringcontainer.

In the examples thatwe have seen so far,we created an instance ofClassPathXmlApplicationContextclass (an implementationofApplicationContext interface) to represent theSpring container. If you areusing an @Configuration annotated class as the source of beans, you need to create an instance ofAnnotationConfigApplicationContext class (another implementation ofApplicationContext interface) torepresenttheSpringcontainer.

The following example listing shows the BankApp class that creates an instance ofAnnotationConfigApplicationContext class and retrieves beans from the newly createdAnnotationConfigApplicationContextinstance:

Examplelisting6-32–BankAppclass-AnnotationConfigApplicationContextusageProject–ch06-bankapp-configurationSourcelocation-src/main/java/sample/spring/chapter06/bankapppackagesample.spring.chapter06.bankapp;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;publicclassBankApp{

Page 240: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicstaticvoidmain(Stringargs[])throwsException{AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(BankAppConfiguration.class);.....FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,12,"[email protected]"));.....}}

In the above example listing, the BankAppConfiguration class is passed as an argument to theAnnotationConfigApplicationContext’s constructor. As AnnotationConfigApplicationContext classimplementsApplicationContextinterface,youcanaccessregisteredbeansinthesamewayasincaseofClassPathXmlApplicationContext.

You should note that@Bean annotated methods can also be defined in@Component and JSR 330’s@Namedannotatedclasses. Incaseyouhavedefinedbeans inmultiple@Configuration,@Componentand @Named annotated classes, pass all these classes to the AnnotationConfigApplicationContext’sconstructor.

The following example listing shows @Bean annotated methods of BankAppConfiguration class thatreturnaBeanFactoryPostProcessorandaBeanPostProcessorimplementation:

Example listing 6-33 – BankAppConfiguration class – defining BeanFactoryPostProcessor andBeanPostProcessorbeansProject–ch06-bankapp-configurationSourcelocation-src/main/java/sample/spring/chapter06/bankapp

packagesample.spring.chapter06.bankapp;importorg.springframework.context.annotation.Bean;@ConfigurationpublicclassBankAppConfiguration{.....@BeanpublicExampleBeanPostProcessorexampleBeanPostProcessor(){returnnewExampleBeanPostProcessor();}@BeanpublicstaticBeanNamePrinterBeanFactoryPostProcessorapplicationConfigurer(){returnnewBeanNamePrinterBeanFactoryPostProcessor();}}

Page 241: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

In theaboveexample listing,ExampleBeanPostProcessor instance representsaBeanPostProcessor thatprints a message on the console before and after a newly created bean instance is initialized, andBeanNamePrinterBeanFactoryPostProcessor instance represents a BeanFactoryPostProcessorimplementationthatprintsnamesofallthebeansregisteredwiththeSpringcontainer.

Ifyougotoch06-bankapp-configurationprojectandexecuteBankApp’smainmethod,you’llnotice thattheBeanNamePrinterBeanFactoryPostProcessor is invoked before any bean defined in@Configurationannotatedclass iscreatedby theSpringcontainer,and theExampleBeanPostProcessor is invokedeachtimeanewbeaninstanceiscreatedbytheSpringcontainer.Thisshowsthatwhetheryouconfigurebeansdeclaratively (via application context XML file) or programmatically (via @Configuration annotatedclass), beans that implement callback interfaces (like ApplicationContextAware, BeanNameAware,InitializingBean, DisposableBean, BeanFactoryPostProcessor, and so on) receive callback from theSpringcontainer.

Page 242: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

6-12SummaryThischapterlookedatannotationsthatyoucanusetosimplifydevelopingSpringapplications.Welookedat how to designate a bean class as a Spring component using Spring’s @Component, @Service,@Repositoryand@Controller annotations,performclasspath scanning toautomatically registerSpringcomponents with container, validate objects using Spring Validation API and JSR 303’s annotations,performdependencyinjectionusingSpring’s@Autowired,JSR330’s@InjectandJSR250’s@Resourceannotations,anduse@Configurationand@Bean annotations to configurebeansprogrammatically.ThenextchaptershowshowSpringsimplifiesinteractingwithdatabases.

Page 243: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter7-DatabaseinteractionusingSpring

Page 244: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

7-1IntroductionSpringsimplifiesinteractionwithdatabasesbyprovidingalayerofabstractionontopofJDBC.Springalso simplifies using ORM (Object Relational Mapping) frameworks, like Hibernate(http://www.hibernate.org/) and MyBatis (http://www.mybatis.org), for database interaction. In thischapter, we’ll look at examples that demonstrate how Spring simplifies developing applications thatinteractwithdatabases.

NOTETheexamplesdescribedinthischaptermakeuseofHibernate4.IfyouareusingHibernate 3, the changes that you’ll need tomake to the configuration are specified atrelevantplaces.We’llbeginthischapterbylookingatasampleapplicationthatusesSpring’sJDBCabstractiontointeractwithMySQL database. After that, we we’ll develop the same application using Spring’s support forHibernate framework. We’ll wrap this chapter by looking at Spring’s support for programmatic anddeclarativetransactionmanagement.

Let’sfirstlookattheMyBankapplication’srequirementsthatwe’llbedevelopinginthischapter.

Page 245: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

7-2MyBankapplication’srequirementsMyBankapplicationisaninternetbankingapplicationthatallowsbankcustomerstocheckbankaccountdetails, generate bank statement, create fixeddeposits, request chequebook, and soon.The followingfigure shows the BANK_ACCOUNT_DETAILS and FIXED_DEPOSIT_DETAILS tables in whichMyBankapplication’sdataisstored:

Figure7-1DatabasetablesusedbytheMyBankapplication

BANK_ACCOUNT_DETAILS table contains information about bank accounts, andFIXED_DEPOSIT_DETAILS table contains information about fixed deposits. The above figure showsthat there is many-to-one relationship between FIXED_DEPOSIT_DETAILS andBANK_ACCOUNT_DETAILS tables. When a bank customer opens a new fixed deposit, the fixeddeposit amount is deducted from the BANK_ACCOUNT_DETAILS table’s BALANCE_AMOUNTcolumn,andthefixeddepositdetailsaresavedintheFIXED_DEPOSIT_DETAILStable.

ThecolumnsofBANK_ACCOUNT_DETAILStableare:

·ACCOUNT_ID–accountidentifierthatuniquelyidentifiesacustomer’sbankaccount.

· BALANCE_AMOUNT – holds the current balance in the bank account.When a customerrequestsforopeningafixeddeposit,thefixeddepositamountisdeductedfromthiscolumn.

·LAST_TRANSACTION_TS–specifiesthedate/timewhenthelasttransactionwasperformedonthisaccount.

ThecolumnsofFIXED_DEPOSIT_DETAILStableare:

·FIXED_DEPOSIT_ID–fixeddepositidentifierthatuniquelyidentifiesafixeddeposit.Whenacustomeropensa fixeddeposit,aunique fixeddeposit identifier isgeneratedby theMyBankforfuturereferencebythecustomer.ThevalueofFIXED_DEPOSIT_IDcolumnisauto-generatedbyMySQLdatabase.

· ACCOUNT_ID–foreignkeythat identifies thebankaccountwithwhichthefixeddeposit isassociated.Everyquarter,interestgeneratedbythefixeddepositiscreditedintothebankaccountidentifiedbythiscolumn.

·FD_CREATION_DATE–thedateonwhichthefixeddepositwascreated

·AMOUNT–fixeddepositamount

·TENURE–fixeddeposittenure(inmonths).Fixeddeposittenuremustbegreaterthanorequal

Page 246: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

to12monthsandlessthanorequalto60months.

·ACTIVE–indicateswhetherthefixeddepositiscurrentlyactiveornot.Anactivefixeddepositgeneratesinterestonthefixeddepositamount.

Let’snowlookathowwecancreatetheMyBankapplicationusingSpring’sJDBCmodule.

Page 247: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

7-3DevelopingtheMyBankapplicationusingSpring’sJDBCmoduleSpring’sJDBCmodulesimplifiesinteractionwithdatasourcesbytakingcareoflowerleveldetailsofopeningandclosingconnections,managingtransactions,processingexceptions,andsoon.Inthissection,we’ll develop the MyBank application (as described in the previous section) using Spring’s JDBCmodule. For the sake of simplicity, we’ll develop only the services and DAOs that form part of theMyBankapplication.

IMPORTchapter7/ch07-bankapp-jdbc(ThisprojectshowstheMyBankapplicationthatusesSpring’sJDBC module to interact with the database. To run the application, execute the main method of theBankAppclassof thisproject.BeforeexecutingBankApp’smainmethod, installMySQLdatabase andexecutethespring_bank_app_db.sqlSQLscriptcontainedinthesqlfolderofch07-bankapp-jdbcproject.Executing spring_bank_app_db.sql script creates SPRING_BANK_APP_DB database and addsBANK_ACCOUNT_DETAILS and FIXED_DEPOSIT_DETAILS tables to theSPRING_BANK_APP_DB database. Also, modify the src/main/resources/META-INF/spring/database.propertiesfiletopointtoyourMySQLinstallation.)

InMyBankapplication,youfirstneedtoconfigureajavax.sql.DataSourceobjectthatidentifiesthedatasourcewithwhichtheMyBankapplicationinteracts,followedbyimplementingDAOsthatuseSpring’sJDBCmoduleclassestointeractwiththedatasource.Let’slookateachofthesestepsindetail.

ConfiguringadatasourceIf you are using Spring to develop a standalone application, you can configure the data source in theapplication context XML file. If you are developing an enterprise application, you can define a datasource that is bound to the application server’s JNDI, and retrieve the JNDI-bound data source in theapplicationcontextXMLfileforusebytheapplication.Incaseofch07-bankapp-jdbcproject, thedatasourceisconfiguredintheapplicationcontextXMLfile.

The following example listing shows how MyBank application’s data source is configured in theapplicationcontextXMLfile:

Examplelisting7-1–applicationContext.xml–datasourceconfigurationProject–ch07-bankapp-jdbcSourcelocation-src/main/resources/META-INF/spring<context:property-placeholderlocation="classpath*:META-INF/spring/database.properties"/><beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><propertyname="driverClassName"value="${database.driverClassName}"/><propertyname="url"value="${database.url}"/><propertyname="username"value="${database.username}"/><propertyname="password"value="${database.password}"/></bean>

Intheaboveexamplelisting,the<property-placeholder>element(refersection5-4ofchapter5formoredetails)ofSpring’scontextschemaloadspropertiesfromtheMETA-INF/spring/database.properties file

Page 248: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

andmakesthemavailabletobeandefinitionsintheapplicationcontextXMLfile.ThedataSourcebeanrepresentsajavax.sql.DataSourceobjectthatactsasafactoryforcreatingconnectionstothedatasource.BasicDataSourceclass isan implementationof javax.sql.DataSource interface that supportsconnectionpooling feature. BasicDataSource class is part of Apache Commons DBCP project(http://commons.apache.org/dbcp/) and supports database connection pooling feature. The values fordriverClassName, url, username and password properties of BasicDataSource class comes from thepropertiesdefinedinthedatabase.propertiesfile.TheclosemethodofBasicDataSourceclassclosesallidle connections in the pool. As the bean definition for the BasicDataSource class specifies value ofdestroy-methodattributeasclose,allidleconnectionsinthepoolareclosedwhenthedataSourcebeaninstanceisdestroyedbytheSpringcontainer.

ConfiguringadatasourceinJavaEEenvironments

If you are developing an enterprise application that is deployed in an application server, you can useSpring’sjeeschema’s<jndi-lookup>elementtomaketheJNDI-bounddatasourceavailableasaSpringbeanintheApplicationContext:

<jee:jndi-lookupjndi-name="java:comp/env/jdbc/bankAppDb"id="dataSource"/>

here,jndi-nameattributespecifiestheJNDInamewithwhichthejavax.sql.DataSourceobjectisboundtotheJNDI,andidattributespecifiesthenamewithwhichthejavax.sql.DataSourceobjectisregisteredasabeanintheApplicationContext.

Let’snowlookatsomeoftheSpring’sJDBCmoduleclassesthatyoucanuseinyourDAOstointeractwiththedatabase.

CreatingDAOsthatuseSpring’sJDBCmoduleclassesSpring’sJDBCmoduledefinesmultipleclassesthatsimplifydatabaseinteraction.We’llfirstlookattheJdbcTemplateclassthatisattheheartofSpring’sJDBCmodule.Theotherclassesthatwe’lldiscussinthis section are NamedParameterJdbcTemplate and SimpleJdbcInsert. To learn about other Spring’sJDBCmoduleclasses,refertoSpring’sreferencedocumentation.

JdbcTemplate

JdbcTemplateclasstakescareofmanagingConnection,StatementandResultSetobjects,catchingJDBCexceptions and translating them into easily understandable exceptions (likeIncorrectResultSetColumnCountException and CannotGetJdbcConnectionException), performing batchoperations,andsoon.AnapplicationdeveloperonlyneedstoprovideSQLtotheJdbcTemplateclass,andextractresultsaftertheSQLisexecuted.

AsJdbcTemplateactsasawrapperaroundjavax.sql.DataSourceobject,youdon’tneedtodirectlydealwithajavax.sql.DataSourceobject.AJdbcTemplateinstanceistypicallyinitializedwithreferencetothejavax.sql.DataSource object from which it needs to obtain connections, as shown in the followingexamplelisting:

Examplelisting7-2–applicationContext.xml–JdbcTemplateconfigurationProject–ch07-bankapp-jdbcSourcelocation-src/main/resources/META-INF/spring

Page 249: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"><propertyname="dataSource"ref="dataSource"/></bean><beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource".....>.....</bean>

TheaboveexamplelistingshowsthattheJdbcTemplateclassdefinesadataSourcepropertythatreferstoajavax.sql.DataSourceobject.

If your application uses a JNDI-bound data source, use the <jndi-lookup> element of jee schema toregistertheJNDI-bounddatasourceasabeanwiththeSpringcontainer.Now,thetheJdbcTemplateclasscan refer to the javax.sql.DataSource bean registered by the <jndi-lookup> element, as shown in thefollowingexamplelisting:

Examplelisting7-3–JdbcTemplateconfigurationforJNDI-bounddatasource<beans.....xmlns:jee="http://www.springframework.org/schema/jee"xsi:schemaLocation=".....http://www.springframework.org/schema/jeehttp://www.springframework.org/schema/jee/spring-jee-4.0.xsd"><beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"><propertyname="dataSource"ref="dataSource"/></bean><jee:jndi-lookupjndi-name="java:comp/env/jdbc/bankAppDb"id="dataSource"/>

.....</beans>

Intheaboveexamplelisting,referencetoSpring’sjeeschemaisincludedintheapplicationcontextXMLfile. The <jndi-lookup> element retrieves javax.sql.DataSource object from JNDI and exposes it as abeannameddataSource,whichisreferencedbytheJdbcTemplateclass.

JdbcTemplateinstanceisthread-safe,whichmeansmultipleDAOsofyourapplicationcansharethesameinstance of JdbcTemplate class to interact with the database. The following example listing showsFixedDepositDaoImpl’screateFixedDepositmethodthatmakesuseofJdbcTemplatetosavefixeddepositdetailsinthedatabase:

Examplelisting7-4–FixedDepositDaoImplclass–savingdatausingJdbcTemplateProject–ch07-bankapp-jdbcSourcelocation-src/main/java/sample/spring/chapter07/bankapp/daopackagesample.spring.chapter07.bankapp.dao;

Page 250: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importjava.sql.*;importorg.springframework.jdbc.core.JdbcTemplate;importorg.springframework.jdbc.core.PreparedStatementCreator;importorg.springframework.jdbc.support.GeneratedKeyHolder;importorg.springframework.jdbc.support.KeyHolder;importorg.springframework.stereotype.Repository;@Repository(value="FixedDepositDao")publicclassFixedDepositDaoImplimplementsFixedDepositDao{@AutowiredprivateJdbcTemplatejdbcTemplate;.....publicintcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails){finalStringsql="insertintofixed_deposit_details(account_id,fixedDeposit_creation_date,amount,tenure,active)values(?,?,?,?,?)";KeyHolderkeyHolder=newGeneratedKeyHolder();jdbcTemplate.update(newPreparedStatementCreator(){@OverridepublicPreparedStatementcreatePreparedStatement(Connectioncon)throwsSQLException{PreparedStatementps=con.prepareStatement(sql,newString[]{"fixed_deposit_id"});ps.setInt(1,fixedDepositDetails.getBankAccountId());ps.setDate(2,newjava.sql.Date(fixedDepositDetails.getFixedDepositCreationDate().getTime()));.....returnps;}},keyHolder);returnkeyHolder.getKey().intValue();}.....}

In the above example listing, the FixedDepositDaoImpl class is annotatedwith Spring’s@RepositoryannotationbecausetheFixedDepositDaoImplclassrepresentsaDAOclass.JdbcTemplate instance thatwe configured in the application context XML file (refer example listing 7-2) is autowired into theFixedDepositDaoImpl class. JdbcTemplate’s update method accepts an instance ofPreparedStatementCreatorandan instanceofKeyHolder.PreparedStatementCreator is used to perform

Page 251: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

insert,updateordeleteoperationonthedatabase.Spring’sKeyHolderinterfacerepresentsaholderforthekeysthatareauto-generatedwheninsertSQLstatementsareexecuted.GeneratedKeyHolderclass isthedefaultimplementationofKeyHolderinterface.

Once the INSERT SQL statement is successfully executed, the auto-generated keys are added to theGeneratedKeyHolderinstance.Youcanextracttheauto-generatedkeysfromtheGeneratedKeyHolderbycalling thegetKeymethod. Inexample listing7-4, thecreateFixedDepositmethod inserts fixeddepositdetailsintotheFIXED_DEPOSIT_DETAILStableandreturnstheauto-generatedkey.Examplelisting7-4showsthatyoudon’tneedtoworryaboutcatchingSQLExceptionthatmaybethrownbytheexecutionof PreparedStatement. This is because JdbcTemplate is responsible for catching SQLExceptions andhandlingthem.

Let’snowlookatNamedParameterJdbcTemplateclass.

NamedParameterJdbcTemplate

Asshowninexamplelisting7-4,ifyouareusingJdbcTemplateclassfordatabaseinteraction,parametersto be passed to the SQL statement are specified using ? placeholders. Spring’sNamedParameterJdbcTemplateisawrapperaroundJdbcTemplateinstancethatallowsyoutousenamedparametersintheSQLstatementratherthanusing?.

Thefollowingexample listingshowshowtheNamedParameterJdbcTemplateclass isconfigured in theapplicationcontextXMLfile:

Examplelisting7-5–applicationContext.xml–NamedParameterJdbcTemplateconfigurationProject–ch07-bankapp-jdbcSourcelocation-src/main/resources/META-INF/spring<beanid="namedJdbcTemplate"class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"><constructor-argindex="0"ref="dataSource"/></bean><beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource".....>.....</bean>

The above example listing shows that the NamedParameterJdbcTemplate class acceptsjavax.sql.DataSourceobjectasconstructorargument.

The following example listing shows the FixedDepositDaoImpl class that usesNamedParameterJdbcTemplatetofetchfixeddepositdetailsfromtheFIXED_DEPOSIT_DETAILStable:

Examplelisting7-6–FixedDepositDaoImplclass–NamedParameterJdbcTemplateusageProject–ch07-bankapp-jdbcSourcelocation-src/main/java/sample/spring/chapter07/bankapp/daopackagesample.spring.chapter07.bankapp.dao;

Page 252: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importjava.sql.ResultSet;importorg.springframework.jdbc.core.RowMapper;importorg.springframework.jdbc.core.namedparam.MapSqlParameterSource;importorg.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;importorg.springframework.jdbc.core.namedparam.SqlParameterSource;.....@Repository(value="FixedDepositDao")publicclassFixedDepositDaoImplimplementsFixedDepositDao{.....@AutowiredprivateNamedParameterJdbcTemplatenamedParameterJdbcTemplate;.....publicFixedDepositDetailsgetFixedDeposit(finalintFixedDepositId){finalStringsql="select*fromfixed_deposit_detailswherefixed_deposit_id=:FixedDepositId";SqlParameterSourcenamedParameters=newMapSqlParameterSource("FixedDepositId",FixedDepositId);returnnamedParameterJdbcTemplate.queryForObject(sql,namedParameters,newRowMapper<FixedDepositDetails>(){publicFixedDepositDetailsmapRow(ResultSetrs,introwNum)throwsSQLException{FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();fixedDepositDetails.setActive(rs.getString("active"));.....returnfixedDepositDetails;}});}}

NamedParameterJdbcTemplate instance that we configured in the application context XML file (referexamplelisting7-5)isautowiredintoFixedDepositDaoImplclass.Intheaboveexamplelisting,theSQLquery passed to NamedParameterJdbcTemplate’s queryForObject method contains a named parameterFixedDepositId. The named parameter values are supplied via an implementation of Spring’sSqlParameterSource interface. MapSqlParameterSource class is an implementation ofSqlParameterSource interface thatstoresnamedparameters(andtheirvalues) ina java.util.Map. In theabove example listing, MapSqlParameterSource instance holds value of FixedDepositId namedparameter.NamedParameterJdbcTemplate’squeryForObjectmethodexecutesthesuppliedSQLqueryandreturnsasingleobject.Spring’sRowMapperobjectisusedformappingeachreturnedrowtoanobject.In the above example listing, RowMapper maps the returned row in the ResultSet to aFixedDepositDetailsobject.

Let’snowlookatSpring’sSimpleJdbcInsertclass.

Page 253: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

SimpleJdbcInsert

SimpleJdbcInsertclassmakesuseofdatabasemetadatatosimplifycreatingabasicSQLinsertstatementforatable.

ThefollowingexamplelistingshowstheBankAccountDaoImplclassthatmakesuseofSimpleJdbcInserttoinsertbankaccountdetailsintoBANK_ACCOUNT_DETAILStable:

Examplelisting7-7–BankAccountDaoImplclass–SimpleJdbcInsertusageProject–ch07-bankapp-jdbcSourcelocation-src/main/java/sample/spring/chapter07/bankapp/daopackagesample.spring.chapter07.bankapp.dao;importjavax.sql.DataSource;importorg.springframework.jdbc.core.simple.SimpleJdbcInsert;.....@Repository(value="bankAccountDao")publicclassBankAccountDaoImplimplementsBankAccountDao{privateSimpleJdbcInsertinsertBankAccountDetail;@AutowiredprivatevoidsetDataSource(DataSourcedataSource){this.insertBankAccountDetail=newSimpleJdbcInsert(dataSource).withTableName("bank_account_details").usingGeneratedKeyColumns("account_id");}@OverridepublicintcreateBankAccount(finalBankAccountDetailsbankAccountDetails){Map<String,Object>parameters=newHashMap<String,Object>(2);parameters.put("balance_amount",bankAccountDetails.getBalanceAmount());parameters.put("last_transaction_ts",newjava.sql.Date(bankAccountDetails.getLastTransactionTimestamp().getTime()));Numberkey=insertBankAccountDetail.executeAndReturnKey(parameters);returnkey.intValue();}.....}

AsthesetDataSourcemethodisannotatedwith@Autowiredannotation, javax.sql.DataSourceobject ispassed as an argument to the setDataSource method. In the setDataSource method, an instance ofSimpleJdbcInsertiscreatedbypassingreferencetojavax.sql.DataSourceobjecttotheSimpleJdbcInsertconstructor.

SimpleJdbcInsert’s withTableName method sets the name of the table into which you want to insert

Page 254: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

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.SimpleJdbcInsert’s usingGeneratedKeyColumnsmethod sets names of table columns that contain auto-generatedkeys.IncaseofBANK_ACCOUNT_DETAILStable,ACCOUNT_IDcolumncontainstheauto-generatedkey;therefore,‘account_id’stringvalueispassedtotheusingGeneratedKeyColumnsmethod.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 columnnames and their corresponding values, and returns the generated key value. You should note that theSimpleJdbcInsertclassinternallyusesJdbcTemplatetoexecutetheactualSQLinsertoperation.

IfyoulookatBankAccountDaoImplclassofch07-bankapp-jdbcproject,you’llnoticethatitmakesuseofboth SimpleJdbcInsert and JdbcTemplate classes to interact with the database. Similarly,FixedDepositDaoImpl class of ch07-bankapp-jdbc project uses both JdbcTemplate andNamedParameterJdbcTemplate classes for database interaction. This shows that you can use acombinationofSpring’sJDBCmoduleclassestointeractwithadatabase.

NOTEAsch07-bankapp-jdbcprojectmakesuseofSpring’sJDBCmoduleandusesSpring’sTransactionManagementfeature(explainedinsection7-5), thepom.xmlfileofch07-bankapp-jdbcprojectdependsonspring-jdbcandspring-txJARfiles.

Let’snowlookatBankAppclassofch07-bankapp-jdbcprojectthatcreatesabankaccountandopensafixeddepositcorrespondingtoit.

BankAppclass

BankApp class of ch07-bankapp-jdbc project runs the MyBank application as a standalone Javaapplication.BankApp’smainmethodcreatesabankaccount in theBANK_ACCOUNT_DETAILStableand creates a fixed deposit (corresponding to the newly created bank account) in theFIXED_DEPOSIT_DETAILStable.

ThefollowingexamplelistingshowstheBankAppclass:

Examplelisting7-8–BankAppclassProject–ch07-bankapp-jdbcSourcelocation-src/main/java/sample/spring/chapter07/bankapppackagesample.spring.chapter07.bankapp;.....publicclassBankApp{privatestaticLoggerlogger=Logger.getLogger(BankApp.class);publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");BankAccountServicebankAccountService=context.getBean(BankAccountService.class);BankAccountDetailsbankAccountDetails=newBankAccountDetails();.....

Page 255: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

intbankAccountId=bankAccountService.createBankAccount(bankAccountDetails);.....FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();.....intFixedDepositId=FixedDepositService.createFixedDeposit(fixedDepositDetails);.....}}

Intheaboveexamplelisting,theBankAccountServiceobjectinteractswithBankAccountDaoImpl (referexample listing 7-7) to create a bank account, and FixedDepositService object interacts withFixedDepositDaoImpl(referexamplelisting7-4and7-6)objecttoopenafixeddepositcorrespondingtothenewlycreatedbankaccount.IfyouexecuteBankApp’smainmethod,you’llfindthatanewrecordisinsertedintobothBANK_ACCOUNT_DETAILSandFIXED_DEPOSIT_DETAILStables.

In this section, we looked at how Spring’s JDBC module simplifies updating or fetching data fromdatabases.Spring’sJDBCmodulecanalsobeusedforthefollowingpurposes:

·executingstoredproceduresandfunctions.Forinstance,youcanuseSpring’sSimpleJdbcCallclassforexecutingstoredproceduresandfunctions

·executingpreparedstatementsinbatches

· accessing relational databases in an object-orientedmanner. For instance, you can extendSpring’s MappingSqlQuery class to create an SQL query and map the returned ResultSet to adomainobject.

·configuringanembeddeddatabaseinstance.Forinstance,youcanSpring’sjdbcschematocreatean instanceofHSQL,H2orDerbydatabases, and register thedatabase instancewith theSpringcontainerasabeanoftypejavax.sql.DataSource.

Let’s now look at how we can use Spring’s support for Hibernate ORM framework to interact withdatabases.

Page 256: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

7-4DevelopingtheMyBankapplicationusingHibernateSpring’sORMmoduleprovides integrationwithHibernate, JavaPersistenceAPI (JPA),MyBatis, andJavaDataObjects(JDO).Inthissection,we’llseehowSpringsimplifiesusingHibernateframeworkfordatabase interaction. As Hibernate itself is a JPA provider, we’ll use JPA annotations to map ourpersistententityclassestodatabasetables.

IMPORT chapter 7/ch07-bankapp-hibernate (This project shows the MyBank application that usesHibernatetointeractwiththedatabase.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject.)

Let’sfirstlookathowtoconfigureHibernate’sSessionFactoryinstance.

ConfiguringSessionFactoryinstanceSessionFactoryisafactoryforcreatingHibernate’sSessionobject.ItistheSessionobjectthatisusedbyDAOs to perform create, read, delete and update operations on persistent entities. Spring’sorg.springframework.orm.hibernate4.LocalSessionFactoryBean(aFactoryBeanimplementation)createsaSessionFactoryinstancethatcanbeusedbyDAOclassesforobtainingaSessioninstance.

NOTE If you want to use JPA’s EntityManager in your application’s DAOs for database interaction,configure Spring’s LocalContainerEntityManagerFactoryBean instead oforg.springframework.orm.hibernate4.LocalSessionFactoryBean.

The following example listing shows how the LocalSessionFactoryBean class is configured in theapplicationcontextXMLfile:

Examplelisting7-9–applicationContext.xml-LocalSessionFactoryBeanconfigurationProject–ch07-bankapp-hibernateSourcelocation-src/main/java/sample/spring/chapter07/bankapp<beanid="sessionFactory"class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"><propertyname="dataSource"ref="dataSource"/><propertyname="packagesToScan"value="sample.spring"/></bean>

ThedataSourcepropertyspecifiesreferencetoabeanoftypejavax.sql.DataSource.ThepackagesToScanpropertyspecifiesthepackage(s)underwhichSpringlooksforpersistentclasses.Forinstance,theaboveexample listing specifies that if a persistent class is annotated with JPA’s@Entity annotation, and islocated inside sample.spring package (or its sub-packages), it is automatically detected byorg.springframework.orm.hibernate4.LocalSessionFactoryBean.AnalternativetousingpackagesToScanpropertyistoexplicitlyspecifyallthepersistentclassesusingannotatedClassesproperty,asshowninthefollowingexamplelisting:

Examplelisting7-10LocalSessionFactoryBean’sannotatedClassesproperty<beanid="sessionFactory"

Page 257: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"><propertyname="dataSource"ref="dataSource"/><propertyname="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 thepersistentclassesintheapplication.

NOTEIfyouareusingHibernate3,useSpring’sorg.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBeaninsteadoforg.springframework.orm.hibernate4.LocalSessionFactoryBeantocreateaSessionFactoryinstance.

As we have configured LocalSessionFactoryBean, let’s now look at DAOs that make use ofSessionFactoryinstancecreatedbyLocalSessionFactoryBeantoperformdatabaseoperations.

CreatingDAOsthatuseHibernateAPIfordatabaseinteractionTointeractwith thedatabase,DAOsneedaccess toHibernate’sSessionobject.ToaccessHibernate’sSession object, inject the SessionFactory instance created by LocalSessionFactoryBean bean (referexample listing 7-9) into DAOs, and use the injected SessionFactory instance to obtain a Sessioninstance.

ThefollowingexamplelistingshowstheFixedDepositDaoImplclassthatusesHibernateAPIforsavingandretrievingtheFixedDepositDetailspersistententity:

Examplelisting7-11–FixedDepositDaoImplclass-HibernateAPIusageProject–ch07-bankapp-hibernateSourcelocation-src/main/java/sample/spring/chapter07/bankapp/daopackagesample.spring.chapter07.bankapp.dao;importorg.hibernate.SessionFactory;.....@Repository(value="FixedDepositDao")publicclassFixedDepositDaoImplimplementsFixedDepositDao{@AutowiredprivateSessionFactorysessionFactory;publicintcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails){sessionFactory.getCurrentSession().save(fixedDepositDetails);returnfixedDepositDetails.getFixedDepositId();}

Page 258: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicFixedDepositDetailsgetFixedDeposit(finalintFixedDepositId){Stringhql="fromFixedDepositDetailsasFixedDepositDetailswhere"+"FixedDepositDetails.FixedDepositId="+FixedDepositId;return(FixedDepositDetails)sessionFactory.getCurrentSession().createQuery(hql).uniqueResult();}}

The above example listing shows that an instance of SessionFactory is autowired intoFixedDepositDaoImplinstance,whichislaterusedbycreateFixedDepositandgetFixedDepositmethodstosaveandretrieveFixedDepositDetailspersistententity.AutowiringofSessionFactoryinstanceshowsthatyoucanautowireanobjectcreatedbySpring’sFactoryBeanimplementationbysimplydefiningthetype created by the FactoryBean and annotating it with@Autowired annotation (refer section 3-9 ofchapter 3 to know more about Spring’s FactoryBean interface). The createFixedDeposit andgetFixedDeposit methods call SessionFactory’s getCurrentSession method to obtain an instance ofSession. It is important to note that the call to getCurrentSession method returns the Session objectassociatedwiththecurrenttransactionorthread.UsinggetCurrentSessionmethodisusefulifyouwantSpringtomanagetransactions,whichisthecaseinMyBankapplication.

Let’snowlookatSpring’sprogrammaticanddeclarativetransactionmanagementfeature.

Page 259: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

7-5TransactionmanagementusingSpringSpringFrameworksupportsbothprogrammaticanddeclarativetransactionmanagement.Inprogrammatictransactionmanagement,Spring’stransactionmanagementabstractionisusedtoexplicitlystart,endandcommit transactions. Indeclarative transactionmanagement,youannotatemethods thatexecutewithinatransactionwithSpring’s@Transactionalannotation.

Let’sfirstlookatthetransactionmanagementrequirementofMyBankapplicationdescribedinsection7-2.

MyBank’stransactionmanagementrequirementsInsection7-2,itwasmentionedthatwhenabankcustomeropensanewfixeddeposit,thefixeddepositamountisdeductedfromtheBANK_ACCOUNT_DETAILStable’sBALANCE_AMOUNTcolumn,andthefixeddepositdetailsaresavedintheFIXED_DEPOSIT_DETAILStable.

ThefollowingsequencediagramshowsthatthecreateFixedDepositmethodofFixedDepositServiceImplclasssavesthefixeddepositdetailsinFIXED_DEPOSIT_DETAILStableanddeductsthefixeddepositamountfromthecorrespondingbankaccountinBANK_ACCOUNT_DETAILStable:

Figure7-2 The sequence of actions performed byMyBank applicationwhen a customer opens a newfixeddeposit

The above sequence diagram shows that FixedDepositServiceImpl’s createFixedDeposit method callsFixedDepositDaoImpl’s createFixedDeposit method and BankAccountDaoImpl’s subtractFromAccountmethod. FixedDepositDaoImpl’s createFixedDeposit method saves the fixed deposit details in theFIXED_DEPOSIT_DETAILS table. BankAccountDaoImpl’s subtractFromAccount method first checksthat thecustomer’sbankaccountcontainssufficientbalance tocreate the fixeddepositof thespecifiedamount. If sufficientbalance is available in customer’sbankaccount, the subtractFromAccountmethoddeductsthefixeddepositamountfromthecustomer’sbankaccount.Ifsufficientbalanceisn’tavailable,an exception is thrown by BankAccountDaoImpl’s subtractFromAccount method. IfFixedDepositDaoImpl’s createFixedDeposit or BankAccountDaoImpl’s subtractFromAccount method

Page 260: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

failsforsomereason,thesystemwillbeleftinaninconsistentstate;therefore,boththemethodsmustbeexecutedwithinatransaction.

Let’s now look at how you can use Spring to programmatically manage transactions in the MyBankapplication.

ProgrammatictransactionmanagementYoucanprogrammaticallymanagetransactionsbyusingSpring’sTransactionTemplateclassorbyusingan implementation of Spring’s PlatformTransactionManager interface. TransactionTemplate classsimplifies transactionmanagement by taking care of initiating and committing transactions. You onlyneedtoprovideanimplementationofSpring’sTransactionCallbackinterfacethatcontainsthecodetobeexecutedwithinatransaction.

IMPORT chapter 7/ch07-bankapp-tx-jdbc (This project shows the MyBank application that usesSpring’sTransactionTemplateclassforprogrammaticallymanagingtransactions.Toruntheapplication,execute the main method of the BankApp class of this project. Create SPRING_BANK_APP_DBdatabase, andBANK_ACCOUNT_DETAILSandFIXED_DEPOSIT_DETAILS tables as described forch07-bankapp-jdbcproject)

ThefollowingexamplelistingshowshowtheTransactionTemplateclassisconfiguredintheapplicationcontextXMLfile:

Examplelisting7-12–applicationContext.xml-TransactionTemplateconfigurationProject–ch07-bankapp-tx-jdbcSourcelocation-src/main/resources/META-INF/spring<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource".....>.....</bean><beanid="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><propertyname="dataSource"ref="dataSource"/></bean><beanid="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 Spring’s PlatformTransactionManagerimplementationthatisresponsibleformanagingtransactions.

TransactionTemplate’sisolationLevelNamepropertyspecifiesthetransactionisolationleveltobesetforthetransactionsmanagedbythetransactionmanager.ThevalueofisolationLevelNamepropertyrefersto

Page 261: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

a constant defined by Spring’s TransactionDefinition interface. For instance,ISOLATION_READ_UNCOMMITTED is a constant defined by TransactionDefinition interface thatindicatesthattheuncommittedchangesbyatransactioncanbereadbyothertransactions.

TransactionTemplate’s propagationBehaviorName property specifies the transaction propagationbehavior. The value of propagationBehaviorName property refers to a constant defined by Spring’sTransactionDefinition interface. For instance, PROPAGATION_REQUIRED is a constant defined byTransactionDefinitioninterfacethatindicates:

·ifamethodisnotinvokedwithinatransaction,thetransactionmanagerstartsanewtransactionandexecutesthemethodinthenewlycreatedtransaction

·ifamethodisinvokedwithinatransaction,thetransactionmanagerexecutesthemethodinthesametransaction

Springprovidesa coupleofbuilt-inPlatformTransactionManager implementations that you can choosefrom, depending upon the data access technology used by your application. For instance,DataSourceTransactionManager isappropriate formanaging transactions inapplications thatuse JDBCforinteractingwithadatabase,HibernateTransactionManagerisappropriatewhenHibernateisusedfordatabase interactionand JpaTransactionManagerwhen JPA’sEntityManager is used for data access. Inexample listing 7-12, TransactionTemplate’s transactionManager property refers to aDataSourceTransactionManager instance because the MyBank application of ch07-bankapp-tx-jdbcproject uses JDBC for data access. The example listing 7-12 shows thatDataSourceTransactionManager’s dataSource property refers to a javax.sql.DataSource object thatrepresentsthedatabasewhosetransactionsaremanagedbytheDataSourceTransactionManagerinstance.

Thefollowingexample listingshows theFixedDepositServiceImplclass thatusesTransactionTemplateinstancefortransactionmanagement:

Examplelisting7-13–FixedDepositServiceImplclassthatusesTransactionTemplateProject–ch07-bankapp-tx-jdbcSourcelocation-src/main/java/sample/spring/chapter07/bankapp/service

packagesample.spring.chapter07.bankapp.service;importorg.springframework.transaction.TransactionStatus;importorg.springframework.transaction.support.TransactionCallback;importorg.springframework.transaction.support.TransactionTemplate;.....@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{@AutowiredprivateTransactionTemplatetransactionTemplate;.....@OverridepublicintcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails)throwsException{transactionTemplate.execute(newTransactionCallback<FixedDepositDetails>(){

Page 262: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicFixedDepositDetailsdoInTransaction(TransactionStatusstatus){try{myFixedDepositDao.createFixedDeposit(fixedDepositDetails);bankAccountDao.subtractFromAccount(fixedDepositDetails.getBankAccountId(),fixedDepositDetails.getFixedDepositAmount());}catch(Exceptione){status.setRollbackOnly();}returnfixedDepositDetails;}});returnfixedDepositDetails.getFixedDepositId();}.....}

TheaboveexamplelistingshowsFixedDepositServiceImpl’screateFixedDepositmethod(referfigure7-2formoredetails)thatsavesfixeddepositdetailsintheFIXED_DEPOSIT_DETAILStable,anddeductsthefixeddepositamountfromthecorrespondingbankaccountintheBANK_ACCOUNT_DETAILStable.

You create an implementation of TransactionCallback interface to define the actions that you want toexecutewithinatransaction.And,TransactionTemplate’sexecutemethodexecutestheactionscontainedin the TransactionCallback instance within a transaction. TransactionCallback interface defines adoInTransaction method that you implement to provide the actions that should be executed within atransaction. TransactionCallback’s doInTransaction method is invoked within a transaction byTransactionTemplate’sexecutemethod.ThedoInTransactionmethod accepts aTransactionStatus objectthatyoucanusetocontroltheoutcomeofthetransaction.Inexamplelisting7-13,TransactionCallback’sdoInTransaction method contains calls to FixedDepositDaoImpl’s createFixedDeposit method andBankAccountDaoImpl’ssubtractFromAccountmethodbecausewewantboththemethodstobeexecutedwithinasingle transaction.Aswe’dwant torollbackthe transactionifeitherof themethodsfails, thesetRollbackOnly method of TransactionStatus is invoked in case of an exception. If you callTransactionStatus’ssetRollbackOnlymethod,theTransactionTemplateinstancerollbacksthetransaction.A transactionwill be automatically rolledback if the actions contained in thedoInTransactionmethodresultinajava.lang.RuntimeException.

TransactionCallbackinstanceacceptsagenerictypeargumentwhichreferstotheobjecttypereturnedbythe doInTransactionmethod. In example listing 7-13, a FixedDepositDetails object is returned by thedoInTransaction method. If you don’t want the doInTransaction method to return any object, use theTransactionCallbackWithoutResultabstractclassthatimplementstheTransactionCallbackinterface.TheTransactionCallbackWithoutResult class allows you to create TransactionCallback implementations inwhichdoInTransactionmethoddoesn’treturnavalue.

The following example listing shows the main method of BankApp class that callsBankAccountServiceImpl’s createBankAccount method to create a bank account, andFixedDepositServiceImpl’s createFixedDeposit method to create a fixed deposit corresponding to thenewlycreatedbankaccount:

Page 263: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting7-14–BankAppclassProject–ch07-bankapp-tx-jdbcSourcelocation-src/main/java/sample/spring/chapter07/bankapp

packagesample.spring.chapter07.bankapp;publicclassBankApp{.....publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");BankAccountServicebankAccountService=context.getBean(BankAccountService.class);FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);BankAccountDetailsbankAccountDetails=newBankAccountDetails();bankAccountDetails.setBalanceAmount(1000);.....intbankAccountId=bankAccountService.createBankAccount(bankAccountDetails);FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();fixedDepositDetails.setFixedDepositAmount(1500);fixedDepositDetails.setBankAccountId(bankAccountId);.....intFixedDepositId=FixedDepositService.createFixedDeposit(fixedDepositDetails);.....}}

The above example listing shows that a bank account is first createdwith a balance amount of 1000,followedbycreatingafixeddepositofamount1500.Asfixeddepositamountisgreaterthanthebalancein the bank account, BankAccountDaoImpl’s subtractFromAccount method throws an exception (referBankAccountDaoImpl’ssubtractFromAccountmethodorfigure7-2).

If you execute BankApp’s main method, you’ll notice that the fixed deposit is not created in theFIXED_DEPOSIT_DETAILS table, and 1500 amount is not deducted from theBANK_ACCOUNT_DETAILS table.This shows that bothFixedDepositDaoImpl’s createFixedDepositandBankAccountDaoImpl’ssubtractFromAccountareexecutedinthesametransaction.

Instead of using TransactionTemplate class, you can directly use a PlatformTransactionManagerimplementation to programmatically manage transactions. When using PlatformTransactionManagerimplementation, you are required to explicitly initiate and commit (or roll back) transactions. For thisreason, it is recommended to use TransactionTemplate instead of directly using aPlatformTransactionManagerimplementation.

Let’snowlookatdeclarativetransactionmanagementfeatureofSpring.

Page 264: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

DeclarativetransactionmanagementProgrammatictransactionmanagementcouplesyourapplicationcodewithSpring-specificclasses.Ontheother hand, declarative transactionmanagement requires you to only annotatemethods or classeswithSpring’s@Transactional annotation. If youwant to execute amethodwithin a transaction, annotate themethod with @Transactional annotation. If you want to execute all the methods of a class within atransaction,annotatetheclasswith@Transactionalannotation.

NOTEInsteadofusing@Transactionalannotationfordeclarativetransactionmanagement,youcanuseSpring’stxschemaelementstoidentifytransactionalmethods.AsusingSpring’stxschemaresultsinverboseapplicationcontextXMLfile,we’llbeonlylookingatusing@Transactionalannotationfordeclarativetransactionmanagement.

IMPORTchapter7/ch07-bankapp-jdbcandchapter7/ch07-bankapp-hibernate (The ch07-bankapp-jdbc project shows theMyBank application that uses Spring’s JDBCmodule for database interaction(refersection7-3tolearnmoreaboutch07-bankapp-jdbcproject).Thech07-bankapp-hibernateprojectshowstheMyBankapplicationthatusesHibernatetointeractwiththedatabase(refersection7-4tolearnmoreaboutch07-bankapp-hibernateproject).

Youenabledeclarativetransactionmanagementusing<annotation-driven>elementofSpring’stxschema.The following example listing shows the <annotation-driven> element’s usage in ch07-bankapp-jdbcproject:

Examplelisting7-15–applicationContext.xml-<annotation-driven>elementProject–ch07-bankapp-jdbcSourcelocation-src/main/resources/META-INF/spring<beans.....xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation=".....http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-4.0.xsd">.....<tx:annotation-driventransaction-manager="txManager"/><beanid="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><propertyname="dataSource"ref="dataSource"/></bean>.....</beans>

In the above example listing,Spring’s txschema is included so that its elements are accessible in theapplication context XML file. The <annotation-driven> element enables declarative transactionmanagement.The<annotation-driven>element’s transaction-managerattributespecifies reference to thePlatformTransactionManager implementation to use for transaction management. The above examplelisting shows that the DataSourceTransactionManager is used as the transaction manager in ch07-bankapp-jdbcproject.

The following example listing shows how you can use declarative transaction management in ch07-

Page 265: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

bankapp-hibernateprojectthatusesHibernateORMfordataaccess:

Examplelisting7-16–applicationContext.xml-<annotation-driven>elementProject–ch07-bankapp-hibernateSourcelocation-src/main/resources/META-INF/spring<beans.....xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation=".....http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-4.0.xsd">.....<tx:annotation-driventransaction-manager="txManager"/><beanid="txManager"class="org.springframework.orm.hibernate4.HibernateTransactionManager"><propertyname="sessionFactory"ref="sessionFactory"/></bean>.....</beans>

If you compare the above example listing with 7-15, you’ll notice that the only difference is in thePlatformTransactionManager implementation referenced by the transaction-manager attribute of<annotation-driven> element. The above example listing shows that if Hibernate ORM is used fordatabase interaction, the org.springframework.orm.hibernate4.HibernateTransactionManagerimplementationofPlatformTransactionManagerisusedformanagingtransactions.

NOTE If you are using Hibernate 3, set transaction-manager attribute toorg.springframework.orm.hibernate3.HibernateTransactionManager instead oforg.springframework.orm.hibernate4.HibernateTransactionManager.

The followingexample listing shows theFixedDepositServiceImpl class thatmakesuseof declarativetransactionmanagement:

Examplelisting7-17–FixedDepositServiceImplclass-@TransactionalannotationusageProject–ch07-bankapp-jdbcSourcelocation-src/main/java/sample/spring/chapter07/bankapp/service

packagesample.spring.chapter07.bankapp.service;importorg.springframework.transaction.annotation.Transactional;.....@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{.....@Transactional

Page 266: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicintcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails)throwsException{bankAccountDao.subtractFromAccount(fixedDepositDetails.getBankAccountId(),fixedDepositDetails.getFixedDepositAmount());returnmyFixedDepositDao.createFixedDeposit(fixedDepositDetails);}.....}

Intheaboveexamplelisting,thecreateFixedDepositmethodisannotatedwith@Transactionalannotation.ThismeansthatthecreateFixedDepositmethodisexecutedwithinatransaction.Thetransactionmanagerspecifiedviathetransaction-managerattributeof<annotation-driven>element(referexamplelisting7-15and 7-16) is used for managing the transaction. If a java.lang.RuntimeException is thrown duringexecutionofcreateFixedDepositmethod,thetransactionisautomaticallyrolledback.

@Transactionalannotationdefinesattributesthatyoucanusetoconfigurethebehaviorofthetransactionmanager. For instance, you canuse the rollbackFor attribute to specify exception classes that result intransaction roll back. The exception classes specified by rollbackFor attributemust be subclasses ofjava.lang.Throwableclass.Similarly,youcanuse isolationattribute tospecify the transaction isolationlevel.

Incaseyourapplicationdefinesmultipletransactionmanagers,youcanuse@Transactionalannotation’svalueattributetospecifythebeannameofthePlatformTransactionManagerimplementationthatyouwanttouse formanaging transactions.The followingexample listingshows that2 transactionmanagers, tx1and tx2, are defined in the application context XML file. The tx1 transaction manager is used bySomeServiceImpl’smethodAandtx2transactionmanagerisusedbySomeServiceImpl’smethodB:

Examplelisting7-18–@Transactional’svalueattributeusage-----------------------SomeServiceImplclass------------------------@ServicepublicclassSomeServiceImplimplementsSomeService{.....@Transactional(value="tx1")publicintmethodA(){.....}@Transactional(value="tx2")publicintmethodB(){.....}}-----------------------applicationcontextXMLfile------------------------<tx:annotation-driven/><beanid="tx1"class="org.springframework.orm.hibernate4.HibernateTransactionManager"><propertyname="sessionFactory1"ref="sessionFactory1"/>

Page 267: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

</bean><beanid="tx2"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><propertyname="dataSource"ref="dataSource"/></bean>

Intheaboveexamplelisting,the<annotation-driven>elementofSpring’stxschemadoesn’tspecifythetransaction-manager attribute because the transaction manager to use for managing transactions isspecified by the @Transactional annotation itself. In the above example listing, @Transactionalannotation’svalueattributespecifiesthetransactionmanagertouseformanagingtransactions.Thismeansthat SomeServiceImpl’s methodA executes under tx1 transaction manager and SomeServiceImpl’smethodBexecutesundertx2transactionmanager.

Let’snowlookatSpring’ssupportforJTA(JavaTransactionAPI)transactions.

Spring’ssupportforJTAInchapter1,wediscussedthatwhenmultipletransactionalresourcesareinvolvedinatransaction,JTAisused for transaction management. Spring provides a generic JtaTransactionManager class (aPlatformTransactionManager implementation) that you can use in applications to manage JTAtransactions.

Figure 7-3 JTA transaction managers and resource-specific transaction managers implementPlatformTransactionManagerinterface

Inmost application server environments, the JtaTransactionManagerwillmeet your requirements.But,Spring also provides vendor-specific PlatformTransactionManager implementations that leverageapplication server-specific features to manage JTA transactions. The vendor-specific JTA transactionmanagers provided by Spring are: OC4JJtaTransactionManager (for Oracle OC4J),WebLogicJtaTransactionManager (for WebLogic application server),WebSphereUowTransactionManager (for WebSphere application server). Figure 7-3 summarizes howJTA transaction managers and resource-specific transaction managers are related to thePlatformTransactionManager interface. The figure shows that the PlatformTransactionManager isimplementedbybothJTAtransactionmanagerclassesandresource-specifictransactionmanagerclasses.

Page 268: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Let’s now look at howSpring simplifies configuring a JTA transactionmanager in application contextXMLfile.

ConfiguringaJTAtransactionmanagerusing<jta-transaction-manager>element

Spring’s tx schema provides a <jta-transaction-manager> element that automatically detects theapplication server inwhich the application is deployed and configures an appropriate JTA transactionmanager.This saves the effort for explicitly configuring an application server-specific JTA transactionmanager in the application contextXML file.For instance, if youdeployan application inWebSphereapplication server, the <jta-transaction-manager> element configures an instance ofWebSphereUowTransactionManager instance. If the same application is deployed in WebLogicapplication server, the <jta-transaction-manager> element configures an instance ofWebLogicJtaTransactionManagerinstance.IftheapplicationisdeployedinanyapplicationserverotherthanOC4J,WebSphere orWebLogic, the <jta-transaction-manager> element configures an instance ofJtaTransactionManagerinstance.

Page 269: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

7-6SummaryIn this chapter, we saw that Spring supports database interaction using JDBC and Hibernate ORMframework. We also saw how we can use Spring to manage transactions programmatically anddeclaratively. In thenext chapter,we’ll lookathowSpring simplifies sendingemails, interactionwithmessagingmiddlewares,andperformtransparentcachingofdata.

Page 270: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter8-Messaging,emailing,asynchronousmethodexecution,andcachingusingSpring

Page 271: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-1IntroductionIn the previous chapter,we saw that Spring simplifies database interaction. In the context ofMyBankapplication,thischaptergoesastepfurtherandshowshowSpringsimplifies:

·sendingandreceivingJMSmessagesfromaJMSprovider,likeActiveMQ

·sendingemailmessages

·asynchronouslyexecutingmethods

·storingandretrievingdatafromcache

Let’sfirstlookattheMyBankapplication’srequirementsthatwe’llimplementinthischapter.

Page 272: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-2MyBankapplication’srequirementsMyBank application allows its customers to open fixed deposits and retrieve details of their existingfixeddeposits.Figure8-1showsthesequenceofeventsthatoccurwhenacustomerrequestsforopeninganewfixeddeposit.

First, FixedDepositService’s createFixedDeposit method is invoked that sends 2 JMS messages – amessage containing customer’s email id, and a message that contains fixed deposit details.EmailMessageListenerretrieves theJMSmessagecontaining theemail idof thecustomerandsendsanemail to the customer informing that the request for opening a fixed deposit has been received.FixedDepositMessageListenerretrievestheJMSmessagecontainingfixeddepositdetailsandsavesthefixeddepositdetailsinthedatabase.

A scheduled job runs every 5 seconds to check if any new fixed deposits have been created in thedatabase. If the job finds any new fixed deposits, it subtracts the fixed deposit amount from the bankaccountof thecustomerandsendsanemail tothecustomerinformingthat thefixeddepositrequesthasbeensuccessfullyprocessed.

Figure8-1MyBankapplicationbehaviorwhenacustomerrequestsforopeninganewfixeddeposit

The following diagram shows the behavior of MyBank application when FixedDepositService’sfindFixedDepositsByBankAccountmethod is invoked to retrieve all fixed deposits corresponding to abankaccount:

Page 273: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure 8-2 MyBank application behavior when a customer requests for the details of all his fixeddeposits

Theabove figure shows thatwhenFixedDepositService’s findFixedDepositsByBankAccountmethod isinvoked,thefixeddepositinformationisfetchedfromthedatabaseandcachedintomemory.IfyoucanFixedDepositService’sfindFixedDepositsByBankAccountagain,thefixeddepositinformationisfetchedfromthecacheandnotfromthedatabase.

Let’s now look at how Spring is used in the MyBank application to send JMS messages to JMSdestinationsconfiguredinActiveMQ.

IMPORTchapter8/ch08-bankapp(Togetthemostofoutofthischapter,installMySQLdatabaseandexecute 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 addsBANK_ACCOUNT_DETAILS and FIXED_DEPOSIT_DETAILS tables to theSPRING_BANK_APP_DB database. Modify the src/main/resources/META-INF/spring/database.properties to point to yourMySQL installation. To get the email featureworking,modifysrc/main/resources/META-INF/spring/email.propertiestospecifytheemailserverandtheemailaccounttouseforsendingemails.ModifytheBankAppclasstospecifytheemailidofthecustomertowhomtheemailsaresent)

Page 274: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-3SendingJMSmessagesSpringsimplifiesinteractionwithJMSprovidersbyprovidingalayerofabstractionontopofJMSAPI.InthecontextofMyBankapplication,thissectionshowshowtosynchronouslyandasynchronouslysendandreceivemessagesfromanActiveMQbrokerusingSpring.Forthesakeofsimplicity,theActiveMQbrokerisconfiguredtoruninembeddedmodeinch08-bankappproject.

NOTEInSpring,JMSsupportclassesaredefinedinspring-jmsJARfile;therefore,youmustdefinethatyourapplicationdependsonspring-jmsJARfiletouseSpring’ssupportforJMS.

ConfiguringActiveMQbrokertoruninembeddedmodeAnembeddedActiveMQbrokerrunsinthesameJVMastheapplication.YoucanuseActiveMQ’sXMLschema to configure an embedded ActiveMQ broker in a Spring application. The following examplelisting shows howActiveMQ’s XML schema is used to configure an embedded ActiveMQ broker inMyBankapplication:

Examplelisting8-1–applicationContext.xml–embeddedActiveMQbrokerconfigurationProject–ch08-bankappSourcelocation-src/main/resources/META-INF/spring<beans.....xmlns:amq="http://activemq.apache.org/schema/core"xsi:schemaLocation=".....http://activemq.apache.org/schema/corehttp://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 toActiveMQ’sXML schema (activemq-core-5.7.0.xsd)thatallowsyoutoconfigureanembeddedActiveMQbroker.The<broker>elementconfiguresanembeddedActiveMQbrokerwithname localhost.The<transportConnectors> element specifies thetransport connectorsonwhich theembeddedActiveMQbrokerallowsclients toconnect. In theaboveexamplelisting,the<transportConnector>sub-elementof<transportConnectors>specifiesthatclientscanconnecttotheembeddedActiveMQbrokeronportnumber61616usingaTCPsocket.

Let’snowlookathowtoconfigureaJMSConnectionFactoryforcreatingconnectionstotheembeddedActiveMQinstance.

ConfiguringaJMSConnectionFactoryThe following example listing shows how a JMS ConnectionFactory is configured in the applicationcontextXMLfile:

Page 275: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting8-2–applicationContext.xml–JMSConnectionFactoryconfigurationProject–ch08-bankappSourcelocation-src/main/resources/META-INF/spring<beans.....xmlns:amq="http://activemq.apache.org/schema/core"xsi:schemaLocation=".....http://activemq.apache.org/schema/corehttp://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd.....">.....<amq:connectionFactorybrokerURL="vm://localhost"id="jmsFactory"/><beanclass="org.springframework.jms.connection.CachingConnectionFactory"id="cachingConnectionFactory"><propertyname="targetConnectionFactory"ref="jmsFactory"/></bean>.....</beans>

In the above example listing, the <connectionFactory> element of amq schema creates a JMSConnectionFactory instance that is used for creating connections to the embeddedActiveMQ instance(refer example listing8-1).ThebrokerUrl attribute specifies theURL for connecting to theActiveMQbroker.AsweareusingembeddedActiveMQbroker,thebrokerUrlspecifiesthatVMprotocol(specifiedbyvm://)isusedtoconnecttotheActiveMQbrokerinstance.

Spring’s CachingConnectionFactory is an adapter for the JMS ConnectionFactory (specified by thetargetConnectionFactory property), that provides the additional feature of caching instances of JMSSession,MessageProducerandMessageConsumer.

Let’snowlookathowtouseSpring’sJmsTemplateclasstosendJMSmessages.

SendingJMSmessagesusingJmsTemplateSpring’s JmsTemplate class simplifies synchronously sending and receiving JMS messages. For thepurpose of this chapter, we’ll only look at how to send JMS messages using JmsTemplate. LikeTransactionTemplate(refersection7-5ofchapter7)andJdbcTemplate(refersection7-3ofchapter7)classes,theJmsTemplateclassprovidesalayerofabstractionsothatyoudon’thavetodealwithlower-levelJMSAPI.

ThefollowingexamplelistingshowshowtheJmsTemplateclassisconfiguredintheapplicationcontextXMLfileofMyBankapplicationtosendmessagestotheembeddedActiveMQinstance:

Examplelisting8-3–applicationContext.xml–JmsTemplateconfigurationProject–ch08-bankappSourcelocation-src/main/resources/META-INF/spring<beans.....xmlns:amq="http://activemq.apache.org/schema/core"xsi:schemaLocation=".....http://activemq.apache.org/schema/core

Page 276: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

http://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd.....">.....<beanclass="org.springframework.jms.core.JmsTemplate"id="jmsTemplate"><propertyname="connectionFactory"ref="cachingConnectionFactory"/><propertyname="defaultDestination"ref="FixedDepositDestination"/></bean><amq:queueid="FixedDepositDestination"physicalName="aQueueDestination"/><amq:queueid="emailQueueDestination"physicalName="emailQueueDestination"/>.....</beans>

JmsTemplate’sconnectionFactorypropertyspecifiestheJMSConnectionFactorythatisusedforcreatingaconnectionwiththeJMSprovider.JmsTemplate’sdefaultDestinationpropertyreferstothedefaultJMSdestination to which the JmsTemplate sends JMS messages. In the above example listing,connectionFactorypropertyreferstotheCachingConnectionFactoryinstance(referexamplelisting8-2),anddefaultDestinationproperty refers to the JMSqueuedestinationcreatedbyamq schema’s<queue>element.

Theamqschema’s<queue>elementcreatesaJMSqueuedestinationinActiveMQ.Inexamplelisting8-3,thefirst<queue>elementcreatesaJMSqueuedestinationnamedaQueueDestinationinActiveMQ,andthe second <queue> element creates a JMS queue destination named emailQueueDestination inActiveMQ. The physicalName attribute refers to the name with which the JMS queue destination iscreated in ActiveMQ, and id attribute refers to the name with which the JMS queue destination isaccessedbyotherbeansintheSpringcontainer.Inexamplelisting8-3,JmsTemplate’sdefaultDestinationproperty refers to the id attribute of the <queue> element that creates the aQueueDestination JMSdestination; therefore, the aQueueDestination is the default JMS destination towhich the JmsTemplateinstancesendsJMSmessages.

JMSSessionusedbyJmsTemplatehas theacknowledgementmodeset toauto-acknowledgeand isnottransactedinnature.IfyouwantJmsTemplatetousetransactedSessions,setJmsTemplate’s transactedpropertytotrue.IncaseoftransactedSessions,anewtransactionbeginswhentheSessioniscreatedbytheapplication,orwhenthe transaction iscommittedorrolledback.Thismeans thata transactedJMSSession is always associated with a transaction. You can use a transacted JMS Session to send andreceive JMS messages within a transaction. If you use JmsTemplate with Spring’sJmsTransactionManager,theJmsTemplateinstancewillalwaysgetatransactedJMSSession.

Let’snowlookathowJmsTransactionManagerisconfigured,andJMSmessagesaresentbyJmsTemplatewithinatransaction.

SendingJMSmessageswithinatransactionInchapter7,wesawthatSpringprovidesacoupleofPlatformTransactionManagerimplementationsthatprovide resource-specific transaction management. In your JMS applications, you can use Spring’sJmsTransactionManager (an implementation of PlatformTransactionManager) class for managingtransactions for a single JMS ConnectionFactory. As JmsTransactionManager implementsPlatformTransactionManager, you can use TransactionTemplate for programmatically managing JMStransactionsoryoucanuse@TransactionalannotationfordeclarativelymanagingJMStransactions.

Page 277: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

ThefollowingexamplelistingshowstheconfigurationofSpring’sJmsTransactionManagerinapplicationcontextXMLfile:

Examplelisting8-4–applicationContext.xml–JmsTransactionManagerconfigurationProject–ch08-bankappSourcelocation-src/main/resources/META-INF/spring<beanid="jmsTxManager"class="org.springframework.jms.connection.JmsTransactionManager"><propertyname="connectionFactory"ref="cachingConnectionFactory"/></bean>

JmsTransactionManager’sconnectionFactorypropertyspecifiesreferencetotheJMSConnectionFactoryforwhich the JmsTransactionManagermanages transactions. In the above example listing, reference toSpring’s CachingConnectionFactory bean (refer example listing 8-2) is specified as the value forconnectionFactory property. As the CachingConnectionFactory caches JMS Sessions, usingCachingConnectionFactorywithJmsTransactionManagerresultsinreducedutilizationofresources.

IfyouwanttoprogrammaticallymanageJMStransactionsusingTransactionTemplateclass,configuretheTransactionTemplateclassintheapplicationcontextXMLfile.Ifyouwanttousedeclarativetransactionmanagement,use<annotation-driven>elementofSpring’stxschema.

ThefollowingexamplelistingshowstheFixedDepositServiceImplclassthatmakesuseofJmsTemplatetosendmessagestotheembeddedActiveMQbroker:

Examplelisting8-5–FixedDepositServiceImplclass–sendJMSmessagesusingJmsTemplateProject–ch08-bankappSourcelocation-src/main/java/sample/spring/chapter08/bankapp/servicepackagesample.spring.chapter08.bankapp.service;importjavax.jms.*;importorg.springframework.jms.core.JmsTemplate;importorg.springframework.jms.core.MessageCreator;@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{@AutowiredprivateJmsTemplatejmsTemplate;.....@Override@Transactional("jmsTxManager")publicvoidcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails)throwsException{jmsTemplate.send("emailQueueDestination",newMessageCreator(){publicMessagecreateMessage(Sessionsession)throwsJMSException{TextMessagetextMessage=session.createTextMessage();textMessage.setText(fixedDepositDetails.getEmail());

Page 278: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

returntextMessage;}});//--thisJMSmessagegoestothedefaultdestinationconfiguredfortheJmsTemplatejmsTemplate.send(newMessageCreator(){publicMessagecreateMessage(Sessionsession)throwsJMSException{ObjectMessageobjectMessage=session.createObjectMessage();objectMessage.setObject(fixedDepositDetails);returnobjectMessage;}});}.....}

The above example listing shows that JmsTemplate’s send method is used to send messages toemailQueueDestinationandaQueueDestinationJMSdestinations.Referexample listing8-3 to seehowthese JMS destinations are configured in the application context XML file. The name of the JMSdestination passed to JmsTemplate’ssendmethod is resolved to the actual JMSDestination object bySpring’s DynamicDestinationResolver instance (an implementation of Spring’s DestinationResolverinterface). If you have configured JMS destinations in the application context XML file using amqschema’s <queue> (or <topic>) element, the JMS destination name passed to the JmsTemplate’s sendmessage is the value of id attribute of the <queue> (or <topic>) element corresponding to the JMSdestinationtowhichyouwanttosendmessages.

In example listing 8-5, the FixedDepositServiceImpl’s createFixedDeposit method is annotated with@Transactional("jmsTxManager"),whichmeans that the createFixedDepositmethod executeswithin atransaction,andthetransactionismanagedbyjmsTxManagertransactionmanager(referexamplelisting8-4toseehowjmsTxManagerisconfigured).JmsTemplate’ssendmethodacceptsthenameoftheJMSdestination(towhichtheJMSmessageistobesent)andaMessageCreatorinstance.Ifyoudon’tspecifytheJMSdestination,thesendmethodsendstheJMSmessagetothedefaultdestinationthatyouconfiguredfortheJmsTemplateusingdefaultDestinationproperty(referexamplelisting8-3).

InMessageCreator’screateMessagemethodyoucreatetheJMSmessagethatyouwanttosend.Youdon’tneed to explicitly handle checked exceptions thrown by JMS API, as they are taken care by theJmsTemplate itself. Example listing 8-5 shows that if you are using JmsTemplate, you don’t need toexplicitly obtainConnection fromConnectionFactory, create Session fromConnection, and so on, forsending JMS messages. So, using JmsTemplate hides the lower-level JMS API details from thedevelopers.

In example listing 8-5, the TextMessage andObjectMessage instances represent JMSmessages. Both,TextMessage and ObjectMessage classes implement javax.jms.Message interface. In the MyBankapplication,theTextMessage instancehasbeenused tosend theemail id(asimplestringvalue)of thecustomer requesting to open a fixed deposit, and the ObjectMessage instance has been used to sendFixedDepositDetails object (a Serializable object) that contains fixed deposit information. As theFixedDepositServiceImpl’screateFixedDepositmethodexecuteswithinaJMStransaction,eitherboththemessagesaresenttotheActiveMQinstanceornone.

Page 279: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Insteadofusing@Transactionalannotation,youcanprogrammaticallymanageJMStransactionsbyusingtheTransactionTemplateclass(refersection7-5ofchapter7).Thefollowingexamplelistingshowshowyou can configure the TransactionTemplate class to use JmsTransactionManager for transactionmanagement:

Examplelisting8-6–TransactionTemplateconfiguration<beanid="jmsTxManager"class="org.springframework.jms.connection.JmsTransactionManager"><propertyname="connectionFactory"ref="cachingConnectionFactory"/></bean><beanid="transactionTemplate"class="org.springframework.transaction.support.TransactionTemplate"><propertyname="transactionManager"ref="jmsTxManager"/></bean>

In the above example listing, TransactionTemplate’s transactionManager property refers to theJmsTransactionManagerbean.

OnceyouhaveconfiguredtheTransactionTemplateclass,youcanuseittomanageJMStransactions.ThefollowingexamplelistingshowsavariantofFixedDepositServiceImpl’screateFixedDepositmethodthatusesTransactionTemplateformanagingJMStransactions:

Examplelisting8-7–ProgrammaticallymanagingJMStransactionsusingTransactionTemplatepackagesample.spring.chapter08.bankapp.service;importjavax.jms.*;importorg.springframework.jms.core.JmsTemplate;importorg.springframework.jms.core.MessageCreator;@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{@AutowiredprivateJmsTemplatejmsTemplate;@AutowiredprivateTransactionTemplatetransactionTemplate;.....publicvoidcreateFixedDeposit(finalFixedDepositDetailsfixedDepositDetails)throwsException{transactionTemplate.execute(newTransactionCallbackWithoutResult(){protectedvoiddoInTransactionWithoutResult(TransactionStatusstatus){jmsTemplate.send("emailQueueDestination",newMessageCreator(){.....});jmsTemplate.send(newMessageCreator(){.....});}

Page 280: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

});}.....}

TheaboveexamplelistingshowsthatJMSmessagesaresentfromwithinthedoInTransactionmethodofTransactionCallbackWithoutResultclasssothattheyareinthesameJMStransaction.Thisissimilartohow we programmatically managed JDBC transactions (refer section 7-5 of chapter 7) usingTransactionTemplate.

SofarwehaveseenexamplesinwhichJmsTemplateisusedtosendmessagestoapre-configuredJMSdestination.Let’snowlookathowtoconfigureJmsTemplateclass ifanapplicationusesdynamicJMSdestinations.

DynamicJMSdestinationsandJmsTemplateconfigurationIf your application uses dynamic JMS destinations (that is, JMS destinations are created by theapplicationatruntime),youmustspecifytheJMSdestinationtype(queueortopic)usingpubSubDomainpropertyofJmsTemplate.ThepubSubDomainpropertyisusedtodeterminetheJMSdestinationtypetowhichtheJmsTemplatesendsJMSmessages.Ifyoudon’tspecifythepubSubDomainproperty,bydefaultJMSqueueisassumedtobethedestinationtype.

ThefollowingexamplelistingshowstheJmsTemplatethatsendsmessagestoadynamicallycreatedJMStopic:

Examplelisting8-8–UsingJmsTemplateforsendingmessagestodynamicJMStopicdestinations--------------------------applicationContext.xml---------------------<beanclass="org.springframework.jms.core.JmsTemplate"id="jmsTemplate"><propertyname="connectionFactory"ref="cachingConnectionFactory"/><propertyname="defaultDestination"ref="FixedDepositDestination"/><propertyname="pubSubDomain"value="true"/></bean>------------------Dynamictopiccreation------------------jmsTemplate.send("dynamicTopic",newMessageCreator(){publicMessagecreateMessage(Sessionsession)throwsJMSException{session.createTopic("dynamicTopic");ObjectMessageobjectMessage=session.createObjectMessage();objectMessage.setObject(someObject);returnobjectMessage;}});

In the above example listing, JmsTemplate’s pubSubDomain property is set to true, whichmeans thatwhen dynamic destinations are used, Spring resolves a dynamic destination’s name to a JMS topic.

Page 281: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

NoticethatthenameoftheJMSdestinationpassedtoJmsTemplate’ssendmethodisdynamicTopic,andaJMS topic with the same name is created by MessageCreator’s createMessage method. As nodynamicTopic JMSdestination is configured in theapplicationcontextXMLfile,Springdoesn’tknowwhether the dynamicTopic JMS destination is a queue or a topic. As JmsTemplate’s pubSubDomainproperty is set to true, Spring’s DynamicDestinationResolver resolves dynamicTopic JMS destinationnametothedynamicTopicJMStopiccreatedatruntimebyMessageCreator’screateMessagemethod. Ifyou hadnot set JmsTemplate’s pubSubDomain property, Spring’s DynamicDestinationResolver wouldhavetriedresolvingdynamicTopicJMSdestinationnametoadynamicTopicJMSqueue.

Let’snowlookathowJmsTemplatesimplifiessendingJavaobjectsasJMSmessages.

JmsTemplateandmessageconversionJmsTemplate definesmultiple convertAndSendmethods that convert and send a Java object as a JMSmessage. By default, JmsTemplate is configured with a SimpleMessageConverter instance (animplementationofSpring’sMessageConverterinterface)thatconvertsJavaobjectstoJMSmessages,andviceversa.

MessageConverterinterfacedefinesthefollowingmethods:

·ObjecttoMessage(Objectobject,Sessionsession)–convertstheJavaobject(representedbyobjectargument)toaJMSMessageusingthesuppliedJMSSession(representedbysessionargument)

·ObjectfromMessage(Messagemessage)-convertsMessageargumenttoJavaobject

Spring’s SimpleMessageConverter class provides conversion between String and JMS TextMessage,byte[] and JMS BytesMessage, Map and JMS MapMessage, and Serializable object and JMSObjectMessage. If you want to modify the JMS Message created by JmsTemplate’s convertAndSendmethod,youcanuseaMessagePostProcessorimplementationtomakemodifications.

The following example listing shows a scenario in which aMessagePostProcessor implementation isusedtomodifytheJMSmessagecreatedbyJmsTemplate’sconvertAndSendmethod:

Examplelisting8-9–JmsTemplate’sconvertAndSendmethodusagejmsTemplate.convertAndSend("aDestination","Hello,World!!",newMessagePostProcessor(){publicMessagepostProcessMessage(Messagemessage)throwsJMSException{message.setBooleanProperty("printOnConsole",true);returnmessage;}});

In the above example listing, ‘Hello, World !!’ string is passed to the convertAndSend method. TheconvertAndSend method creates a JMS TextMessage instance and makes it available to theMessagePostProcessorimplementationtoperformanypostprocessingofthemessagebeforeitissent.Intheaboveexample listing,MessagePostProcessor’spostProcessMessagemethodsetsaprintOnConsolepropertyontheJMSmessagebeforeitissenttoaDestination.

Page 282: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

SofarwehaveseenhowtosendJMSmessagestoJMSdestinationsusingJmsTemplate.Let’snowlookat how to receive JMS messages from JMS destinations using JmsTemplate and Spring’s messagelistenercontainers.

Page 283: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-4ReceivingJMSmessagesYou can receive JMSmessages synchronously using JmsTemplate andasynchronously using Spring’smessagelistenercontainers.

SynchronouslyreceivingJMSmessagesusingJmsTemplateJmsTemplatedefinesmultiplereceivemethodsthatyoucanusetosynchronouslyreceiveJMSmessages.ItisimportanttonotethatcalltoJmsTemplate’sreceivemethodcausesthecallingthreadtoblockuntilaJMS message is obtained from the JMS destination. To ensure that the calling thread is not blockedindefinitely, you must specify an appropriate value for JmsTemplate’s receiveTimeout property. ThereceiveTimeout property specifies the amount of time (inmilliseconds) the calling thread shouldwaitbeforegivingup.

JmsTemplatealsodefinesmultiple receiveAndConvertmethods that automatically convert the receivedJMSmessage toa Javaobject.Bydefault, JmsTemplate usesSimpleMessageConverter for performingconversions.

AsynchronouslyreceivingJMSmessagesusingmessagelistenercontainersYoucanuseSpring’smessagelistenercontainerstoasynchronously receiveJMSmessages.Amessagelistener container takes careof transaction and resourcemanagement aspects, so that youcan focusonwritingthemessageprocessinglogic.

A message listener container receives messages from JMS destinations and dispatches them to JMSMessageListenerimplementationsforprocessing.Thefollowingexamplelistingshowshowtoconfigureamessagelistenercontainerusing<listener-container>elementofSpring’sjmsschema:

Examplelisting8-10–applicationContext.xml–messagelistenercontainerconfigurationProject–ch08-bankappSourcelocation-src/main/resources/META-INF/spring<beans.....xmlns:jms="http://www.springframework.org/schema/jms"xsi:schemaLocation=".....http://www.springframework.org/schema/jmshttp://www.springframework.org/schema/jms/spring-jms-4.0.xsd">.....<jms:listener-containerconnection-factory="cachingConnectionFactory"destination-type="queue"transaction-manager="jmsTxManager"><jms:listenerdestination="aQueueDestination"ref="FixedDepositMessageListener"/><jms:listenerdestination="emailQueueDestination"ref="emailMessageListener"/></jms:listener-container><beanclass="sample.spring.chapter08.bankapp.jms.EmailMessageListener"id="emailMessageListener"/><beanclass="sample.spring.chapter08.bankapp.jms.FixedDepositMessageListener"

Page 284: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

id="FixedDepositMessageListener"/>.....</beans>

In theaboveexample listing,Spring’s jms schema is included so that its elements are available in theapplicationcontextXMLfile.The<listener-container>elementconfiguresamessage listenercontainerfor each of theMessageListener implementations defined by <listener> sub-elements. The connection-factory attribute specifies reference to the JMS ConnectionFactory bean that the message listenercontainer uses to obtain connections to the JMS provider. As we are using Spring’sCachingConnectionFactory in the MyBank application, the connection-factory attribute refers to thecachingConnectionFactorybeandefinedintheapplicationcontextXMLfileofMyBankapplication(referexample listing 8-2). The destination-type attribute specifies the JMS destination type with which themessagelistenercontainerisassociatedwith.Thepossiblevaluesthatthedestination-typeattributecanacceptare:queue,topicanddurableTopic.

The transaction-manager attribute of <listener-container> element specifies aPlatformTransactionManager implementation that ensures JMS message reception and messageprocessingbyMessageListenerhappenswithina transaction. In theaboveexample listing, thevalueoftransaction-managerattributereferstotheJmsTransactionManagerimplementation(referexamplelisting8-4) configured for theMyBank application. If aMessageListener implementation interactswith othertransactional resources also, consider using Spring’s JtaTransactionManager instead ofJmsTransactionManager. In a standaloneapplication,youcanuse embedded transactionmanagers, likeAtomikos(http://www.atomikos.com/),toperformJTAtransactionsinyourapplication.

NOTE By default, the <listener-container> element creates an instance of Spring’sDefaultMessageListenerContainer class corresponding to each JMS MessageListener implementationspecifiedby<listener>sub-elements.

Each <listener> element specifies a JMS MessageListener implementation which is asynchronouslyinvoked by themessage listener container. The <listener> element’s destination attribute specifies theJMSdestinationnamefromwhichMessageListenerimplementationreceivesitsmessagesviathemessagelistener container. The <listener> element’s ref attribute specifies reference to the MessageListenerimplementation responsible for processing the JMSmessages received from the destination. Examplelisting 8-10 shows that the FixedDepositMessageListener (a MessageListener implementation) isresponsible for processing messages received from aQueueDestination destination, and theEmailMessageListener (a MessageListener implementation) is responsible for processing messagesreceivedfromemailQueueDestinationdestination.

MessageListenerinterfacedefinesanonMessagemethodthatisasynchronouslyinvokedbythemessagelistener container. The message listener container passes the JMS Message received from the JMSdestinationtotheonMessagemethod.TheonMessagemethodisresponsibleforprocessingthereceivedJMS message. The following example listing shows implementation of MyBank application’sFixedDepositMessageListenerthatisresponsibleforretrievingFixedDepositDetailsobjectfromtheJMSMessage,andthensavingthefixeddepositinformationcontainedintheFixedDepositDetailsobjectintothedatabase:

Examplelisting8-11–FixedDepositMessageListenerclass–processingJMSmessageProject–ch08-bankapp

Page 285: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/jmspackagesample.spring.chapter08.bankapp.jms;importjavax.jms.MessageListener;importjavax.jms.ObjectMessage;importsample.spring.chapter08.bankapp.domain.FixedDepositDetails;.....publicclassFixedDepositMessageListenerimplementsMessageListener{@Autowired@Qualifier(value="FixedDepositDao")privateFixedDepositDaomyFixedDepositDao;@AutowiredprivateBankAccountDaobankAccountDao;@TransactionalpublicintcreateFixedDeposit(FixedDepositDetailsfixedDepositDetails){bankAccountDao.subtractFromAccount(fixedDepositDetails.getBankAccountId(),fixedDepositDetails.getFixedDepositAmount());returnmyFixedDepositDao.createFixedDeposit(fixedDepositDetails);}@OverridepublicvoidonMessage(Messagemessage){ObjectMessageobjectMessage=(ObjectMessage)message;FixedDepositDetailsfixedDepositDetails=null;try{fixedDepositDetails=(FixedDepositDetails)objectMessage.getObject();}catch(JMSExceptione){e.printStackTrace();}if(fixedDepositDetails!=null){createFixedDeposit(fixedDepositDetails);}}}

In the above example listing, FixedDepositMessageListener’s onMessage method obtains theFixedDepositDetailsobjectfromtheJMSmessageandsavesthefixeddepositdetailsintothedatabase.FixedDepositMessageListener’screateFixedDepositmethod is responsible for saving the fixed depositinformation into the database. As the createFixedDeposit method is annotated with @Transactionalannotation, it is executed under the transaction managed byDataSourceTransactionManager (refer theapplicationContext.xmlfileofch08-bankappproject).Themessage listenercontainer receives theJMSmessageandexecutesFixedDepositMessageListener’sonMessagemethodunderthetransactionmanaged

Page 286: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

byJmsTransactionManager(referexamplelisting8-10).

As onMessage and createFixedDeposit methods execute under different transaction managers, thedatabaseupdateisnotrolledbackiftheJMStransactionfailsforsomereason,andtheJMSmessageisnot redelivered to theMessageListener if the database update fails for some reason. If youwant JMSmessagereception(andprocessing)andthedatabaseupdatetobepartofthesametransaction,youshoulduseJTAtransactions.

Inthissection,welookedathowtosendandreceiveJMSmessagesusingSpring.Let’snowlookathowSpringsimplifiessendingemails.

Page 287: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-5SendingemailsSpring simplifies sending emails from an application by providing a layer of abstraction on top ofJavaMailAPI.Springtakescareofresourcemanagementandexceptionhandlingaspects,sothatyoucanfocusonwritingthenecessarylogicrequiredtopreparetheemailmessage.

To send emails using Spring, you first need to configure Spring’s JavaMailSenderImpl class in yourapplicationcontextXMLfile.TheJavaMailSenderImpl class acts as awrapper around JavaMailAPI.The following example listing shows how JavaMailSenderImpl class is configured in MyBankapplication:

Examplelisting8-12–applicationContext.xml–JavaMailSenderImplclassconfigurationProject–ch08-bankappSourcelocation-src/main/resources/META-INF/spring<beanid="mailSender"class="org.springframework.mail.javamail.JavaMailSenderImpl"><propertyname="host"value="${email.host}"/><propertyname="protocol"value="${email.protocol}"/>.....<propertyname="javaMailProperties"><props><propkey="mail.smtp.auth">true</prop><propkey="mail.smtp.starttls.enable">true</prop></props></property></bean>

JavaMailSenderImpl class defines properties, like host, port, protocol, and so on, that provideinformationabout themail server.The javaMailProperties property specifies configuration informationthatisusedbyJavaMailSenderImplinstanceforcreatingaJavaMailSessionobject.Themail.smtp.authproperty value is set to true, which means that SMTP (Simple Mail Transfer Protocol) is used forauthentication with the mail server. The mail.smtp.starttls.enable property value is set to true, whichmeansTLS-protectedconnectionisusedforauthenticatingwiththemailserver.

Example listing8-12shows that thevaluesofsomeof thepropertiesofJavaMailSenderImplclassarespecifiedusingpropertyplaceholders.Forinstance,hostpropertyvalueisspecifiedas${email.host}andprotocol property value as ${email.protocol}. The value of these property placeholders comes fromemail.propertiesfile located insrc/main/resources/META-INF/springdirectory.Thefollowingexamplelistingshowsthecontentsofemail.propertiesfile:

Examplelisting8-13–email.propertiesProject–ch08-bankappSourcelocation-src/main/resources/META-INF/springemail.host=smtp.gmail.comemail.port=587email.protocol=smtp

Page 288: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

email.username=<enter-email-id>email.password=<enter-email-password>

The above example listing shows that email.properties file contains mail server information,communicationprotocol information,andthemailaccount touseforconnectingto themailserver.Thepropertiesspecified in theemail.properties fileareused toconfigure theJavaMailSenderImpl instance(referexamplelisting8-12).

NOTETheclassesthatprovideabstractionontopofJavaMailAPIaredefinedinspring-context-supportJARfile.So,touseSpring’ssupportforsendingemails,youmustdefinethatyourapplicationdependsonspring-context-supportJARfile.

Spring’s SimpleMailMessage class represents a simple email message. SimpleMailMessage definesproperties, like to,cc,subject, text,andsoon, thatyoucanset toconstruct theemailmessage thatyouwanttosendfromyourapplication.

The following example listing shows theMyBank’s application context XML file that configures twoSimpleMailMessageinstancescorrespondingtothetwoemailmessagesthatwesendfromtheMyBankapplication:

Examplelisting8-14–applicationContext.xml–SimpleMailMessageconfigurationProject–ch08-bankappSourcelocation-src/main/resources/META-INF/spring<beanclass="org.springframework.mail.SimpleMailMessage"id="requestReceivedTemplate"><propertyname="subject"value="${email.subject.request.received}"/><propertyname="text"value="${email.text.request.received}"/></bean><beanclass="org.springframework.mail.SimpleMailMessage"id="requestProcessedTemplate"><propertyname="subject"value="${email.subject.request.processed}"/><propertyname="text"value="${email.text.request.processed}"/></bean>

Intheaboveexamplelisting,therequestReceivedTemplatebeanrepresentstheemailmessagethatissentto the customer informing that the request for opening a fixed deposit has been received, andrequestProcessedTemplatebeanrepresents theemailmessagethat issent to thecustomerinformingthattherequestforopeningthefixeddeposithasbeensuccessfullyprocessed.SimpleMailMessage’ssubjectproperty specifies the subject lineof the email, and text property specifies thebodyof the email.Thevalues for these properties are defined in the emailtemplate.properties file, as shown in the followingexamplelisting:

Examplelisting8-15–emailtemplate.propertiesProject–ch08-bankappSourcelocation-src/main/resources/META-INF/springemail.subject.request.received=Fixeddepositrequestreceivedemail.text.request.received=Yourrequestforcreatingthefixeddeposithasbeenreceived

Page 289: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

email.subject.request.processed=Fixeddepositrequestprocessedemail.text.request.processed=Yourrequestforcreatingthefixeddeposithasbeenprocessed

We have so far seen how to configure JavaMailSenderImpl and SimpleMailMessage classes in theapplicationcontextXMLfile.Let’snowlookathowtosendemailmessages.

The following example listing shows the MyBank application’s EmailMessageListener class (a JMSMessageListener implementation) that retrieves customer’s email address from the JMS message andsendsanemailtothecustomerinformingthattherequestforopeningafixeddeposithasbeenreceived:

Examplelisting8-16–EmailMessageListenerclass–sendingemailsusingMailSenderProject–ch08-bankappSourcelocation-src/main/java/sample/spring/chapter08/bankapp/jmspackagesample.spring.chapter08.bankapp.jms;importorg.springframework.mail.MailSender;importorg.springframework.mail.SimpleMailMessage;.....publicclassEmailMessageListenerimplementsMessageListener{@AutowiredprivatetransientMailSendermailSender;@Autowired@Qualifier("requestReceivedTemplate")privatetransientSimpleMailMessagesimpleMailMessage;publicvoidsendEmail(){mailSender.send(simpleMailMessage);}publicvoidonMessage(Messagemessage){TextMessagetextMessage=(TextMessage)message;try{simpleMailMessage.setTo(textMessage.getText());}catch(Exceptione){e.printStackTrace();}sendEmail();}}

TheaboveexamplelistingshowsthattheMailSender’ssendmethodsendstheemailmessagerepresentedby the SimpleMailMessage instance. As JavaMailSenderImpl class implements Spring’s MailSenderinterface, the JavaMailSenderImpl instance (refer example listing 8-12) is autowired into theEmailMessageListener instance. SimpleMailMessage instance named requestReceivedTemplate (refer

Page 290: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

example listing 8-14) is also autowired into the EmailMessageListener instance. AsSimpleMailMessage’s to property identifies the email recipient, the onMessage method retrieves theemailidofthecustomerfromtheJMSmessageandsetsitasthevalueoftoproperty.

Spring’sMailSenderinterfacerepresentsagenericinterfacethatisindependentofJavaMailAPI,andissuited for sending simple email messages. Spring’s JavaMailSender interface (a sub-interface ofMailSender)isdependentonJavaMailAPI,anddefinesthefunctionalityforsendingMIMEmessages.AMIMEmessage isused ifyouwant tosendemailscontaining inline images,attachments,andsoon.AMIME message is represented by a MimeMessage class in JavaMail API. Spring provides aMimeMessageHelperclassandaMimeMessagePreparatorcallbackinterface thatyoucanuse tocreateandpopulateaMimeMessageinstance.

The following example listing shows the MyBank application’s FixedDepositProcessorJob class thatsubtractsthefixeddepositamountfromthecustomer’sbankaccountandsendsanemailtothecustomerinformingthattherequestforopeningthefixeddeposithasbeenprocessed:

Examplelisting8-17–FixedDepositProcessorJobclass–JavaMailSenderusageProject–ch08-bankappSourcelocation-src/main/java/sample/spring/chapter08/bankapp/jobpackagesample.spring.chapter08.bankapp.job;importjavax.mail.internet.MimeMessage;importorg.springframework.mail.javamail.JavaMailSender;publicclassFixedDepositProcessorJob{.....@AutowiredprivatetransientJavaMailSendermailSender;@Autowired@Qualifier("requestProcessedTemplate")privatetransientSimpleMailMessagesimpleMailMessage;privateList<FixedDepositDetails>getInactiveFixedDeposits(){returnmyFixedDepositDao.getInactiveFixedDeposits();}publicvoidsendEmail()throwsAddressException,MessagingException{List<FixedDepositDetails>inactiveFixedDeposits=getInactiveFixedDeposits();for(FixedDepositDetailsfixedDeposit:inactiveFixedDeposits){MimeMessagemimeMessage=mailSender.createMimeMessage();MimeMessageHelpermimeMessageHelper=newMimeMessageHelper(mimeMessage);mimeMessageHelper.setTo(fixedDeposit.getEmail());mimeMessageHelper.setSubject(simpleMailMessage.getSubject());

Page 291: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

mimeMessageHelper.setText(simpleMailMessage.getText());mailSender.send(mimeMessage);}myFixedDepositDao.setFixedDepositsAsActive(inactiveFixedDeposits);}}

TheaboveexamplelistingshowsthatJavaMailSender’ssendmethodisusedtosendaMIMEmessage.As JavaMailSenderImpl instance implements Spring’s JavaMailSender interface, JavaMailSenderImplinstance (refer example listing 8-12) is autowired into the FixedDepositProcessorJob instance.SimpleMailMessage instance named requestProcessedTemplate (refer example listing 8-14) is alsoautowired into theFixedDepositProcessorJob instance.ThemailSender instancevariable is definedoftype JavaMailSender (and notMailSender) because the FixedDepositProcessorJob creates and sendsMIMEmessages.FixedDepositProcessorJob’ssendEmailmethodcreatesaninstanceofaMimeMessageusing JavaMailSender’s createMimeMessage method. Spring’s MimeMessageHelper is then used topopulatetheMimeMessageinstancewithto,subjectandtextproperties.

The following example listing shows how the FixedDepositProcessorJob’s sendEmail method can bewrittenusingSpring’sMimeMessagePreparatorcallbackinterfaceinsteadofMimeMessageHelper:

Examplelisting8-18–MimeMessagePreparatorusageimportjavax.mail.Message;importjavax.mail.internet.InternetAddress;importorg.springframework.mail.javamail.MimeMessagePreparator;publicclassFixedDepositProcessorJob{.....publicvoidsendEmail_()throwsAddressException,MessagingException{List<FixedDepositDetails>inactiveFixedDeposits=getInactiveFixedDeposits();for(finalFixedDepositDetailsfixedDeposit:inactiveFixedDeposits){mailSender.send(newMimeMessagePreparator(){@Overridepublicvoidprepare(MimeMessagemimeMessage)throwsException{mimeMessage.setRecipient(Message.RecipientType.TO,newInternetAddress(fixedDeposit.getEmail()));mimeMessage.setSubject(simpleMailMessage.getText());mimeMessage.setText(simpleMailMessage.getText());}});}myFixedDepositDao.setFixedDepositsAsActive(inactiveFixedDeposits);}}

TheaboveexampleshowsthataMimeMessagePreparatorinstanceispassedtoJavaMailSender’ssendmethod to prepare a MimeMessage instance for sending. MimeMessagePreparator’s prepare method

Page 292: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

providesanewinstanceofMimeMessagethatyouneedtopopulate.Intheaboveexamplelisting,noticethatsettingtheMimeMessage’srecipientpropertyrequiresyoutodealwithlower-levelJavaMailAPI.Inexample listing 8-17,MimeMessageHelper’s setTomethod accepted an email id of the recipient as astringargumenttosettheMimeMessage’srecipientproperty.Forthisreason,youshouldconsiderusingMimeMessageHelper to populate the MimeMessage instance passed to the prepare method ofMimeMessagePreparator.

Let’snowlookathowyoucanuseSpringtoexecuteataskasynchronously,andtoscheduleexecutionofataskinthefuture.

Page 293: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-6TaskschedulingandasynchronousexecutionYou can asynchronously execute java.lang.Runnable tasks using Spring’s TaskExecutor, and you canschedule executionof java.lang.Runnable tasks using Spring’sTaskScheduler. Instead of directly usingTaskExecutorandTaskScheduler,youcanuseSpring’s@Asyncand@Scheduledannotationstoexecuteamethodasynchronouslyandtoscheduleexecutionofamethod,respectively.

Let’sfirstlookatTaskExecutorandTaskSchedulerinterfaces.

TaskExecutorinterfaceJava 5 introduced the concept of executors for executing java.lang.Runnable tasks. An executorimplements java.util.concurrent.Executor interface that defines a single method, execute(Runnablerunnable).Spring’sTaskExecutorextendsjava.util.concurrent.Executorinterface.Springalsoprovidesacouple of TaskExecutor implementations that you can choose from depending upon your application’srequirements.Dependingupon theTaskExecutor implementationyouchoose, theRunnable taskmay beexecuted synchronously or asynchronously, using a thread pool or CommonJ, and so on. Some of theTaskExecutor implementations provided by Spring are: ThreadPoolTaskExecutor (asynchronouslyexecutestasksusingathreadfromathreadpool),SyncTaskExecutor(executestaskssynchronously)andSimpleAsyncTaskExecutor(asynchronouslyexecuteseachtaskinanewthread).

ThreadPoolTaskExecutor is the most commonly used TaskExecutor implementation that uses Java 5’sThreadPoolExecutor to execute tasks. The following example listing shows how to configure aThreadPoolTaskExecutorinstanceintheapplicationcontextXMLfile:

Examplelisting8-19–ThreadPoolTaskExecutorconfiguration<beanid="myTaskExecutor"class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><propertyname="corePoolSize"value="5"/><propertyname="maxPoolSize"value="10"/><propertyname="queueCapacity"value="15"/><propertyname="rejectedExecutionHandler"ref="abortPolicy"/></bean><beanid="abortPolicy"class="java.util.concurrent.ThreadPoolExecutor.AbortPolicy"/>

ThecorePoolSizepropertyspecifiestheminimumnumberofthreadsinthethreadpool.ThemaxPoolSizeproperty specifies themaximum number of threads that can be accommodated in the thread pool. ThequeueCapacity property specifies the maximum number of tasks that can wait in the queue if all thethreads in the threadpoolarebusyexecuting tasks.The rejectedExecutionHandlerproperty specifies ahandlerfortasksrejectedbytheThreadPoolTaskExecutor.AtaskisrejectedbyThreadPoolTaskExecutorifthequeueisfullandthereisnothreadavailableinthethreadpoolforexecutingthesubmittedtask.TherejectedExecutionHandler property refers to an instance ofjava.util.concurrent.RejectedExecutionHandlerobject.

In example listing 8-19, the rejectedExecutionHandler property refers tojava.util.concurrent.ThreadPoolExecutor.AbortPolicy instance that always throws

Page 294: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

RejectedExecutionException. The other possible handlers for rejected tasks are:java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy (the rejected task is executed in caller’sthread), java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy (the handler discards the oldesttask from the queue and retries executing the rejected task), andjava.util.concurrent.ThreadPoolExecutor.DiscardPolicy(thehandlersimplydiscardstherejectedtask).

The <executor> element of Spring’s task schema simplifies configuring a ThreadPoolTaskExecutorinstance,asshowninthefollowingexamplelisting:

Examplelisting8-20–ThreadPoolTaskExecutorconfigurationusingSpring’staskschema

<beans.....xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation=".....http://www.springframework.org/schema/taskhttp://www.springframework.org/schema/task/spring-task-4.0.xsd"><task:executorid="myTaskExecutor"pool-size="5-10"queue-capacity="15"rejection-policy="ABORT"/></beans>

Intheaboveexamplelisting,the<executor>elementconfiguresaThreadPoolTaskExecutorinstance.Thepool-sizeattributespecifiesthecorepoolsizeandthemaximumpoolsize.Intheaboveexamplelisting,5is the core pool size and 10 is the maximum pool size. The queue-capacity attribute sets thequeueCapacity property, and rejection-policy attribute specifies the handler for rejected tasks. Thepossible values of rejection-policy attribute areABORT,CALLER_RUNS,DISCARD_OLDEST, andDISCARD.

OnceyouhaveconfiguredaThreadPoolTaskExecutorinstancebyexplicitlydefiningitasaSpringbean(referexamplelisting8-19)orbyusingSpring’staskschema(referexamplelisting8-20),youcaninjecttheThreadPoolTaskExecutorinstanceintobeansthatwanttoasynchronouslyexecutejava.lang.Runnabletasks,asshowninthefollowingexamplelisting:

Examplelisting8-21–ExecutingtasksusingThreadPoolTaskExecutor

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.core.task.TaskExecutor;@ComponentpublicclassSample{@AutowiredprivateTaskExecutortaskExecutor;publicvoidexecuteTask(Runnabletask){taskExecutor.execute(task);}}

Intheaboveexamplelisting,aninstanceofThreadPoolTaskExecutorisautowiredintotheSampleclass,andislaterusedbySample’sexecuteTaskmethodtoexecuteajava.lang.Runnabletask.

Page 295: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

TaskExecutor executes a java.lang.Runnable task immediately after it is submitted, and the task isexecutedonlyonce.Ifyouwanttoscheduleexecutionofajava.lang.Runnabletask,andyouwantthetasktobeexecutedperiodically,youshoulduseaTaskSchedulerimplementation.

TaskSchedulerinterfaceSpring’sTaskScheduler interface provides the abstraction to schedule execution of java.lang.Runnabletasks. Spring’s Trigger interface abstracts the time when a java.lang.Runnable task is executed. YouassociateaTaskSchedulerinstancewithaTrigger instance toscheduleexecutionof java.lang.Runnabletasks.PeriodicTrigger(animplementationofTriggerinterface)isusedifyouwantperiodicexecutionoftasks.CronTrigger(anotherimplementationofTriggerinterface)acceptsacronexpressionthatindicatesthedate/timewhenthetaskisexecuted.

ThreadPoolTaskScheduler is one of the most commonly used implementations of TaskScheduler thatinternally uses Java 5’s ScheduledThreadPoolExecutor (an implementation of Java 5’sScheduledExecutorService interface) to schedule task execution. You can configure aThreadPoolTaskSchedulerimplementationandassociateitwithaTriggerimplementationtoscheduletaskexecution.ThefollowingexamplelistingshowshowThreadPoolTaskSchedulerisconfiguredandused:

Examplelisting8-22–ThreadPoolTaskExecutorconfigurationandusage

------------ThreadPoolTaskSchedulerconfiguration---------------------<beanid="myScheduler"class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"><propertyname="poolSize"value="5"/></bean>---------------ThreadPoolTaskSchedulerusage---------------------importorg.springframework.scheduling.TaskScheduler;importorg.springframework.scheduling.support.PeriodicTrigger;@ComponentpublicclassSample{@Autowired@Qualifier("myScheduler")privateTaskSchedulertaskScheduler;publicvoidexecuteTask(Runnabletask){taskScheduler.schedule(task,newPeriodicTrigger(5000));}}

In the above example listing, ThreadPoolTaskScheduler’s poolSize property specifies the number ofthreadsinthethreadpool.Toscheduleataskforexecution,ThreadPoolTaskScheduler’sschedulemethodis called, passing the java.lang.Runnable task and a Trigger instance. In the above example listing,

Page 296: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

PeriodicTriggerinstanceispassedtoThreadPoolTaskScheduler’sschedulemethod.TheargumenttothePeriodicTriggerconstructorspecifiesthetimeinterval(inmilliseconds)betweentaskexecutions.

The <scheduler> element of Spring’s task schema simplifies configuring a ThreadPoolTaskSchedulerinstance.TheThreadPoolTaskSchedulerinstancecreatedbythe<scheduler>elementcanbeusedbythe<scheduled-tasks>elementofSpring’staskschematoscheduleexecutionofbeanmethods.Thefollowingexamplelistingshowshow<scheduler>and<scheduled-tasks>elementsareusedbyMyBankapplicationtoexecuteFixedDepositProcessorJob’ssendEmailmethodevery5seconds:

Examplelisting8-23–<scheduler>and<scheduled-tasks>elementsProject–ch08-bankappSourcelocation-src/main/java/sample/spring/chapter08/bankapp/job<task:schedulerid="emailScheduler"pool-size="10"/><task:scheduled-tasksscheduler="emailScheduler"><task:scheduledref="FixedDepositProcessorJob"method="sendEmail"fixed-rate="5000"/></task:scheduled-tasks><beanid="FixedDepositProcessorJob"class="sample.spring.chapter08.bankapp.job.FixedDepositProcessorJob"/>

In theaboveexample listing, the<scheduler>elementconfiguresaThreadPoolTaskScheduler instance.Theidattributeofthe<scheduler>elementspecifiesthenamewithwhichtheThreadPoolTaskSchedulerinstanceisaccessedbyotherbeansintheSpringcontainer.The<scheduled-tasks>element’sschedulerattribute specifies reference to the ThreadPoolTaskScheduler instance that is used for schedulingexecutionofbeanmethods.Intheaboveexamplelisting,theThreadPoolTaskSchedulerinstancecreatedbythe<scheduler>elementisreferencedbythe<scheduled-tasks>element’sscheduledattribute.

The<scheduled-tasks>element containsoneormore<scheduled>elements.The<scheduled> elementcontainsinformationaboutthebeanmethodtobeexecutedandthetriggerforthebeanmethodexecution.TherefattributespecifiesreferencetoaSpringbean,themethodattributespecifiesamethodofthebeanreferencedby therefattribute,and thefixed-rateattribute (an interval-based trigger) specifies the timeinterval between successive method executions. In example listing 8-23, the <scheduled> elementspecifiesthatFixedDepositProcessorJob’ssendEmailmethodisexecutedevery5seconds.

Instead of using fixed-rate attribute of the <scheduled> element, you can use fixed-delay (an interval-basedtrigger)orcron(acron-basedtrigger)ortrigger(referencetoaTriggerimplementation)attribute,tospecifyatriggerforthebeanmethodexecution.

Let’snowlookatSpring’s@Asyncand@Scheduledannotations.

@Asyncand@ScheduledannotationsIfyouannotateabeanmethodwithSpring’s@Asyncannotation,itisasynchronouslyexecutedbySpring.If you annotate a beanmethodwith Spring’s@Scheduled annotation, it is scheduled for execution bySpring.

Useof@Asyncand@Scheduledannotationsisenabledby<annotation-driven>elementofSpring’stask

Page 297: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

schema,asshowninthefollowingexamplelisting:

Examplelisting8-24–Enabling@Asyncand@Scheduledannotations<task:annotation-drivenexecutor="anExecutor"scheduler="aScheduler"/><task:executorid="anExecutor"/><task:scheduled-tasksscheduler="aScheduler"><task:scheduledref="sampleJob"method="doSomething"fixed-rate="5000"/></task:scheduled-tasks>

The<annotation-driven>element’sexecutorattributespecifiesreferencetoaSpring’sTaskExecutor (orJava5’sExecutor)instancethatisusedforexecuting@Asyncannotatedmethods.TheschedulerattributespecifiesreferencetoaSpring’sTaskScheduler(orJava5’sScheduledExecutorService)instancethatisusedforexecuting@Scheduledannotatedmethods.

Let’snowlookat@Asyncannotationindetail.

@Asyncannotation

Thefollowingexamplelistinghighlightssomeoftheimportantpointsthatyouneedtoknowwhenusing@Asyncannotation:

Examplelisting8-25–@Asyncannotationusageimportjava.util.concurrent.Future;importorg.springframework.scheduling.annotation.Async;importorg.springframework.scheduling.annotation.AsyncResult;importorg.springframework.stereotype.Component;@ComponentpublicclassSample{@AsyncpublicvoiddoA(){.....}@Async(value="someExecutor")publicvoiddoB(Stringstr){.....}@AsyncpublicFuture<String>doC(){returnnewAsyncResult<String>("Hello");}}

@Asyncannotation’svalueattributespecifiestheSpring’sTaskExecutor(orJava5’sExecutor) instancetouse forasynchronouslyexecuting themethod.As the@Asyncannotationon thedoAmethoddoesn’tspecifytheexecutor touse,Spring’sSimpleAsyncTaskExector isusedforasynchronouslyexecuting the

Page 298: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

doA method. @Async annotation on the doB method specifies the value attribute’s value assomeExecutor,whichmeansthebeannamedsomeExecutor(oftypeTaskExecutororJava5’sExecutor)isusedforasynchronouslyexecutingthedoBmethod.@Asyncannotatedmethodscanacceptarguments,likethedoBmethodintheaboveexamplelisting.@Asyncannotatedmethodscaneitherreturnvoid(likethedoAanddoBmethods)oraFuture instance (like thedoCmethod).To return aFuture instance, you’llneed towrap thevalue thatyouwant to return intoanAsyncResult object, and return theAsyncResultobject.

Let’snowlookat@Scheduledannotationindetail.

@Scheduledannotation

Thefollowingexamplelistinghighlightssomeoftheimportantpointsthatyouneedtoknowwhenusing@Scheduledannotation:

Examplelisting8-26–@Scheduledannotationusageimportorg.springframework.scheduling.annotation.Scheduled;@ComponentpublicclassSample{@Scheduled(cron="009-17**MON-FRI")publicvoiddoA(){.....}@Scheduled(fixedRate=5000)publicvoiddoB(){.....}}

Amethodannotatedwith@Scheduledannotationmustreturnvoidandmustnotbedefinedtoacceptanyarguments.Youmustspecifycron,fixedRateorfixedDelayattributeof@Scheduledannotation.

Itisimportanttonotethatifthe@Async(or@Scheduled)annotationisspecifiedononeormoremethodsofaclass,youarerequiredtoincludeCGLIBJARfileinyourapplication’sclasspath.Ifthe@Async(or@Scheduled) annotation is specified only on the methods defined in an interface, you don’t need toincludeCGLIBJARfile.StartingwithSpring3.2,theCGLIBclassesarepackagedwithinthespring-coreJARfile itself; therefore,youdon’tneed toexplicitlyspecify thatyourproject isdependentonCGLIBJARfile.

NOTEIfyouwanttousetheQuartzScheduler(http://quartz-scheduler.org/)inyourSpringapplication,youcanusetheintegrationclassesprovidedbySpringthatsimplifyusingtheQuartzScheduler.

Spring simplifies using caching in an application by providing an abstraction on top ofjava.util.concurrent.ConcurrentMapandEhcache(http://ehcache.org/).

Page 299: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-7CachingIfyouwanttousecachinginyourapplication,youcanconsiderusingSpring’scacheabstraction.Spring’scacheabstractionshieldsdevelopersfromdirectlydealingwiththeunderlyingcachingimplementation’sAPI. Starting with Spring 3.2, cache abstraction is available out-of-the-box forjava.util.concurrent.ConcurrentMap,Ehcache and for caching solutions that implement JSR107 – JavaTemporaryCachingAPI(referredtoasJCACHE).

NOTEIfyouareusingacachingsolutionwhichisnotcurrentlysupportedbySpring’scacheabstraction,you have the option to either directly use theAPI of the caching solution or create adapters thatmapSpring’scacheabstractiontothecachingsolution.

Spring provides a CacheManager interface that defines methods for managing a collection of Cacheinstances. A CacheManager instance acts as a wrapper around the cache manager provided by theunderlying caching solution. For instance, EhCacheCacheManager is a wrapper around Ehcache’snet.sf.ehcache.CacheManager, JCacheCacheManager is a wrapper around JSR 107 provider’sjavax.cache.CacheManager implementation, and so on. A Cache instance is a wrapper around theunderlying 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, andJCacheCache (a Cache implementation) is a wrapper around JSR 107 provider’s javax.cache.Cacheinstance.

Spring also provides a ConcurrentMapCacheManager that you can use if you want to usejava.util.concurrent.ConcurrentMap as the underlying cache. The Cache instance managed byConcurrentMapCacheManager is a ConcurrentMapCache. The following diagram summarizesrelationshipbetweenCacheManagerandCacheinterfacesprovidedbySpring’scachingabstraction:

NOTE If you want to use Spring’s caching abstraction for a caching solution that is not currentlysupportedbySpring’s caching abstraction, all youneed to do is to provideCacheManager andCacheimplementationsforthecachingsolution.

Page 300: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure8-3ACacheManagerimplementationactsaswrapperaroundthecachemanageroftheunderlyingcachingsolution,andaCacheimplementationprovidesoperationstointeractwiththeunderlyingcache.

TheabovefigureshowsthatCacheManagermanagesCache instances.EhCacheCacheManagermanagesEhCacheCache instances (underlying cache store is Ehcache), JCacheCacheManager managesJCacheCache instances (underlying cache store is a caching solution that implements JSR 107),ConcurrentMapCacheManager manages ConcurrentMapCache instances (underlying cache store isjava.util.concurrent.ConcurrentMap),andsoon.

Figure 8-3 shows a SimpleCacheManager class that implements CacheManager interface.SimpleCacheManagerisusefulforsimplecachingscenariosandfortestingpurposes.Forinstance,ifyouwant to use java.util.concurrent.ConcurrentMap as the underlying cache store, you can useSimpleCacheManager,insteadofConcurrentMapCacheManager,tomanagethecache.

Let’snowlookathowaCacheManagerisconfiguredintheapplicationcontextXMLfile.

ConfiguringaCacheManagerIn MyBank application, a collection of java.util.concurrent.ConcurrentMap instances are used as theunderlyingcachestore;therefore,SimpleCacheManagerisusedtomanagethecache.

The following example listing shows how a SimpleCacheManager instance is configured in MyBankapplication:

Examplelisting8-27–SimpleCacheManagerconfigurationProject–ch08-bankappSourcelocation-src/main/resources/META-INF/spring/<beanid="myCacheManager"class="org.springframework.cache.support.SimpleCacheManager"><propertyname="caches"><set><beanclass="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"><propertyname="name"value="FixedDepositList"/></bean><beanclass="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"><propertyname="name"value="FixedDeposit"/></bean></set></property></bean>

SimpleCacheManager’s caches property specifies a collection of caches managed by theSimpleCacheManager instance.ConcurrentMapCacheFactoryBean isaFactoryBean implementation thatsimplifies configuring a ConcurrentMapCache instance - a Cache instance that uses ajava.util.concurrent.ConcurrentHashMap instance (an implementation of

Page 301: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

java.util.concurrent.ConcurrentMap interface) as the underlying cache store.ConcurrentMapCacheFactoryBean’snamepropertyspecifiesanameforthecache.Intheaboveexamplelisting,theFixedDepositListandFixedDepositcachesaremanagedbytheSimpleCacheManagerinstance.

Let’snowlookathowtouseSpring’scachingannotationsinapplications.

Cachingannotations-@Cacheable,@CacheEvictand@CachePutAfteryouhaveconfiguredanappropriateCacheManager foryourapplication,youneed tochoosehowyou want to use Spring’s cache abstraction. You can use Spring’s cache abstraction either by usingcaching annotations (like @Cacheable, @CacheEvict and @CachePut) or by using Spring’s cacheschema.AsusingSpring’scacheschemaforcachingresults inaverboseapplicationcontextXMLfile,we’llbeonlylookingatusingcachingannotationsfordeclarativecaching.

Tousecachingannotations,youneedtoconfigure<annotation-driven>elementofSpring’scacheschema,asshownherefortheMyBankapplication:

Examplelisting8-28–Enablecachingannotationsusing<annotation-driven>Project–ch08-bankappSourcelocation-src/main/resources/META-INF/spring/<beans.....xmlns:cache="http://www.springframework.org/schema/cache"xsi:schemaLocation=".....http://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache.xsd"><cache:annotation-drivencache-manager="myCacheManager"/>.....</beans>

Intheaboveexamplelisting,Spring’scacheschemaisincludedsothatitselementsareaccessibleintheapplication contextXML file.The<annotation-driven>element’s cache-manager attribute refers to theCacheManagerbean that is used formanaging the cache.Youdon’t need to specify the cache-managerattributeiftheCacheManagerbeanisnamedcacheManager.

Now,thatwehaveenabledcachingannotations,let’slookatdifferentcachingannotations.

@Cacheable

@Cacheableannotationonamethodindicatesthatthevaluereturnedbythemethodiscached.Spring’sDefaultKeyGeneratorclassisusedbydefaulttogeneratethekeywithwhichthemethod’sreturnvalueisstored in the cache.DefaultKeyGenerator usesmethod signature andmethod arguments to compute thekey. You can use a custom key generator by providing an implementation of Spring’s KeyGeneratorinterface,andspecifyingitasthevalueofkey-generatorattributeof<annotation-driven>element.

Thefollowingexamplelistingshowstheusageof@CacheableannotationtocachethevaluereturnedbyFixedDepositService’sfindFixedDepositsByBankAccountmethodintheMyBankapplication:

Examplelisting8-29–@CacheableannotationProject–ch08-bankapp

Page 302: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Sourcelocation-src/main/java/sample/spring/chapter08/bankapp/servicepackagesample.spring.chapter08.bankapp.service;importorg.springframework.cache.annotation.Cacheable;.....@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{.....@Cacheable(value={"FixedDepositList"})publicList<FixedDepositDetails>findFixedDepositsByBankAccount(intbankAccountId){logger.info("findFixedDepositsByBankAccountmethodinvoked");returnmyFixedDepositDao.findFixedDepositsByBankAccount(bankAccountId);}}

@Cacheable annotation’s value attribute specifies the cache region into which the returned value iscached.Inlisting8-27,wecreatedacacheregionnamedFixedDepositListfortheMyBankapplication.Inthe above example listing, the @Cacheable annotation specifies that the value returned by thefindFixedDepositsByBankAccountmethodisstoredintheFixedDepositListcache.Itisimportanttonotethat@Cacheableannotatedmethod isnot invoked if the samesetofargumentvaluesarepassed to themethod.But,@Cacheableannotatedmethodwillbeinvokedifyoupassadifferentvalueforatleastoneofthearguments.

@CacheEvict

If you want to evict data from the cache when a method is called, annotate the method with the@CacheEvict annotation. In theMyBank application, when a new fixed deposit is created, the fixeddepositdetailscachedbyFixedDepositServiceImpl’sfindFixedDepositsByBankAccountmethodmustbeevictedfromthecache.ThisensuresthatwhenthenexttimefindFixedDepositsByBankAccountmethodisinvoked,thenewlycreatedfixeddepositisalsofetchedfromthedatabase.Thefollowingexamplelistingshowsusageof@CacheEvictannotation:

Examplelisting8-30–@CacheEvictannotationProject–ch08-bankappSourcelocation-src/main/java/sample/spring/chapter08/bankapp/servicepackagesample.spring.chapter08.bankapp.service;importorg.springframework.cache.annotation.CacheEvict;.....@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{.....@Transactional("jmsTxManager")@CacheEvict(value={"FixedDepositList"},allEntries=true,beforeInvocation=true)

Page 303: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicvoidcreateFixedDeposit(finalFixedDepositDetails fixedDepositDetails) throwsException{.....}.....}

In the above example listing, the@CacheEvict annotation on the createFixedDeposit method instructsSpring to remove all the cached entries from the cache region named FixedDepositList. The valueattributespecifiesthecacheregionfromwhichtoevictthecacheditem,andallEntriesattributespecifieswhetherornotallentriesfromthespecifiedcacheregionareevicted.Ifyouwant toevictaparticularcacheditem,usethekeyattributetospecifythekeywithwhichtheitemiscached.Youcanalsospecifyconditional eviction of itemsbyusing the condition attribute.The condition andkey attributes supportspecifying values using SpEL (refer section 6-8 of chapter 6 formore details), making it possible toperform sophisticated cache evictions. The beforeInvocation attribute specifies whether the cacheevictionisperformedbeforeorafterthemethodexecution.AsthevalueofbeforeInvocationattributeissettotrue,cacheisevictedbeforethecreateFixedDepositmethodisinvoked.

@CachePut

Spring also provides a@CachePut annotation that indicates that amethod isalways invoked, and thevalue 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 methodinvocationifthemethodiscalledwiththesamesetofargumentvalues.

Thefollowingexamplelistingshowsusageof@CachePutannotationbyFixedDepositServiceImplclassofMyBankapplication:

Examplelisting8-31–@CachePutannotationProject–ch08-bankappSourcelocation-src/main/java/sample/spring/chapter08/bankapp/servicepackagesample.spring.chapter08.bankapp.service;importorg.springframework.cache.annotation.CachePut;importorg.springframework.cache.annotation.Cacheable;.....@Service(value="FixedDepositService")publicclassFixedDepositServiceImplimplementsFixedDepositService{.....@CachePut(value={"FixedDeposit"},key="#FixedDepositId")publicFixedDepositDetailsgetFixedDeposit(intFixedDepositId){logger.info("getFixedDepositmethodinvokedwithFixedDepositId"+FixedDepositId);returnmyFixedDepositDao.getFixedDeposit(FixedDepositId);}@Cacheable(value={"FixedDeposit"},key="#FixedDepositId")publicFixedDepositDetailsgetFixedDepositFromCache(intFixedDepositId){logger.info("getFixedDepositFromCachemethodinvokedwithFixedDepositId"

Page 304: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

+FixedDepositId);thrownewRuntimeException("Thismethodthrowsexceptionbecause"+"FixedDepositDetailsobjectmustcomefromthecache");}.....}

Intheaboveexamplelisting,thegetFixedDepositmethodisannotatedwith@CachePutannotation,whichmeansthatthegetFixedDepositmethodisalwaysinvoked,andthereturnedFixedDepositDetailsobjectisstoredintothecachenamedFixedDeposit.ThevalueattributespecifiesthenameofthecacheintowhichtheFixedDepositDetailsobject is stored.Thekey attribute specifies thekey to beused for storing thereturnedFixedDepositDetailsobjectintothecache.Asyoucansee,keyattributemakesuseofSpELtospecifythekey.The#FixedDepositIdvalueofkeyattributereferstotheFixedDepositIdargumentpassedto the getFixedDeposit method. To summarize, the FixedDepositDetails object returned by thegetFixedDepositmethod is stored in the cache named FixedDeposit, and the value of FixedDepositIdmethodargumentisusedasthekey.

In example listing 8-31, FixedDepositServiceImpl’s getFixedDepositFromCache method retrieves theFixedDepositDetailsobjectfromthecachebasedonthekeyattributevaluespecifiedbythe@Cacheableannotation. Notice that the body of the getFixedDepositFromCache method does nothing but throw aRuntimeException. The key attribute value refers to the FixedDepositId argument passed to thegetFixedDepositFromCache method. If the FixedDepositDetails object is not found in the cache, thegetFixedDepositFromCachemethodisinvoked,whichwillresultinRuntimeException.

Let’snowlookatwhathappenswhenyouruntheMyBankapplicationofch08-bankappproject.

Page 305: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-8RunningtheMyBankapplicationBankApp class ofMyBank application defines the mainmethod of the application. Themain methodaccesses methods of FixedDepositService andBankAccountService instances to demonstrate differentfeaturesthatwediscussedinthischapter.

ThefollowingexamplelistingshowstheMyBankapplication’sBankAppclass:

Examplelisting8-32–BankAppclassProject–ch08-bankappSourcelocation-src/main/java/sample/spring/chapter08/bankapppackagesample.spring.chapter08.bankapp;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassBankApp{publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");BankAccountServicebankAccountService=context.getBean(BankAccountService.class);BankAccountDetailsbankAccountDetails=newBankAccountDetails();.....intbankAccountId=bankAccountService.createBankAccount(bankAccountDetails);FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();.....fixedDepositDetails.setEmail("[email protected]");FixedDepositService.createFixedDeposit(fixedDepositDetails);.....FixedDepositService.findFixedDepositsByBankAccount(bankAccountId);FixedDepositService.findFixedDepositsByBankAccount(bankAccountId);FixedDepositService.createFixedDeposit(fixedDepositDetails);.....List<FixedDepositDetails>FixedDepositDetailsList=FixedDepositService.findFixedDepositsByBankAccount(bankAccountId);for(FixedDepositDetailsdetail:FixedDepositDetailsList){FixedDepositService.getFixedDeposit(detail.getFixedDepositId());}

Page 306: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

for(FixedDepositDetailsdetail:FixedDepositDetailsList){FixedDepositService.getFixedDepositFromCache(detail.getFixedDepositId());}.....}}

Intheaboveexamplelisting,followingsequenceofactionsareperformedbythemainmethod:

Step 1. First, a bank account is created in the BANK_ACCOUNT_DETAILS table by callingBankAccountService’screateBankAccountmethod.

Step 2. Corresponding to the newly created bank account, a fixed deposit is created in theFIXED_DEPOSIT_DETAILS table by calling FixedDepositService’s createFixedDeposit method. YoushouldmakesurethatemailpropertyofFixedDepositDetailsobjectissettotheemailidwhereyoucanchecktheemails.ThecreateFixedDepositmethodsends2JMSmessages(referexamplelisting8-5).OneJMSmessagecontainstheemailidspecifiedbytheFixedDepositDetailsobject’semailproperty,andisprocessedbyEmailMessageListener(referexamplelisting8-16)thatsendsanemailtothecustomer.TheotherJMSmessageisprocessedbyFixedDepositMessageListener(referexamplelisting8-11)thatsavesthe fixed deposit details in the FIXED_DEPOSIT_DETAILS table. You should also note thatFixedDepositServiceImpl’screateFixedDepositmethodisannotatedwith@CacheEvictannotation(referexamplelisting8-30)thatresultsinremovingalltheitemscachedinFixedDepositListcache.

Step3.FixedDepositService’sfindFixedDepositsByBankAccountmethodisinvokedthatretrievesfixeddeposits corresponding to the bank account that we created in Step 1. As thefindFixedDepositsByBankAccount method is annotated with @Cacheable annotation (refer examplelisting8-29),fixeddepositsreturnedbythefindFixedDepositsByBankAccountmethodarestored in thecache named FixedDepositList. Listing 8-29 showed that findFixedDepositsByBankAccount methodwritesthefollowingmessagetotheconsole‘findFixedDepositsByBankAccountmethodinvoked’.Intheaboveexamplelisting,thefindFixedDepositsByBankAccountiscalledtwiceforthesamebankAccountIdargument,butyou’llnoticethatonlyonce‘findFixedDepositsByBankAccountmethodinvoked’iswrittento the console. This is because the second call to the findFixedDepositsByBankAccount results inretrieving fixed deposit details from the cache named FixedDepositList, and thefindFixedDepositsByBankAccountmethodisnotexecuted.

Step 4. Corresponding to the bank account created in Step 1, another fixed deposit is created in theFIXED_DEPOSIT_DETAILStablebycallingFixedDepositService’screateFixedDepositmethod.Now,the FixedDepositServiceImpl’s createFixedDeposit method is annotated with @CacheEvict annotation(referexamplelisting8-30)thatresultsinremovingalltheitemscachedinFixedDepositListcache.

Step 5. FixedDepositService’s findFixedDepositsByBankAccount method is invoked once again. Thistime findFixedDepositsByBankAccount is executed because the previous call to createFixedDepositmethod (referStep 4) resulted in evicting all the items from theFixedDepositList cache.At this time,you’ll once again see ‘findFixedDepositsByBankAccount method invoked’ message written on theconsole. The fixed deposits returned by the findFixedDepositsByBankAccount method are cached inFixedDepositListcachebecausethemethodisannotatedwith@Cacheableannotation.

Step6.ForeachfixeddepositretrievedinStep5,FixedDepositService’sgetFixedDepositmethod(refer

Page 307: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

example listing8-31) is invoked.ThegetFixedDepositmethod accepts the fixeddeposit identifier andreturns the fixeddeposit information from thedatabase.ThegetFixedDepositmethod is annotatedwith@CachePut,whichmeansitisalwaysinvoked.ThefixeddepositreturnedbythegetFixedDepositmethodiscachedintheFixedDepositcache.

Step7.For each fixeddeposit retrieved inStep5,FixedDepositService’s getFixedDepositFromCachemethod(referexamplelisting8-31)isinvoked.ThegetFixedDepositFromCachemethodacceptsthefixeddepositidentifierandthrowsaRuntimeExceptiononexecution.ThegetFixedDepositFromCachemethodis annotated with @Cacheable, and is executed only when the fixed deposit is not found in theFixedDepositcache.AsallthefixeddepositswerecachedbythegetFixedDepositmethodinStep6,thegetFixedDepositFromCachemethodisneverexecuted.

Step8.Every5seconds,theFixedDepositProcessorJob(referexamplelisting8-17)checksifanynewfixed deposits have been created in the database. If new fixed deposits are found in the database, theFixedDepositProcessorJobactivatesthefixeddepositandsendsanemailtothecustomer,confirmingthatthefixeddepositrequesthasbeensuccessfullyprocessed.

Page 308: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

8-9SummaryIn this chapter, we touched upon some of the frequently used features of Spring.We saw that SpringsimplifiessendingandreceivingJMSmessages,sendingemails,asynchronouslyinvokingbeanmethods,scheduling bean methods for execution, and caching data. In the next chapter, we’ll look at Spring’ssupportforAOP(Aspect-orientedprogramming).

Page 309: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter9-Aspect-orientedprogramming

Page 310: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

9-1IntroductionAspect-oriented programming (AOP) is a programming approach in which responsibilities that aredistributedacrossmultipleclassesareencapsulatedintoaseparateclass,referredtoasan‘aspect’.Theresponsibilities that are distributed acrossmultiple classes are referred to as ‘cross-cutting concerns’.Logging,transactionmanagement,caching,security,andsoon,areexamplesofcross-cuttingconcerns.

Spring provides an AOP framework that is used internally by Spring for implementing declarativeservices, like transactionmanagement (refer chapter 7) and caching (refer chapter 8). Instead of usingSpringAOP framework, you can consider usingAspectJ (http://www.eclipse.org/aspectj/) as theAOPframework for your application.AsSpringAOP framework is sufficient formostAOP scenarios, andprovidesintegrationwiththeSpringcontainer,thischapterfocusesonSpringAOPframework.

Let’sbeginthischapterbylookingatanexampleusageofAOP.

Page 311: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

9-2AsimpleAOPexampleLet’ssay that forauditingpurposeswewant tocapture theargumentspassed to themethodsofclassesdefinedintheservicelayerofMyBankapplication.Asimpleapproachtologdetailsofmethodargumentsistowritethelogginglogicinsideeachmethod.But,thiswouldmeanthateachmethodisadditionallyresponsible for logging details of method arguments. As the responsibility to log details of methodargumentsisdistributedacrossmultipleclassesandmethods,itrepresentsacross-cuttingconcern.

Toaddressacross-cuttingconcernusingAOP,youneedtofollowthesesteps:

·createaJavaclass(referredtoasanaspect)

·addimplementationofthecross-cuttingconcerntotheJavaclass,and

·usearegularexpressiontospecifythemethodstowhichthecross-cuttingconcernapplies

IntermsofAOPterminology,themethodsofanaspectthatimplementcross-cuttingconcernsarereferredtoasadvices.And, each advice is associatedwith apointcut that identifies themethods towhich theadviceapplies.Themethodstowhichanadviceappliesarereferredtoasjoinpoints.

InSpringAOP,youhavetheoptiontodevelopanaspectusingAspectJannotation-styleorXMLschema-style. InAspectJannotation-style,AspectJannotations, like@Aspect,@Pointcut,@Before, and soon,are used to develop an aspect. In XML schema-style, elements of Spring’s aop schema are used toconfigureaSpringbeanasanaspect.

IMPORTchapter9/ch09-simple-aop(Thech09-simple-aopprojectshowstheMyBankapplicationthatusesSpringAOPtologdetailsofmethodargumentspassedtothemethodsdefinedbytheclassesintheservice layerofMyBankapplication.To run theapplication,execute themainmethodof theBankAppclassofthisproject)

The following example listing shows the logging aspect that logs details of the arguments passed toservicemethodsinMyBankapplication:

Examplelisting9-1–LoggingAspectclassProject–ch09-simple-aopSourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspectspackagesample.spring.chapter09.bankapp.aspects;importorg.aspectj.lang.JoinPoint;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;importorg.springframework.stereotype.Component;@Aspect@ComponentpublicclassLoggingAspect{privateLoggerlogger=Logger.getLogger(LoggingAspect.class);

Page 312: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@Before(value="execution(*sample.spring.chapter09.bankapp.service.*Service.*(..))")publicvoidlog(JoinPointjoinPoint){logger.info("Entering"+joinPoint.getTarget().getClass().getSimpleName()+"'s"+joinPoint.getSignature().getName());Object[]args=joinPoint.getArgs();for(inti=0;i<args.length;i++){logger.info("args["+i+"]-->"+args[i]);}}}

Inexamplelisting9-1:

·AspectJ’s@Aspecttype-levelannotationspecifiesthattheLoggingAspectclassisanAOPaspect

·AspectJ’s@Beforemethod-levelannotationspecifiesthatthelogmethodrepresentsanadvicethatisappliedbeforethemethodsmatchedbythevalueattributeareexecuted.Refersection9-5tolearnaboutdifferentadvicetypesthatyoucancreate.

·@Beforeannotation’svalueattributespecifiesapointcutexpression thatisusedbySpringAOPframeworktoidentifymethods(referredtoastargetmethods)towhichanadviceapplies.Insection9-4,we’ll take an in-depth look at pointcut expressions.Fornow,you can assume that the pointcutexpression execution(* sample.spring.chapter09.bankapp.service.*Service.*(..)) specifies thatLoggingAspect’slogmethodisappliedtoallthepublicmethodsdefinedbyclasses(orinterfaces)insample.spring.chapter09.bankapp.servicepackage,andwhosenamesendwithService.

· The logmethod’sJoinPointargument represents the targetmethod towhich theadvice isbeingapplied.ThelogmethodusesJoinPointinstancetoretrieveinformationabouttheargumentspassedtothetargetmethod.Inexamplelisting9-1,JoinPoint’sgetArgsmethodisinvokedtoretrievethemethodargumentsbeingpassedtothetargetmethod.

YouneedtoregisteranaspectwiththeSpringcontainersothattheSpringAOPframeworkismadeawareof theaspect. Inexample listing9-1, theLoggingAspect class is annotatedwithSpring’s@ComponentannotationsothatitisautomaticallyregisteredwiththeSpringcontainer.

The following example listing shows the BankApp class that invokes methods ofBankAccountServiceImpl (implements BankAccountService interface) and FixedDepositServiceImpl(implementsFixedDepositServiceinterface)classesofMyBankapplication:

Examplelisting9-2–BankAppclassProject–ch09-simple-aopSourcelocation-src/main/java/sample/spring/chapter09/bankapppackagesample.spring.chapter09.bankapp;

Page 313: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....publicclassBankApp{publicstaticvoidmain(Stringargs[])throwsException{ApplicationContextcontext=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");BankAccountServicebankAccountService=context.getBean(BankAccountService.class);BankAccountDetailsbankAccountDetails=newBankAccountDetails();bankAccountDetails.setBalanceAmount(1000);bankAccountDetails.setLastTransactionTimestamp(newDate());bankAccountService.createBankAccount(bankAccountDetails);FixedDepositServiceFixedDepositService=context.getBean(FixedDepositService.class);FixedDepositService.createFixedDeposit(newFixedDepositDetails(1,1000,12,"[email protected]"));}}

In the above example listing, BankAccountService’s createBankAccount and FixedDepositService’screateFixedDepositmethods are invoked byBankApp’smainmethod. If you execute BankApp’smainmethod,you’llseethefollowingoutputontheconsole:

INFOLoggingAspect-EnteringBankAccountServiceImpl'screateBankAccountINFOLoggingAspect-args[0]-->BankAccountDetails[accountId=0,balanceAmount=1000,lastTransactionTimestamp=SatOct2716:48:11IST2012]INFOBankAccountServiceImpl-createBankAccountmethodinvokedINFOLoggingAspect-EnteringFixedDepositServiceImpl'screateFixedDepositINFOLoggingAspect-args[0]-->id:1,depositamount:1000.0,tenure:12,email:someemail@somedomain.comINFOFixedDepositServiceImpl-createFixedDepositmethodinvoked

The above output shows that LoggingAspect’s log method is executed before the execution ofBankAccountService’screateBankAccountandFixedDepositService’screateFixedDepositmethod.

InthecontextofLoggingAspect,let’slookathowSpringAOPframeworkworks.

NOTETouseAspectJannotation-styleaspects,ch09-simple-aopprojectdefinesdependencyonspring-aop,aopalliance,aspectjrtandaspectjweaverJARfiles.Pleaserefertothepom.xmlfileofch09-simple-aopprojectfordetails.

Page 314: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

9-3SpringAOPframeworkSpringAOPframeworkisproxy-based;aproxyobjectiscreatedforobjectsthataretargetofanadvice.Aproxyisanintermediaryobject,introducedbytheAOPframework,betweenthecallingobjectandthetargetobject.Atruntime,callstothetargetobjectareinterceptedbytheproxy,andadvicesthatapplytothetargetmethodareexecutedbytheproxy.InSpringAOP,atargetobjectisabeaninstanceregisteredwiththeSpringcontainer.

ThefollowingdiagramshowshowtheLoggingAspect’slogmethod(referexamplelisting9-1)isappliedtothemethodsofBankAccountServiceandFixedDepositServiceobjects(referexamplelisting9-2):

Figure9-1Theproxyobjectisresponsibleforinterceptingmethodcallstothetargetobjectandexecutingtheadvicesthatapplytothetargetmethod.

TheabovediagramshowsthataproxyiscreatedforbothBankAccountServiceandFixedDepositServiceobjects. The proxy for BankAccountService intercepts the call to BankAccountService’screateBankAccount method, and the proxy for FixedDepositService intercepts the call toFixedDepositService’s createFixedDeposit method. The proxy for BankAccountService first executesLoggingAspect’slogmethod,followedbyBankAccountService’screateBankAccountmethodinvocation.Similarly, the proxy for FixedDepositService first executes LoggingAspect’s log method, followed byFixedDepositService’screateFixedDepositmethodinvocation.

Thetimingof theexecutionofanadvice(likethelogmethodofLoggingAspectaspect)dependson thetypeoftheadvice.InAspectJannotation-style,typeofanadviceisspecifiedbytheAspectJannotationontheadvice.Forinstance,AspectJ’s@Beforeannotationspecifies that theadvice isexecutedbefore theinvocation of the target method, @After annotation specifies that the advice is executed after theinvocationofthetargetmethod,@Aroundannotationspecifiesthattheadviceisexecutedbothbeforeandafter the execution of the targetmethod, and so on.AsLoggingAspect’s logmethod is annotatedwith@Beforeannotation,logmethodisexecutedbeforetheexecutionofthetargetobject’smethod.

Let’snowlookathowSpringAOPframeworkcreatesaproxyobject.

ProxycreationWhen using Spring AOP, you have the option to explicitly create AOP proxies via Spring’sProxyFactoryBean (refer to org.springframework.aop.framework package) or you can let SpringautomaticallycreateAOPproxies.TheautomaticgenerationofAOPproxiesbySpringAOPisreferredtoasautoproxying.

Page 315: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

If youwant to useAspectJ annotation-style for creating aspects, you need to enable support for usingAspectJannotation-stylebyspecifyingSpringaopschema’s<aspectj-autoproxy>element.The<aspectj-autoproxy>elementalsoinstructsSpringAOPframeworktoautomaticallycreateAOPproxiesfortargetobjects.Thefollowingexamplelistingshowsusageof<aspectj-autoproxy>elementinch09-simple-aopproject:

Examplelisting9-3–applicationContext.xml-<aspectj-autoproxy>elementProject–ch09-simple-aopSourcelocation-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/aophttp://www.springframework.org/schema/aop/spring-aop-4.0.xsd"><context:component-scanbase-package="sample.spring"/><aop:aspectj-autoproxyproxy-target-class="false"expose-proxy="true"/></beans>

The <aspectj-autoproxy> element’s proxy-target-class attribute specifies whether JavaSE- or CGLIB-basedproxiesarecreatedfortargetobjects,andexpose-proxyattributespecifieswhethertheAOPproxyitselfisavailabletothetargetobject.Ifexpose-proxy’svalueissettotrue,thetargetobject’smethodcanaccesstheAOPproxybycallingAopContext’scurrentProxystaticmethod.

SpringAOPframeworkcreatesaCGLIB-orJavaSE-basedproxy.Ifthetargetobjectdoesn’timplementany interface, SpringAOP creates aCGLIB-based proxy. If the target object implements one ormoreinterfaces, Spring AOP creates a JavaSE-based proxy. If the value of <aspectj-autoproxy> element’sproxy-target-classattributeissettofalse,itinstructsSpringAOPtocreateaJavaSE-basedproxyifthetargetobject implementsoneormore interface. Ifyousetproxy-target-classattribute’svalue to true, itinstructs SpringAOP to create CGLIB-based proxies even if a target object implements one ormoreinterfaces.

NOTEStartingwithSpring3.2,theCGLIBclassesarepackagedwithinthespring-coreJARfileitself;therefore,youdon’tneedtoexplicitlyincludeCGLIBJARfileinyourapplicationtoallowSpringAOPframeworktocreateCGLIB-basedproxiesfortargetobjects.

Let’snowlookatascenarioinwhichyou’dprefertosetexpose-proxyattributeof<aspectj-autoproxy>elementtotrue.

IMPORT chapter 9/ch09-aop-proxy (The ch09-aop-proxy project shows theMyBank application inwhichAopProxy’s currentProxymethod is used by a target method to retrieve the AOP proxy objectcreatedbySpringAOPframework.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

expose-proxyattribute

Page 316: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

The following example listing shows a modified BankAccountServiceImpl class in which thecreateBankAccountmethodinvokestheisDuplicateAccountmethodtocheckifabankaccountwithsamedetailsalreadyexistsinthesystem:

Examplelisting9-4–BankAccountServiceImplclass@Service(value="bankAccountService")publicclassBankAccountServiceImplimplementsBankAccountService{@AutowiredprivateBankAccountDaobankAccountDao;@OverridepublicintcreateBankAccount(BankAccountDetailsbankAccountDetails){if(!isDuplicateAccount(bankAccountDetails)){returnbankAccountDao.createBankAccount(bankAccountDetails);}else{thrownewBankAccountAlreadyExistsException("Bankaccountalreadyexists");}}@OverridepublicbooleanisDuplicateAccount(BankAccountDetailsbankAccountDetails){.....}}

The above example listing shows that the createBankAccount method invokes the isDuplicateAccountmethodtocheckifthebankaccountalreadyexistsinthesystem.

Now,thequestionarisesthatwhethertheLoggingAspect’slogmethod(referexamplelisting9-1)willbeexecutedwhentheisDuplicateAccountmethodisinvokedbythecreateBankAccountmethod?EventhoughtheisDuplicateAccountmethodmatchesthepointcutexpressionspecifiedby@BeforeannotationontheLoggingAspect’slogmethod(referexamplelisting9-1),theLoggingAspect’slogmethodisnotinvoked.ThisisbecausemethodsinvokedbythetargetobjectonitselfarenotproxiedbytheAOPproxy.Asthemethodinvocationdoesn’tgothroughtheAOPproxyobject,anyadvicethatisassociatedwiththetargetmethodisnotexecuted.

To ensure that the call to isDuplicateAccountmethodgoes to the target object through theAOPproxy,retrieve the AOP proxy object in the createBankAccount method and invoke the isDuplicateAccountmethodontheAOPproxyobject.ThefollowingexamplelistingshowshowtoretrieveAOPproxyobjectinsidethecreateBankAccountmethod:

Examplelisting9-5–BankAccountServiceImplclassProject–ch09-aop-proxySourcelocation-src/main/java/sample/spring/chapter09/bankapp/servicepackagesample.spring.chapter09.bankapp.service;importorg.springframework.aop.framework.AopContext;

Page 317: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....@Service(value="bankAccountService")publicclassBankAccountServiceImplimplementsBankAccountService{.....@OverridepublicintcreateBankAccount(BankAccountDetailsbankAccountDetails){//--obtaintheproxyandinvoketheisDuplicateAccountmethodviaproxybooleanisDuplicateAccount= ((BankAccountService)AopContext.currentProxy()).isDuplicateAccount(bankAccountDetails);if(!isDuplicateAccount){.....}.....}@OverridepublicbooleanisDuplicateAccount(BankAccountDetailsbankAccountDetails){.....}}

Intheaboveexamplelisting,calltoAopContext’scurrentProxymethodreturnstheAOPproxythatmadethecalltothecreateBankAccountmethod.IfthecreateBankAccountmethodisnotinvokedthroughSpringAOPframeworkorthevalueofexpose-proxyattributeof<aspectj-autoproxy>elementisfalse,calltothecurrentProxy method will result in throwing java.lang.IllegalStateException. As the AOP proxyimplementsthesameinterfaceasthetargetobject,theaboveexamplelistingshowsthattheAOPproxyreturned by the currentProxy method is cast to BankAccountService type and BankAccountService’sisDuplicateAccountmethodisinvoked.

If you now go to ch09-aop-proxy project and execute BankApp’s main method, you’ll notice thatLoggingAspect’s log method is executed when isDuplicateAccount method is invoked by thecreateBankAccountmethod.

Let’snowtakeatanin-depthlookatpointcutexpressions.

Page 318: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

9-4PointcutexpressionsWhenusingSpringAOP,apointcutexpressionidentifiesthejoinpointstowhichanadviceisapplied.InSpringAOP,joinpointsarealwaysbeanmethods.Ifyouwanttoapplyanadvicetofields,constructors,non-publicmethods,andtoobjects thatarenotSpringbeans,youshoulduseAspectJ insteadofSpringAOPframework. Ifyouwant todevelopaspectsusingAspectJannotation-style,youhave theoption tospecify a pointcut expression using AspectJ’s @Pointcut annotation or by using AspectJ’s @Before,@After,andsoon,annotationsthatspecifytheadvicetype.

Pointcut expressions use pointcut designators, like execution, args, within, this, and so on, to findmatchingmethodstowhichanadviceisapplied.Forinstance,inexamplelisting9-1,@Beforeannotationmadeuseofexecutionpointcutdesignator to findmethods towhich theLoggingAspect’s logmethod isapplied.

Let’snowlookathowpointcutexpressionsarespecifiedusing@Pointcutannotation.

IMPORTchapter9/ch09-aop-pointcuts(Thech09-aop-pointcutsprojectshowstheMyBankapplicationthatusesAspectJ’s@Pointcutannotationtospecifyapointcutexpression.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

@Pointcutannotation@Pointcut annotation’s value attribute specifies the pointcut expression. To use@Pointcut annotation,createanemptymethodandannotateitwith@Pointcutannotation.Theemptymethodmustbedefinedtoreturnvoid.Anadvicethatreferstothenameofthe@Pointcutannotatedmethodisappliedtothemethodsmatchedbythepointcutexpressionspecifiedbythe@Pointcutannotation.

NOTEUsing@Pointcutannotation isparticularlyuseful if apointcutexpression is sharedbymultipleadvicesinthesameordifferentaspects.

The following example listing shows amodifiedversionofLoggingAspect (refer example listing9-1)classthatuses@Pointcutannotation:

Examplelisting9-6–LoggingAspectclassProject–ch09-aop-pointcutsSourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspectspackagesample.spring.chapter09.bankapp.aspects;importorg.aspectj.lang.annotation.Before;importorg.aspectj.lang.annotation.Pointcut;@Aspect@ComponentpublicclassLoggingAspect{@Pointcut(value="execution(*sample.spring.chapter09.bankapp.service.*Service.*(..))")privatevoidinvokeServiceMethods(){}

Page 319: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@Before(value="invokeServiceMethods()")publicvoidlog(JoinPointjoinPoint){logger.info("Entering"+joinPoint.getTarget().getClass().getSimpleName()+"'s"+joinPoint.getSignature().getName());.....}}

Intheaboveexamplelisting,theinvokeServiceMethodsmethodisannotatedwith@Pointcutannotation,and@Beforeannotation’svalueattributereferstotheinvokeServiceMethodsmethod.Thismeansthatthelog method is applied to the methods that match the pointcut expression specified by the @PointcutannotationontheinvokeServiceMethodsmethod.

Astheexecutionandargspointcutdesignatorsaremostlyusedwhenspecifyingpointcutexpressions,let’slookatexecutionandargspointcutdesignatorsindetail.

executionandargspointcutdesignatorsTheexecutionpointcutdesignatorhasthefollowingformat:

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, you’ll notice that an executionexpressionissimilartoamethoddeclaration.

Figure9-2Differentpartsofanexecutionexpressionmaptodifferentpartsofamethoddeclaration.

Figure9-2showshowthedifferentpartsofanexecutionexpressionmaptoamethoddeclaration:

Spring AOP framework matches different parts of an execution expression with different parts of amethoddeclaration(asshownabove)tofindthemethodstowhichanadviceisapplied.The<declaring-type-pattern>isnotshownintheabovefigurebecause<declaring-type-pattern>isonlyusedwhenyouwanttorefertomethodscontainedinaparticulartypeorpackage.

Thefollowingtabledescribesdifferentpartsofanexecutionexpression:Expressionpart Description

access-modifier-patternSpecifiestheaccessmodifierofthetargetmethod.InSpringAOP,theonlyvaluethatcanbe specified for this expression part is public. This part of execution expression isoptional.

return-type-pattern Specifiesthefully-qualifiednameofthereturntypeofthetargetmethod.Avalueof*meansthatthereturntypeofamethoddoesn’tmatter.

Page 320: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

declaring-type-patternSpecifiesthefully-qualifiednameofthetypethatcontainsthetargetmethod.Thispartof execution expression is optional. A value of * means that all types (classes andinterfaces)intheapplicationareconsideredbythepointcutexpression.

method-name-pattern Specifies the method name pattern. For instance, a value of save* means that themethodswhosenamesbeginwithsavearetargetofadvice.

method-param-pattern Specifies themethodparameterpattern. If thevalue is (..), itmeans targetmethod cancontainanynumberofargumentsornoargumentsatall.

throws-pattern Specifies the exception(s) thrown by the target method. This part of executionexpressionisoptional.

The args pointcut designator specifies the arguments that must be accepted by the target method atruntime. For instance, if you want pointcut expression to locate methods that accept an instance ofjava.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 methodavailabletoanadvice.

Let’snowlookatsomepointcutexpressionsthatuseexecutionandargspointcutdesignators:

Example1

Figure9-3executionexpressionthatusesamethodnamepattern

The methods matched by the above pointcut expression are the methods whose names start withcreateFixed.Thereturntypeisspecifiedas*,whichmeansthetargetmethodmayreturnanytype.The(..)specifiesthatthetargetmethodmayacceptzeroormorearguments.

Example2

Figure9-4executionexpressionthatspecifiesthetype(classorinterface)containingthetargetmethod(s)

ThemethodsmatchedbytheabovepointcutexpressionarethemethodsdefinedbytheMyServicetypeinsamplepackage.

Page 321: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Example3

Figure9-5executionexpressionthatspecifiesanexceptionpatternforthemethod

Themethodsmatchedby theabovepointcutexpressionare themethodsofsample.MyService type thatspecifyathrowsclause.

Example4

Figure9-6argspointcutdesignatorspecifiestheobjectinstancepassedtothetargetmethod

Intheabovepointcutexpression,combinationsofexecutionandargspointcutdesignatorshavebeenused.Youcancombinepointcutdesignatorsusing&&and||operators tocreatecomplexpointcutexpressions.Themethodsmatchedbytheabovepointcutexpressionarethemethodsdefinedinsample.MyServicetypethatacceptaninstanceofSomeObjectatruntime.The&&intheabovepointcutexpressionspecifiesthatthetargetmethodmustmatchtheexpressionsspecifiedbytheexecutionandargspointcutdesignators.

If you want an advice to have access to one or moremethod arguments passed to the target method,specifynamesofthemethodargumentsintheargsexpression,asshownhere:

Page 322: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure9-7argspointcutdesignatorspecifiesthetargetmethod’sargument(s)thatmustbemadeavailabletotheadvice

Intheabovepointcutexpression,argsexpressionspecifiesthatthetargetmethodmustacceptanargumentoftypeSomeObject,andthatargumentisavailabletoadviceviaxyzparameter.Let’ssee,arealexamplethatmakesuseofthisfeaturetopassargumentstotheadvice.

Passingtargetmethod’sargumentstoanadvice

The following example listing shows a modified version of LoggingAspect in which log method isexecutedonlyifthemethodargumentpassedtothetargetmethodisaninstanceofFixedDepositDetails,andthatFixedDepositDetailsinstanceisalsomadeavailabletothelogmethod:

Examplelisting9-7–LoggingAspectclass–passingtargetmethod’sargumentstoanadviceimportorg.aspectj.lang.annotation.Before;importorg.aspectj.lang.annotation.Pointcut;@Aspect@ComponentpublicclassLoggingAspect{.....@Pointcut(value="execution(*sample.spring.chapter09.bankapp.service.*Service.*(..))&&args(FixedDepositDetails)")privatevoidinvokeServiceMethods(FixedDepositDetailsFixedDepositDetails){}@Before(value="invokeServiceMethods(FixedDepositDetails)")publicvoidlog(JoinPointjoinPoint,FixedDepositDetailsFixedDepositDetails){.....}}

Intheaboveexamplelisting,theargsexpressionspecifiesthattheFixedDepositDetailsinstancepassedto

Page 323: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

thetargetmethodisavailabletologmethod(anadvice)viaFixedDepositDetailsparameter.AstheargsexpressionprovideslogmethodwithaninstanceofFixedDepositDetailsobject,thelogmethodhasbeenmodifiedtoacceptanadditionalargumentoftypeFixedDepositDetails.

Pointcutdesignators,likeexecution,args,within,this,target,andsoon,aredefinedbyAspectJ.SpringAOPdefinesabeanpointcutdesignatorthatisspecifictoSpringAOPframework.Let’stakeaquicklookatbeanpointcutdesignator.

beanpointcutdesignatorThebeanpointcutdesignatorisforlimitingthetargetmethodstothespecifiedbeanid(orname).Youcanspecify the exactbean idorname,oryoucan specify apattern.Let’s lookat a fewexamplesofbeanpointcutdesignator:

Example1

Figure9-8beanpointcutdesignatorspecifiesthebeanidornamewhosemethodsaretargetoftheadvice

The methods matched by the above pointcut expression are the methods defined by the bean namedsomeBean.

Example2

Figure9-9beanpointcutdesignatorspecifiesthatanadviceisappliedtothemethodsofthebeanswhoseidornamebeginwithsomeBean.

In the above pointcut expression, bean pointcut designator specifies that an advice is applied to themethodsofthebeanswhoseidornamebeginwithsomeBean.

NOTELikeanyotherpointcutdesignator,youcancombinebeanpointcutdesignatorwithotherpointcutdesignatorsusing&&and||operatorstoformcomplexpointcutexpressions.

Let’snowlookatpointcutdesignatorsthatperformmatchingbasedonannotations.

Annotations-basedpointcutdesignatorsAspectJalsoprovidespointcutdesignators,like@annotation,@target,@withinand@argsthatyoucanusewithSpringAOPtofind targetmethods.Let’s lookatcoupleofexamples thatshowusageof these

Page 324: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

pointcutdesignators:

Example1

Figure9-10@annotationpointcutdesignatorspecifiesthatanadviceisappliedtothemethodsannotatedwithSpring’sCacheableannotation

The methods matched by the above pointcut expression are the methods annotated with Spring’s@Cacheableannotation.

Example2

Figure 9-11 @target pointcut designator specifies that advice is applied to the methods of objectsannotatedwithSpring’s@Componentannotation

ThemethodsmatchedbytheabovepointcutexpressionarethemethodscontainedinanobjectannotatedwithSpring’s@Componentannotation.

Inthissection,welookedatsomeofthepointcutdesignatorsdefinedbyAspectJ.ItisimportanttonotethatnotallpointcutdesignatorsdefinedbyAspectJaresupportedbySpringAOPframework.Ifyouusean unsupported pointcut designator in pointcut expressions, Spring AOP framework throws ajava.lang.IllegalArgumentException. For instance, if you use call, set and get pointcut designators inpointcutexpressions,SpringAOPwillthrowjava.lang.IllegalArgumentException.

Let’snowlookatdifferentadvicetypesandhowtocreatethem.

Page 325: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

9-5AdvicetypesSo far in thischapter,we’ve seenexamplesofbefore advice type.Abeforeadvice type iscreatedbyannotating amethod of an aspectwith@Before annotation (refer listing 9-1, 9-6 and 9-7). The otheradvicetypesthatyoucancreateareafter,afterreturning,afterthrowing,afterandaround.

IMPORTchapter9/ch09-aop-advices (The ch09-aop-advices project shows theMyBank applicationthatusesdifferentadvicetypes.Toruntheapplication,executethemainmethodoftheBankAppclassofthisproject)

Let’snowlookatsalientfeaturesofvariousadvicetypes,andhowtocreatethem.

BeforeadviceAbefore advice is executedbefore the targetmethod is executed. If a before advicedoesn’t throwanexception, the target method will always be invoked. You can control whether the target method isexecuted or not, by using an around advice (explained later in this section). As discussed earlier,AspectJ’s@Beforeannotationisusedtoindicatethatanadviceisabeforeadvice.

@BeforeannotatedmethodmaydefineitsfirstargumenttobeoftypeJoinPoint.YoucanusetheJoinPointargument inside the advice to retrieve information about the target method. For instance, listing 9-1showed that the JoinPoint instance can be used to obtain the class name of the target object and theargumentspassedtothetargetmethod.

AfterreturningadviceAnafter returning advice is executed after the target method returns. You should note that an afterreturningadviceisnotexecutedifthetargetmethodthrowsanexception.Anafterreturningadvice isannotatedwithAspectJ’s@AfterReturning annotation.Anafterreturning advice can access the valuereturnedbythetargetmethod,andmodifyitbeforeitisreturnedtothecallingobject.

TheSampleAspectclassofch09-aop-advicesprojectrepresentsanAOPaspect.ThefollowingexamplelistingshowsthattheSampleAspectclassdefinesanafterreturningadvicethatprintsthevaluereturnedbyBankAccountService’screateBankAccountmethod:

Examplelisting9-8–SampleAspectclass–afterreturningadviceProject–ch09-aop-advicesSourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspectspackagesample.spring.chapter09.bankapp.aspects;importorg.aspectj.lang.annotation.AfterReturning;.....@AspectpublicclassSampleAspect{privateLoggerlogger=Logger.getLogger(SampleAspect.class);@Pointcut(value="execution(*sample.spring..BankAccountService.createBankAccount(..))")privatevoidcreateBankAccountMethod(){}

Page 326: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@AfterReturning(value="createBankAccountMethod()",returning="aValue")publicvoidafterReturningAdvice(JoinPointjoinPoint,intaValue){logger.info("Valuereturnedby"+joinPoint.getSignature().getName()+"methodis"+aValue);}.....}

In the above example listing, afterReturningAdvicemethod represents an after returning advice. Thepointcutexpressionspecifiedbythe@PointcutannotationlimitsthejoinpointtoBankAccountService’screateBankAccountmethod.The..intheexecutionexpressionspecifies that thesample.springpackageanditssub-packagesaresearchedtofindtheBankAccountServicetype.

Inexample listing9-8,SampleAspect’safterReturningAdvicemethod is invokedafter the invocationofBankAccountService’screateBankAccountmethod.Thereturningattributeof@AfterReturningannotationspecifiesthenamewithwhichthereturnvalueofthetargetmethodisavailabletotheadvice.Intheaboveexample listing, the value returned by the createBankAccount method is made available to theafterReturningAdvicemethodviaaValueargument.ThetypeoftheaValueargumenthasbeenspecifiedasintbecause thecreateBankAccountmethod returnsan intvalue.You shouldnote that if you specify thereturning attribute, the advice is applied only to methods that return the specified type. If an afterreturningadviceisappliedtomethodsthatreturndifferentvaluetypes(includingvoid),youcanspecifyargumenttypeofthereturnedvalueasObject.

Asshowninexamplelisting9-8,a@AfterReturningannotatedmethodmaydefineitsfirstargumenttobeoftypeJoinPointtoaccesstargetmethodinformation.

AfterthrowingadviceAnafter throwing advice is executedwhen the targetmethod throws an exception.Anafter throwingadvicecanaccesstheexceptionthrownbythetargetmethod.AnafterthrowingadviceisannotatedwithAspectJ’s@AfterThrowingannotation.

The following example listing shows anafter throwing advice that is executedwhen an exception isthrownbytargetmethods:

Examplelisting9-9–SampleAspectclass–afterthrowingadviceProject–ch09-aop-advicesSourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspectspackagesample.spring.chapter09.bankapp.aspects;importorg.aspectj.lang.annotation.AfterThrowing;.....@AspectpublicclassSampleAspect{privateLoggerlogger=Logger.getLogger(SampleAspect.class);.....

Page 327: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@Pointcut(value="execution(*sample.spring..FixedDepositService.*(..))")privatevoidexceptionMethods(){}.....@AfterThrowing(value="exceptionMethods()",throwing="exception")publicvoidafterThrowingAdvice(JoinPointjoinPoint,Throwableexception){logger.info("Exceptionthrownby"+joinPoint.getSignature().getName()+"Exceptiontypeis:"+exception);}}

Intheaboveexamplelisting,SampleAspect’safterThrowingAdvicemethodrepresentsanafterthrowingadvice. The afterThrowingAdvice method is executed when an exception is thrown by any of theFixedDepositService object’s methods. In the above example listing, the throwing attribute of@AfterThrowingannotationspecifiesthenamewithwhichtheexceptionthrownbythetargetmethodismadeavailable to theafterThrowingAdvicemethod.As the throwingattribute’svalue is exception, theexception ispassed to theafterThrowingAdvicemethodviaargumentnamedexception.Notice that thetype of the exception argument is java.lang.Throwable, which means that the afterThrowingAdvicemethod is executed for all exceptions thrown by the target method. If you want afterThrowingAdvicemethodisexecutedonlywhenaspecificexceptiontypeisthrownbythetargetmethod,changethetypeoftheexceptionargument.Forinstance,ifyouwanttheafterThrowingAdvicemethodisexecutedonlywhenthe targetmethod throws java.lang.IllegalStateException, specify java.lang.IllegalStateException as thetypeoftheexceptionargument.

Asshowninexamplelisting9-9,@AfterThrowingannotatedmethodmaydefineitsfirstargumenttobeoftypeJoinPointtoaccesstargetmethodinformation.

AfteradviceAnafteradviceisexecutedafterthetargetmethodisexecuted,irrespectiveofwhetherthetargetmethodcompletes normally or throws an exception. An after advice is annotated with AspectJ’s @Afterannotation.

The following example listing shows an after advice that is executed for BankAccountService’screateBankAccountmethod,andforthemethodsdefinedbytheFixedDepositServiceinterface:

Examplelisting9-10–SampleAspectclass–afteradviceProject–ch09-aop-advicesSourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspectspackagesample.spring.chapter09.bankapp.aspects;importorg.aspectj.lang.annotation.After;.....@AspectpublicclassSampleAspect{privateLoggerlogger=Logger.getLogger(SampleAspect.class);@Pointcut(value="execution(*sample.spring..BankAccountService.createBankAccount(..))")

Page 328: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

privatevoidcreateBankAccountMethod(){}@Pointcut(value="execution(*sample.spring..FixedDepositService.*(..))")privatevoidexceptionMethods(){}.....@After(value="exceptionMethods()||createBankAccountMethod()")publicvoidafterAdvice(JoinPointjoinPoint){logger.info("Afteradviceexecutedfor"+joinPoint.getSignature().getName());}}

In the above example listing, SampleAspect’s afterAdvice method represents an after advice. TheafterAdvicemethodisexecutedafter the targetmethodisexecuted.Notice that the@Afterannotation’svalue attribute uses || operator to combine pointcut expressions represented by thecreateBankAccountMethodandexceptionMethodsmethodstoformanewpointcutexpression.

Asshowninexamplelisting9-10,@AfterannotatedmethodmaydefineitsfirstargumenttobeoftypeJoinPoint,toaccesstargetmethodinformation.

AroundadviceAnaround advice is executed both before andafter the execution of the target method. Unlike otheradvices,anaroundadvicecancontrolwhetherthetargetmethodisexecutedornot.AnaroundadviceisannotatedwithAspectJ’s@Aroundannotation.

The following example listing shows an around advice defined by SampleAspect class of ch09-aop-advicesproject:

Examplelisting9-11–SampleAspectclass–aroundadviceProject–ch09-aop-advicesSourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspectspackagesample.spring.chapter09.bankapp.aspects;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.springframework.util.StopWatch;.....@AspectpublicclassSampleAspect{.....@Around(value="execution(*sample.spring..*Service.*(..))")publicObjectaroundAdvice(ProceedingJoinPointpjp){Objectobj=null;StopWatchwatch=newStopWatch();watch.start();try{obj=pjp.proceed();

Page 329: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

}catch(Throwablethrowable){//--performanyactionthatyouwant}watch.stop();logger.info(watch.prettyPrint());returnobj;}}

In the above example listing, the aroundAdvice method represents an around advice. TheProceedingJoinPointargumenttothearoundAdvicemethodismeantforcontrollingtheinvocationofthetargetmethod.ItisimportanttonotethatProceedingJoinPointargumentmustbethefirstargumentpassedto an around advice. When you invoke ProceedingJoinPoint’s proceed method, the target method isinvoked.Thismeansthatifyoudon’tinvoketheProceedingJoinPoint’sproceedmethod,thetargetmethodisnot invoked.IfyoupassanObject[] to theproceedmethod, thevaluescontained in theObject[]arepassedasargumentstothetargetmethod.Ifanaroundadvicechoosesnottoinvokethetargetmethod,thearoundadvicemayitselfreturnavalue.

As the target method is invoked only when you call ProceedingJoinPoint’s proceed method, aroundadviceallowsyoutoperformactionsbeforeandafter theinvocationof thetargetmethod,andtoshareinformation between these action. In example listing 9-11, the aroundAdvicemethod records the timetaken for the targetmethod to execute. The aroundAdvicemethod starts a stopwatch (represented bySpring’s StopWatch object) before calling ProceedingJoinPoint’s proceed method, and stops the stopwatchaftercallingProceedingJoinPoint’sproceedmethod.StopWatch’sprettyPrintmethodisthenusedtoprintthetimetakenbythetargetmethodtoexecute.

If you want to modify the value returned by the target method, cast the returned value ofProceedingJoinPoint’sproceedmethod to the return type of the targetmethod andmodify it.A callingmethod sees the value returned by the around advice; therefore, youmust define the return type of anadvicemethodasObjectorthetypethatisreturnedbythetargetmethod.Anadvicemethodhastheoptionto return thevalue returnedby the targetmethod,or to returnadifferentvaluealtogether.For instance,insteadofinvokingthetargetmethod,anaroundadvicemayinspecttheargument(s)beingpassedtothetargetmethodandreturnavaluefromthecacheifacacheentryexistsforthesamesetofarguments.

Sofarwehave lookedatexamples thatshowedhowtouseAspectJannotation-style tocreateaspects.Let’snowlookathowtousearegularSpringbeanasanAOPaspect.

Page 330: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

9-6SpringAOP-XMLschema-styleIn XML schema-style, a regular Spring bean acts as an aspect. A method defined in an aspect isassociatedwithanadvicetypeandapointcutexpressionusingSpring’saopschema.

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 thatdoesn’tuseAspectJ’sannotations)

The following example listing shows the SampleAspect class of ch09-aop-xml-schema project thatdefinesadvices:

Examplelisting9-12–SampleAspectclassProject–ch09-aop-xml-schemaSourcelocation-src/main/java/sample/spring/chapter09/bankapp/aspectspackagesample.spring.chapter09.bankapp.aspects;.....publicclassSampleAspect{.....publicvoidafterReturningAdvice(JoinPointjoinPoint,intaValue){logger.info("Valuereturnedby"+joinPoint.getSignature().getName()+"methodis"+aValue);}publicvoidafterThrowingAdvice(JoinPointjoinPoint,Throwableexception){logger.info("Exceptionthrownby"+joinPoint.getSignature().getName()+"Exceptiontypeis:"+exception);}.....}

The above example listing shows that the SampleAspect class defines methods that represent AOPadvices.NoticethattheSampleAspectclassisnotannotatedwith@Aspectannotationandthemethodsarenotannotatedwith@After,@AfterReturning,andsoon,annotations.

Let’snow lookathow<config>elementofSpring’saop schema isused toconfigurea regularSpringbeanasanAOPaspect.

ConfiguringanAOPaspectInXMLschema-style,AOP-specificconfigurationsareenclosedwithin<config>elementofSpring’saopschema.And,anAOPaspectisconfiguredusing<aspect>sub-elementof<config>element.

The following example listing shows how the SampleAspect class is configured using <aspect> sub-elementof<config>element:

Examplelisting9-13–applicationContext.xml–Spring’saopschemausageProject–ch09-aop-xml-schemaSourcelocation-src/main/resources/META-INF/spring

Page 331: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beans.....xmlns:aop="http://www.springframework.org/schema/aop".....>.....<beanid="sampleAspect"class="sample.spring.chapter09.bankapp.aspects.SampleAspect"/><aop:configproxy-target-class="false"expose-proxy="true"><aop:aspectid="sampleAspect"ref="sampleAspect">.....</aop:aspect></aop:config></beans>

As the <config> element relies on autoproxying, the <config> element defines proxy-target-class andexpose-proxy attributes. If you remember, the same attributes were defined by <aspectj-autoproxy>elementofSpring’saopschema.Refer section9-3 toknowmoreaboutproxy-target-class and expose-proxyattributes.

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> element’s idattributespecifiesauniqueidentifierforanaspect,andtherefattributespecifiestheSpringbeanthatyouwanttoconfigureasanAOPaspect.

Now,thatwehaveconfiguredanAOPaspect,let’slookathowtomapmethodsdefinedinanAOPaspecttodifferentadvicetypesandpointcutexpressions.

ConfiguringanadviceYou configure an advice using one of the following sub-elements of <aspect> element: <before> (forconfiguring a before advice type), <after-returning> (for configuring an after returning advice type),<after-throwing>(forconfiguringanafterthrowingadvicetype),<after>(forconfiguringanafteradvicetype)and<around>(forconfiguringanaroundadvicetype).

Let’snowlookathowtheadvicesdefinedintheSampleAspectclassofch09-aop-xml-schemaprojectareconfiguredintheapplicationcontextXMLfile.

Configuringanafterreturningadvice

The following figure showshow theSampleAspect’safterReturningAdvicemethod is configured as anafterreturningadviceusing<after-returning>element:

Page 332: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure 9-12 afterReturningAdvicemethod of SampleAspect class is configured as an after returningadviceusing<after-returning>elementofSpring’saopschema

The <after-returning> element’smethod attribute specifies the name of themethodwhich youwant toconfigure as an after returning advice. The returning attribute serves the same purpose as the@AfterReturning annotation’s returning attribute; it makes the returned value from the target methodavailable to the advice. The pointcut attribute specifies the pointcut expression used for finding themethodstowhichtheadviceisapplied.

Configuringanafterthrowingadvice

The following figure showshow theSampleAspect’safterThrowingAdvicemethod is configured as anafterthrowingadviceusing<after-throwing>element:

Figure 9-13 afterThrowingAdvice method of SampleAspect class is configured as an after throwingadviceusing<after-throwing>elementofSpring’saopschema

The <after-throwing> element’smethod attribute specifies the name of themethodwhich youwant toconfigure as an after throwing advice. The throwing attribute serves the same purpose as the@AfterThrowing annotation’s throwing attribute; it makes the exception thrown by the target methodavailable to the advice. The pointcut attribute specifies the pointcut expression used for finding themethodstowhichtheadviceisapplied.

Theotheradvicetypes(before,afterandaround)areconfiguredthesamewayastheafterreturningandafterthrowingadvicesthatwejustsaw.

Let’snowlookatdifferentwaysinwhichyoucanassociateapointcutexpressionwithanadvice.

AssociatingapointcutexpressionwithanadviceThe <after>, <after-returning>, <after-throwing>, <before> and <around> elements of Spring’s aopschemadefineapointcutattributethatyoucanusetospecifythepointcutexpressionassociatedwiththeadvice.Ifyouwanttosharepointcutexpressionsbetweendifferentadvices,youcanusethe<pointcut>sub-elementofthe<config>elementtodefinepointcutexpressions.

The following example listing shows that the <pointcut> element is used for defining pointcutexpressions:

Examplelisting9-14–applicationcontextXML-<pointcut>element<beans.....xmlns:aop="http://www.springframework.org/schema/aop".....>.....

Page 333: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<beanid="sampleAspect"class="sample.spring.chapter09.bankapp.aspects.SampleAspect"/><aop:configproxy-target-class="false"expose-proxy="true"><aop:pointcutexpression="execution(*sample.spring..*Service.*(..))"id="services"/><aop:aspectid="sampleAspect"ref="sampleAspect"><aop:aftermethod="afterAdvice"pointcut-ref="services"/><aop:aroundmethod="aroundAdvice"pointcut-ref="services"/></aop:aspect></aop:config></beans>

In the above example listing, the <pointcut> element specifies a pointcut expression. The expressionattributespecifiesthepointcutexpression,andtheidattributespecifiesauniqueidentifierforthepointcutexpression.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 aboveexamplelisting,<after>and<around>elementsusepointcut-refattributetorefertotheservicespointcutexpressions.

Page 334: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

9-7SummaryIn thischapter,we lookedatAOPconceptsandhowSpringAOPcanbeused toaddresscross-cuttingconcernsinSpringapplications.WesawhowtocreateaspectsusingAspectJannotation-styleandXMLschema-style.Wealsodiscussedhowtocreateandconfiguredifferentadvicetypes.Wetoucheduponthepointcut expressions that you can create to find matching methods in the application. For a morecomprehensive coverage of Spring AOP please refer to Spring reference documentation. In the nextchapter, we’ll look at how to develop web applications using Spring Web MVC module of SpringFramework.

Page 335: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter10–SpringWebMVCbasics

Page 336: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-1IntroductionThe Spring Web MVC module of Spring Framework provides an MVC (Model-View-Controller)frameworkthatyoucanusefordevelopingservlet-basedwebapplications.SpringWebMVCisanon-intrusiveframeworkthatprovidesaclearseparationofconcernsbetweenapplicationobjectsthatformtheweblayer.Forinstance,acontrollerobjectisusedforprocessingtherequest,avalidatorobjectisused for performing validation, and a command object is used for storing form data, and so on. It isimportant to note that none of these application objects implement or extend from any Spring-specificinterfaceorclass.

In this chapter,we’ll first look at the directory structure thatwill be followed by all the samplewebprojectsdiscussedinthischapter.We’llthenlookatasimple‘HelloWorld’webapplicationdevelopedusingSpringWebMVC.Intherestofthischapter,we’lllookatsomeoftheSpringWebMVCannotationsinthecontextofourMyBankwebapplication.ThischaptersetsthestagefordiscussingmoreadvancedSpringWebMVCfeaturesinthenextchapter.

IMPORTchapter10/ch10-helloworld(Thisprojectshowsasimple‘HelloWorld’webapplicationthatusesSpringWebMVC.ReferappendixAtolearnhowtodeploysamplewebprojectsonTomcatserver.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 ‘HelloWorld!!’message.)

Page 337: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-2DirectorystructureofsamplewebprojectsFigure10-1describestheimportantdirectoriesofch10-helloworldwebproject.Someoftheimportantpointsthatyouneedtorememberare:

§ Thesrc/main/resources/META-INF/springfoldercontains therootwebapplicationcontextXMLfilethatdefinesbeansthataresharedbyalltheservletsandfiltersofthewebapplication.Therootweb application context XML file typically defines data sources, services, DAOs, transactionmanagers, and so on. The root web application context XML file is loaded by Spring’sContextLoaderListener (a javax.servlet.ServletContextListener implementation).Refer section10-10tolearnabouthowContextLoaderListenerisconfiguredinweb.xmlfile.

§Thesrc/main/webapp/WEB-INF/springfoldercontainsthewebapplicationcontextXML file thatdefinesbeansthatformpartoftheweblayeroftheapplication.ThewebapplicationcontextXMLfiletypicallydefinescontrollers(alsoreferredtoashandlers),handlermappings,viewresolvers,exceptionresolvers,andsoon.We’lllearnabouttheseobjectslaterinthischapter.

§ThebeansdefinedintherootwebapplicationcontextXMLfileareavailabletothebeansdefinedinthewebapplicationcontextXMLfile.Thismeans,abeandefinedinthewebapplicationcontextXMLfilecanbedependentonabeandefinedintherootwebapplicationcontextXMLfile,butnottheotherwayround.

Figure10-1Directorystructureofch10-helloworldproject

Page 338: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Let’snowlookattheconfigurationfilesandtheclassesthatformthech10-helloworldproject.

Page 339: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-3Understandingthe‘HelloWorld’webapplicationIfyouright-clickonthech10-helloworldprojectinyourEclipseIDEandselectBuildPathàConfigureBuild Path option, you’ll notice that the project depends on spring-beans, spring-context, spring-core,spring-expression,spring-webandspring-webmvcJARfiles.TheseJARfilesarerequiredforbuildingabasicSpringWebMVCapplication.

The following tabledescribes theconfiguration filesand theJavasource files thatconstitute thech10-helloworldproject.Laterinthissection,we’lltakeacloserlookatthesefilesandclasses.

Configuration file or Javasourcefile Description

HelloWorldController.javaSpringWebMVCcontrollerthatisresponsibleforrequesthandling.

You’ll find this file inside sample.spring.chapter10.web package of src/main/javafolder.

helloworld.jspJSPfilethatshowsthe‘HelloWorld!!’message

You’llfindthisfileinsidesrc/main/webapp/WEB-INF/jspfolder

myapp-config.xmlWeb application context XML file that contains bean definitions for controllers,handlermappings,andsoon.

You’llfindthisfileinsidesrc/main/webapp/WEB-INF/springfolder

web.xmlWebapplicationdeploymentdescriptor

You’llfindthisfileinsidesrc/main/webapp/WEB-INFfolder

Apartfromthefilesshownintheabovetable,thech10-helloworldprojectalsocontainslog4j.propertiesfile that containsLog4j configuration, and pom.xml file that goes as input to themaven build tool. Toknow more about these files refer to Log4j (http://logging.apache.org/log4j/1.2/) and Maven(http://maven.apache.org/index.html)documentation.

Let’snowtakeacloserlookateachofthefilesdescribedintheabovetable.

HelloWorldController.java–HelloWorldwebapplication’scontrollerclassIn Spring Web MVC applications, the request handling logic is contained in controller classes. ThefollowingexamplelistingshowstheHelloWorldControllercontrollerclassofch10-helloworldproject:

Examplelisting10-1–HelloWorldControllerclassProject–ch10-helloworldSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importorg.springframework.web.servlet.ModelAndView;importorg.springframework.web.servlet.mvc.Controller;.....publicclassHelloWorldControllerimplementsController{@OverridepublicModelAndViewhandleRequest(HttpServletRequestrequest,

Page 340: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

HttpServletResponseresponse)throwsException{Map<String,String>modelData=newHashMap<String,String>();modelData.put("msg","HelloWorld!!");returnnewModelAndView("helloworld",modelData);}}The above example listing shows that the HelloWorldController class implements Spring’sController interface. The Controller interface defines a handleRequest method, which you need toimplement to provide the request handling logic. The handleRequestmethod returns aModelAndViewobjectthatcontainsthefollowinginformation:

§thedata(referredtoasmodeldata)tobeshowntotheuser,and§logicalnameoftheJSPpage(referredtoasview)thatshowsthemodeldata

Themodeldataisusuallyrepresentedasajava.util.Maptypeobject,andeachentryinthejava.util.Mapobject represents amodelattribute. The name of the view (the JSP page) to be shown to the user isspecifiedasaStringvalue.

Example listing 10-1 shows that the HelloWorldController’s handleRequest method returns aModelAndView object that contains helloworld (a String value) as the view name andmodelData (ajava.util.Maptypeobject)asthemodeldata.ThemodelDatacontainsamsgmodelattributewhosevalueis the‘HelloWorld!!’message.We’llsoonsee that themsgmodelattribute isusedby thehelloworldview(aJSPpage)toshowthe‘HelloWorld!!’messagetotheusers.

The following diagram summarizes howHelloWorldController’s handleRequestmethod renders a JSPpage:

Page 341: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure10-2SpringWebMVCframeworkinvokestheHelloWorldController’shandleRequestmethodandusesthereturnedModelAndViewobjecttorenderthehelloworld.jsppage

TheabovefigureshowsthattheSpringWebMVCframeworkinterceptsanincomingHTTPrequestandinvokes the HelloWorldController’s handleRequest method. The handleRequest method returns aModelAndView object that contains the model data and the view information. After receiving theModelAndViewobjectfromthehandleRequestmethod,theSpringWebMVCframeworkdispatchestheHTTPrequesttothehelloworld.jsppageandmakesthemodelattributesavailabletothehelloworld.jsppageasrequestattributes.

NOTE SpringWebMVCmakes themodel attributes available to the view technology (like JSP andVelocity) ina format that is suitable for theview technology.For instance, ifyouareusing JSPas theviewtechnology,modelattributesaremadeavailabletotheJSPpagesasrequestattributes.

helloworld.jsp–JSPpagethatshowsthe‘HelloWorld!!’messageThefollowingexamplelistingshowsthehelloworld.jsppageofch10-helloworldproject:

Examplelisting10-2–helloworld.jspJSPpageProject–ch10-helloworldSourcelocation-src/main/webapp/WEB-INF/jsp

<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%><c:outvalue="${msg}"/>

Intheaboveexamplelisting,<c:out>printsthevalueofmsgrequestattribute.Themsgrequestattributerefers to the msg model attribute returned by HelloWorldController’s handleRequest method (referexamplelisting10-1).Asthevalueofmsgmodelattributeis‘HelloWorld!!’,helloworld.jspJSPpageshows‘HelloWorld!!’message.

myapp-config.xml–WebapplicationcontextXMLfileThefollowingexamplelistingshowsthebeansconfiguredinmyapp-config.xmlfileofch10-helloworldproject:

Page 342: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting10-3–myapp-config.xmlProject–ch10-helloworldSourcelocation-src/main/webapp/WEB-INF/spring

<beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><beanname="helloWorldController"class="sample.spring.chapter10.web.HelloWorldController"/><beanid="handlerMapping"class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><propertyname="urlMap"><map><entrykey="/sayhello"value-ref="helloWorldController"/></map></property></bean><beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="/WEB-INF/jsp/"/><propertyname="suffix"value=".jsp"/></bean></beans>The above example listing shows that apart from the HelloWorldController, Spring’sSimpleUrlHandlerMappingandInternalResourceViewResolverbeansarealsoconfiguredinthemyapp-config.xmlfile.

SimpleUrlHandlerMapping bean (an implementation of Spring’s HandlerMapping interface) maps anincomingHTTPrequesttothecontrollerresponsibleforhandlingtherequest.SimpleUrlHandlerMappingbeanuses theURLpath tomap a request to a controller.TheurlMap property (of type java.util.Map)specifies URL path to controller bean mapping. In example listing 10-3, the "/sayhello" URL path(specifiedbythekeyattribute)ismappedtotheHelloWorldControllerbean(specifiedbythevalue-refattribute).YoushouldnotethattheURLpathspecifiedbythekeyattributeisrelativetotheURLpathtowhichSpring’sDispatcherServlet (a servlet) ismapped in theweb applicationdeployment descriptor.DispatcherServletisdiscussedlaterinthissection.

InternalResourceViewResolverbean(animplementationofSpring’sViewResolverinterface)locatestheactualview(like,JSPorservlet)basedontheviewnamecontainedintheModelAndViewobject.Theactual view is located by prepending the value of prefix property andappending the value of suffixproperty to theviewname.Theexample listing10-3shows that thevalueofprefixproperty is /WEB-INF/jsp,and thevalueof suffixproperty is .jsp.As theHelloWorldController’shandleRequestmethodreturnsaModelAndViewobjectwhichcontainshelloworldastheviewname,theactualviewis/WEB-

Page 343: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

INF/jsp/helloworld.jsp(astringthatisobtainedbyprepending/WEB-INF/jspandappending.jsptothehelloworldviewname).

The following figure shows the role played by SimpleUrlHandlerMapping andInternalResourceViewResolverbeansinthe‘HelloWorld’webapplication:

Figure 10-3 SimpleUrlHandlerMapping locates the controller to be invoked andInternalResourceViewResolverresolvestheactualviewbasedontheviewname

SimpleUrlHandlerMapping and InternalResourceViewResolver beans are automatically detected bySpring Web MVC and used for finding the controller for request handling and resolving views,respectively.

web.xml–WebapplicationdeploymentdescriptorIn Spring Web MVC based applications, requests are intercepted by a DispatcherServlet (a servletprovidedbySpringWebMVC)thatisresponsiblefordispatchingrequeststotheappropriatecontroller.

The following example listing shows the configuration of DispatcherServlet inweb.xml file of ch10-helloworldproject:

Examplelisting10-4–web.xmlProject–ch10-helloworldSourcelocation-src/main/webapp/WEB-INF/spring

<web-appxmlns="java.sun.com/xml/ns/javaee"xmlns:xsi="w3.org/2001/XMLSchema-instance"xsi:schemaLocation="java.sun.com/xml/ns/javaeejava.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>

Page 344: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/helloworld/*</url-pattern></servlet-mapping></web-app>ADispatcherServlet is associatedwith awebapplication contextXML filewhich is identifiedby thecontextConfigLocation servlet initialization parameter. In the above example listing, thecontextConfigLocationinitializationparameterreferstothemyapp-config.xmlfile(referexamplelisting10-3).

If you don’t specify the contextConfigLocation parameter, the DispatcherServlet looks for the webapplication context XML file named <name-of-DispatcherServlet>-servlet.xml file in the WEB-INFdirectory of theweb application.Here, the value of <name-of-DispatcherServlet> is the servlet namespecified by the <servlet-name> sub-element of <servlet> that configures the DispatcherServlet. Forinstance, if we had not specified the contextConfigLocation parameter in example listing 10-3, theDispatcherServletwouldhavelookedforafilenamedhello-servlet.xmlintheWEB-INFdirectory.

TheHandlerMappingandViewResolverbeansdefinedinthewebapplicationcontextXMLfileareusedby the DispatcherServlet for request processing. DispatcherServlet uses the HandlerMappingimplementation for finding the appropriate controller for the request, and uses the ViewResolverimplementationforresolvingtheactualviewbasedontheviewnamereturnedbythecontroller.

Inthecontextof‘HelloWorld’webapplication,thefollowingfiguresummarizestheroleplayedbytheDispatcherServletservletinrequestprocessing:

Figure10-4DispatcherServletusesHandlerMappingandViewResolverbeansforrequestprocessing.

The above figure shows that the following sequence of activities are performed by SpringWebMVCduringrequestprocessing:

§requestisfirstinterceptedbytheDispatcherServletservlet

Page 345: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

§DispatcherServletusestheHandlerMappingbean(whichisSimpleUrlHandlerMappingbeanincaseof‘HelloWorld’webapplication)tofindanappropriatecontrollerforhandlingtherequest

§ DispatcherServlet calls the request handling method of the controller (which isHelloWorldController’shandleRequestmethodincaseof‘HelloWorld’webapplication)

§DispatcherServletsendstheviewnamereturnedbythecontrollertotheViewResolverbean(whichisInternalResourceViewResolverbeanincaseof‘HelloWorld’webapplication)tofindtheactualview(JSPorservlet)toberendered

§ DispatcherServlet dispatches the request to the actual view (JSP or servlet). The model datareturnedbythecontrolleraremadeavailabletotheviewasrequestattributes.

The DispatcherServlet of ‘Hello World’ web application is mapped to /helloworld/* pattern (referexamplelisting10-4),andSimpleUrlHandlerMappingmaps/sayhelloURLpathtoHelloWorldControllerbean (refer example listing 10-3). If you access the URL http://localhost:8080/ch10-helloworld/helloworld/sayhello, it results in invocation of handleRequest method ofHelloWorldController controller. The following figure shows how Spring Web MVC maps the URLhttp://localhost:8080/ch10-helloworld/helloworld/sayhellototheHelloWorldControllercontroller:

Figure10-5HowtheURLpathhttp://localhost:8080/ch10-helloworld/helloworld/sayhelloismappedtotheHelloWorldControllerbySpringWebMVC

Intheabovefigure,the/ch10-helloworldpartoftheURLrepresentsthecontextpathofthe‘HelloWorld’webapplication, the /helloworldpartof theURLmaps to theDispatcherServletservlet (referexamplelisting 10-4), and the /sayhello part of the URL maps to the HelloWorldController controller (referexamplelisting10-3).

In this section,we saw how a simple ‘HelloWorld’web application is developed using SpringWebMVC.Let’snowtakeacloserlookattheDispatcherServletservletthatactsafrontcontrollerinaSpringWebMVCapplication.

Page 346: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-4DispatcherServlet–thefrontcontrollerIntheprevioussection,wesawthattheDispatcherServletactsasafrontcontrollerthatinteractswiththeHandlerMappingandViewResolverbeansdefined in thewebapplicationcontextXML file toprocessrequests.Inthissection,we’lllookathowDispatcherServletworksbehindthescenes.

Atthetimeofinitialization,aDispatcherServletloadsthecorrespondingwebapplicationcontextXMLfile(whichcouldbespecifiedviacontextConfigLocationinitializationparameter,orisnamedas<name-of-DispatcherServlet>-servlet.xmlfileandplacedintheWEB-INFdirectory),andcreatesaninstanceofSpring’sWebApplicationContextobject.WebApplicationContextisasub-interfaceofApplicationContextinterface that provides features that are specific to web applications. For instance, beans in theWebApplicationContext can have additional scopes, like request and session. You can think ofWebApplicationContext object as an object that represents a Spring container instance in SpringWebMVCapplications.

ThefollowingtabledescribestheadditionalscopesthatyoucanspecifyforbeansconfiguredinthewebapplicationcontextXMLfile:

Beanscope Description

request

SpringcontainercreatesanewbeaninstanceforeveryHTTPrequest.ThebeaninstanceisdestroyedbytheSpringcontainerwhentheHTTPrequestcompletes.

This scope is valid only for ApplicationContext implementations that are applicable in webapplication scenarios. For instance, if you are using XmlWebApplicationContext orAnnotationConfigWebApplicationContext,onlythenyoucanspecifytherequestscopeforabean.

session

SpringcontainercreatesanewbeaninstancewhenanHTTPSessioniscreated.ThebeaninstanceisdestroyedbytheSpringcontainerwhentheHTTPSessionisdestroyed.

This scope is valid only for ApplicationContext implementations that are applicable in webapplication scenarios. For instance, if you are using XmlWebApplicationContext orAnnotationConfigWebApplicationContext,onlythenyoucanspecifythesessionscopeforabean.

globalSession Thisscopeisapplicableonlyincaseofportletapplications.

Ifyourwebapplicationconsistsofmultiplemodules,youmaydefineaDispatcherServletforeachofthemodules in theweb.xml file. In such a scenario, eachDispatcherServlet has its ownweb applicationcontextXMLfilethatcontainsbeans(likecontrollers,viewresolvers,andsoon)specifictothatmodule.YoushouldnotethatthesebeansarenotsharedbetweenDispatcherServletinstances.ThebeansthataresharedbetweenDispatcherServletinstancesaredefinedintherootwebapplicationcontextXMLfile.Asmentionedearlier,therootwebapplicationcontextXMLfiledefinesdatasources,servicesandDAOs,andsoon,thataretypicallysharedbydifferentmodulesofawebapplication.Refertosection10-10tolearnabouthowtherootwebapplicationcontextXMLfileisloaded.

ThefollowingfigureshowsrelationshipbetweenbeansdefinedbythewebapplicationcontextXMLfileassociatedwithaDispatcherServletandthebeansdefinedbytherootwebapplicationcontextXMLfile:

Page 347: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure 10-6 Beans in the root WebApplicationContext are inherited by the WebApplicationContextinstanceassociatedwithaDispatcherServlet

In the above figure, servlet1, servlet2 and servlet3 are the names of DispatcherServlet instancesconfigured in theweb.xml file.And, servlet1-servlet.xml,servlet2-servlet.xml and servlet3-servlet.xmlarewebapplicationcontextXMLfiles thatare loadedbyservlet1,servlet2andservlet3, respectively.When DispatcherServlet instances are initialized, an instance of WebApplicationContext is createdcorresponding to each servlet1-servlet.xml, servlet2-servlet.xml and servlet3-servlet.xml files andassociated with the DispatcherServlet instance. A WebApplicationContext instance is also createdcorrespondingtotherootwebapplicationcontextXMLfile,root-servlet.xml.Thebeanscontainedintheroot WebApplicationContext instance are available to all the WebApplicationContext instancesassociatedwithDispatcherServlets.

Let’snowlookathowacontrolleroranyotherSpringbeandefinedinawebapplicationcontextXMLfilecanaccessServletContextandServletConfigobjects.

AccessingServletContextandServletConfigobjectsIn some scenarios, beans defined in the web application context XML filemay require access to theServletContextorServletConfigobjectassociatedwiththewebapplication.

ServletContextisaServletAPIobjectthatabeancanusetocommunicatewiththeservletcontainer.Forinstance,youcanuseittogetandsetcontextattributes,obtaincontextinitializationparameters,andsoon.If a bean class implements Spring’s ServletContextAware interface (a callback interface), the SpringcontainerprovidesthebeaninstancewithaninstanceofServletContextobject.

ServletConfig isaServletAPIobject thatabeancanuse toobtainconfiguration informationabout theDispatcherServlet that intercepted the request. For instance, you can use it to obtain initializationparameterspassedtotheDispatcherServletandthenamewithwhichtheDispatcherServletisconfiguredinweb.xml.IfabeanclassimplementsSpring’sServletConfigAwareinterface(acallbackinterface),theSpringcontainerprovidesthebeaninstancewithaninstanceofServletConfigobject.

The following example listing shows a bean class that implements ServletContextAware and theServletConfigAwareinterface:

Examplelisting10-5–ServletContextAwareandServletConfigAwareusage

Page 348: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importjavax.servlet.ServletConfig;importjavax.servlet.ServletContext;importorg.springframework.web.context.ServletConfigAware;importorg.springframework.web.context.ServletContextAware;publicclassABeanimplementsServletContextAware,ServletConfigAware{privateServletContextservletContext;privateServletConfigservletConfig;@OverridepublicvoidsetServletContext(ServletContextservletContext){this.servletContext=servletContext;}@OverridepublicvoidsetServletConfig(ServletConfigservletConfig){this.servletConfig=servletConfig;}publicvoiddoSomething(){//--useServletContextandServletConfigobjects}}

The above example listing shows that the ABean class implements ServletContextAware andServletConfigAware interface. The ServletContextAware interface defines a setServletContext methodwhichisinvokedbytheSpringcontainertoprovideABeaninstancewithaninstanceofServletContextobject. The ServletConfigAware interface defines a setServletConfigmethod which is invoked by theSpringcontainertoprovideABeaninstancewithaninstanceofServletConfigobject.

WesawearlierthatyoucancreateacontrollerbyimplementingtheControllerinterface.Let’snowlookat@Controllerand@RequestMappingannotationsthatsimplifydevelopingcontrollers.

Page 349: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-5 Developing controllers using @Controller and@RequestMappingannotationsSpring Web MVC provides classes, like MultiActionController, UrlFilenameViewController,AbstractController,andsoon,thatyoucanextendtocreateyourcontrollerimplementation.IfyouextendaSpring-specificclassorimplementaSpring-specificinterfacetocreateacontroller,thecontrollerclassbecomes tightly coupled with Spring. Spring 2.5 introduced annotations like @Controller,@RequestMapping, @ModelAttribute, and so on, that allow you to create controllers with flexiblemethod signatures. In this section,we’ll lookatdifferentSpringWebMVCannotations fordevelopingannotatedcontrollers.

Let’sfirstlookata‘HelloWorld’webapplicationthatusesanannotatedcontrollertoshowthe‘HelloWorld!!’message.

IMPORT chapter 10/ch10-annotation-helloworld (This project shows a simple ‘Hello World’ webapplicationthatusesanannotatedcontrollertoshow‘HelloWorld!!’message.Ifyoudeploytheprojecton Tomcat server and access the URL http://localhost:8080/ch10-annotation-helloworld/helloworld/saySomething/sayhello,you’llseethe‘HelloWorld!!’message.)

Developinga‘HelloWorld’webapplicationusinganannotatedcontrollerThech10-annotation-helloworldproject issimilar toch10-helloworld, except that thech10-annotation-helloworld project uses an annotated controller to show ‘HelloWorld !!’message. Theweb.xml andhelloworld.jspfilesinboththeprojectsareexactlythesame,butHelloWorldController.javaandmyapp-config.xmlfilesaredifferent.Forthisreason,we’llrestrictourdiscussiontoHelloWorldController.javaandmyapp-config.xmlfilesinthissection.

Let’sfirstlookathowtocreateacontrollerusing@Controllerand@RequestMappingannotations.

@Controllerand@RequestMappingannotations

You designate a particular class as a SpringWebMVC controller by annotating it [email protected], you use@RequestMapping annotation tomap an incoming request to the appropriatemethodofacontroller.

The following example listing shows the HelloWorldController class that uses @Controller and@RequestMappingannotations:

Examplelisting10-6–HelloWorldControllerclass-@Controllerand@RequestMappingusagepackagesample.spring.chapter10.web;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.servlet.ModelAndView;.....

Page 350: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@Controller(value="sayHelloController")@RequestMapping("/saySomething")publicclassHelloWorldController{@RequestMapping("/sayhello")publicModelAndViewsayHello(){Map<String,String>modelData=newHashMap<String,String>();modelData.put("msg","HelloWorld!!");returnnewModelAndView("helloworld",modelData);}}In the above example listing, the HelloWorldController class is annotated with @Controller and@RequestMappingannotations,andthesayHellomethodisannotatedwith@RequestMappingannotation.@Controllerannotationisaspecializedformof@Componentannotation(referchapter6)thatindicatesthattheHelloWorldControllerisacontrollercomponent.

Like @Service (refer chapter 6) and @Repository (refer chapter 7) annotated classes, @Controllerannotated classes are automatically registered with the Spring container; you don’t need to explicitlydefine a@Controller annotated class in theweb application contextXML file. The value attribute of@ControllerannotationspecifiesthenamewithwhichtheclassisregisteredwiththeSpringcontainer.Thevalueattributeservesthesamepurposeasthe<bean>element’sidattribute.Ifthevalueattributeisnot specified, thename (beginningwith lowercase first letter)of theclass isused to register theclasswiththeSpringcontainer.

@RequestMappingannotationmaps incomingwebrequests toappropriatecontrollersand/orcontrollermethods.@RequestMappingannotationatthetype-levelmapsarequesttotheappropriatecontroller.Forinstance,@RequestMapping("/saySomething")onHelloWorldControllerclassindicatesthatallrequeststo/saySomethingrequestpatharehandledbytheHelloWorldControllercontroller.

@RequestMapping at the method-level narrows down the @RequestMapping at the type-level to aspecific method in the controller class. For instance, @RequestMapping("/sayhello") annotation onsayHellomethodinexamplelisting10-6specifiesthatthesayHellomethodisinvokedwhentherequestpathis/saySomething/sayhello.Noticethat theHelloWorldController’ssayHellomethoddoesn’tacceptanyargumentsandreturnsaModelAndViewobject.This ispossiblebecauseannotatedcontrollerscanhave flexible method signatures. In section 10-7, we’ll look at possible arguments and return types@RequestMappingannotatedmethodscandefine.

@RequestMapping annotation at the type-level usually specifies a request pathor a pathpattern.And,@RequestMapping annotation at the method-level usually specifies an HTTP method or a requestparametertofurthernarrowdownthemappingspecifiedbythetype-level@RequestMappingannotation.The following figure shows how http://localhost:8080/ch10-annotation-helloworld/helloworld/saySomething/sayhelloURLwill result in invocationofHelloWorldController’ssayHellomethodbySpringWebMVC:

Page 351: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure10-7HowarequestURLismappedtoanappropriate@RequestMappingannotatedmethodofacontroller

Theabove figureshowshowaparticular requestURLresults in invocationofHelloWorldController’ssayHellomethod.

Let’snowlookathowannotation-drivendevelopmentofSpringWebMVCcontrollersisenabledinanapplication.

EnablingSpringWebMVCannotations

TouseannotatedcontrollersinyourSpringWebMVCapplication,youneedtoenableSpringWebMVCannotations using <annotation-driven> element of Spring’s mvc schema, as shown in the followingexamplelisting:

Examplelisting10-7–myapp-config.xmlProject–ch10-annotation-helloworldSourcelocation-src/main/webapp/WEB-INF/spring

<beans.....xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation=".....http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd....."><mvc:annotation-driven/><context:component-scanbase-package="sample.spring.chapter10.web"/><beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="/WEB-INF/jsp/"/><propertyname="suffix"value=".jsp"/></bean></beans>

Page 352: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

In theaboveexample listing,<mvc:annotation-driven>elementofSpring’smvcschemaenablesuseofSpring Web MVC annotations in implementing controllers. Also, <component-scan> element (refersection6-2formoredetails)ofcontextschemaisusedtoautomaticallyregister@ControllerannotatedclasseswiththeSpringcontainer.

Inthissection,wesawhowtodevelopasimple‘HelloWorld’webapplicationusing@[email protected]’snowlookat therequirementsof theMyBankwebapplicationthatwe’lldevelopinthischapterusingSpringWebMVCannotations.

Page 353: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-6MyBankwebapplication’srequirementsThefollowingfigureshows thehomepageofMyBankwebapplication thatdisplaysa listofcurrentlyactivefixeddepositsinthesystem:

Figure10-8MyBankwebapplication’shomepageshowsfixeddepositdetails.Thewebpageprovidestheoptiontoclose,editandcreateafixeddeposit.

In the above figure, the ID column shows the unique identifier for a fixed deposit. The ID value isassignedtoafixeddepositwhenitiscreatedbyauser.CloseandEdithyperlinksallowausertoremoveoreditdetailsofafixeddeposit.TheCreatenewFixedDepositbuttonshowsthe‘Openfixeddeposit’formforenteringdetailsofthefixeddeposittobeopened,asshowninthefollowingfigure:

Figure10-9‘Openfixeddeposit’formforopeningfixeddeposits.Amount,TenureandEmailfieldsaremandatory.

Intheabovefigure,clickingtheSavebuttonsavesthefixeddepositdetailsinthedatastore,andGoBackhyperlink takes theuserback to thewebpage thatshows thefixeddeposit list (refer figure10-8).Theabove figure shows that appropriate errormessages aredisplayed if the entereddatadoesn’tmeet theconstraintssetonAmount,TenureandEmailfields.

WhenyouclicktheEdithyperlink infigure10-8,aformsimilar tofigure10-9 isshownformodifying

Page 354: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

details of the selected fixed deposit. And, clicking the Close hyperlink in figure 10-8 removes theselectedfixeddepositfromthelistoffixeddeposits.

Now,thatweknowtheMyBankwebapplicationrequirements,let’slookathowweimplementitusingSpringWebMVCannotations.

Page 355: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-7 Spring Web MVC annotations - @RequestMapping and@RequestParamInsection10-5,wesawthatwecanuse@Controllerand@RequestMappingannotations todevelopasimplecontroller. In this section,we’ll takeacloser lookat@RequestMapping andotherSpringWebMVCannotationsthatsimplifydevelopingannotatedcontrollers.

IMPORTchapter10/ch10-bankapp (This project shows theMyBankweb application that allows itsuser to manage fixed deposits. If you deploy the project on Tomcat server and access the URLhttp://localhost:8080/ch10-bankapp,you’llseethelistoffixeddeposits(asshowninfigure10-8)inthesystem.)

Let’sbeginbylookingatthe@RequestMappingannotation.

Mappingrequeststocontrollersorcontrollermethodsusing@RequestMappingInsection10-5,wesawthat the@RequestMappingannotation isusedat the typeandmethod-level tomap requests to controllers and itsmethods. In this section,we’ll first look at howSpringWebMVCmapsawebrequesttoaparticularcontrollermethodthatuses@RequestMappingannotation.We’llthenlook at the attributes of @RequestMapping annotation, and the arguments and return types that@RequestMappingannotatedmethodscanhave.

@RequestMappingannotationandRequestMappingHandlerMapping

Thefollowingexample listingshows@RequestMappingannotationusage inSomeController (aSpringWebMVCcontroller)class:

Examplelisting10-8–SomeControllerclass-@RequestMappingusage@Controller@RequestMapping("/type_Level_Url")publicclassSomeController{@RequestMapping("/methodA_Url")publicModelAndViewmethodA(){.....}@RequestMapping("/methodB_Url")publicModelAndViewmethodB(){.....}}The <annotation-driven> element of Spring’s mvc schema creates an instance ofRequestMappingHandlerMapping(aHandlerMappingimplementation)thatisresponsibleformappingaweb request to an appropriate@RequestMapping annotatedmethod. RequestMappingHandlerMappingconsiders controller methods as endpoints, and is responsible for uniquely mapping a request to acontroller method based on the @RequestMapping annotations at type- and method-level. In case ofSomeController, if the request path is /type_Level_Url/methodA_Url,methodA is invoked, and if therequest path is /type_Level_Url/methodB_Url,methodB is invoked. You should note that if a requestcannotbemappeduniquelytoacontrollermethod,thenaHTTP404(whichmeans,resourcenotfound)

Page 356: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

statuscodeisreturned.

Theattributesof@RequestMappingannotationareused tonarrowdownthemappingofa request toaparticularcontrolleroracontrollermethod.Youcanspecify theseattributesatboth [email protected]’snowlookattheattributesof@RequestMappingannotation.

Mappingrequestsbasedonrequestpath

@RequestMapping’svalueattributespecifiestherequestpathtowhichacontrollerorcontrollermethodis 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").

YoucanalsospecifyAnt-stylepathpatternsasthevalueofvalueattribute.Forinstance,youcanspecifypatterns,like/myUrl/*,/myUrl/**and/myUrl/*.do,asthevalueofvalueattribute.Thefollowingexamplelistingshowsa@RequestMappingannotationthatspecifies/myUrl/**asthepathpattern:

Examplelisting10-9–SomeControllerclass–Ant-stylerequestpathpatternusage@Controller@RequestMapping("/myUrl/**")publicclassSomeController{.....}Intheaboveexamplelisting,@RequestMapping("/myUrl/**")annotationatthetype-levelspecifiesthattheSomeControllercontrollerhandlesallrequeststhatbeginwith/myUrlpath.Forinstance,requeststo/myUrl/abc,/myUrl/xyzand/myUrl/123/somethingpathsarehandledbySomeControllercontroller.

MappingrequestsbasedonHTTPmethods

@RequestMapping’smethod attribute specifies the HTTPmethod that is handled by the controller orcontroller method. So, if the method attribute specifies an HTTP GET method, the controller or thecontrollermethodhandlesonlyHTTPGETrequests.

The following example listing shows the FixedDepositController’s listFixedDeposits method that isresponsibleforrenderingthelistoffixeddepositsinthesystem:

Examplelisting10-10–@RequestMapping’smethodattributeusageProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importorg.springframework.web.bind.annotation.RequestMethod;.....@Controller@RequestMapping(value="/fixedDeposit")publicclassFixedDepositController{.....@RequestMapping(value="/list",method=RequestMethod.GET)

Page 357: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicModelAndViewlistFixedDeposits(){.....}.....}In the above example listing,@RequestMapping annotation on the listFixedDepositsmethod specifiesvalue ofmethod attribute as RequestMethod.GET. TheRequestMethod is an enum that defines HTTPrequestmethods, likeGET,POST,PUT,DELETE, and so on.As the value of themethod attribute isRequestMethod.GET, the listFixedDepositsmethod is invokedonly if anHTTPGETrequest is sent to/fixedDeposit/list path. For instance, if you send an HTTP POST request to /fixedDeposit/list path,applicationwillreturnanHTTP405(whichmeans,theHTTPmethodisnotsupported)statuscode.

You can also specify an array of HTTP methods as the value of method attribute, as shown in thefollowingexamplelisting:

Examplelisting10-11–SpecifyingmultipleHTTPmethodsasthevalueofmethodattribute@Controller@RequestMapping(value="/sample")publicclassMyController{@RequestMapping(value="/action"method={RequestMethod.GET,RequestMethod.POST})publicModelAndViewaction(){.....}}In theaboveexample listing, theactionmethod is annotatedwith@RequestMapping annotationwhosemethodattribute’svalue is{RequestMethod.GET,RequestMethod.POST}.Thismeans that the actionmethodisinvokedifanHTTPGETorPOSTrequestissentto/sample/actionpath.

Mappingrequestsbasedonrequestparameters

@RequestMapping’sparamsattributetypicallyspecifiesthenameandvalueoftherequestparameterthatmust be present in the request. The following example listing shows the FixedDepositController’sshowOpenFixedDepositForm method that is responsible for showing the form for creating a fixeddeposit:

Examplelisting10-12–@RequestMapping’sparamsattributeusageProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importorg.springframework.web.bind.annotation.RequestMethod;.....@Controller@RequestMapping(value="/fixedDeposit")publicclassFixedDepositController{.....@RequestMapping(params="fdAction=createFDForm",method=RequestMethod.POST)publicModelAndViewshowOpenFixedDepositForm(){.....}

Page 358: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....}Intheaboveexamplelisting,@RequestMappingannotationontheshowOpenFixedDepositFormmethodspecifies the value of params attribute as fdAction=createFDForm. As the FixedDepositController ismapped to /fixedDeposit path, the showOpenFixedDepositFormmethod is invoked if anHTTP POSTrequestcontainingrequestparameternamedfdActionwithvaluecreateFDFormissent to /fixedDepositpath.

Ifyouwanttomaprequeststoacontrollerorcontrollermethodbasedonthevaluesofmultiplerequestparameters, you can specify an array of request parameter name-value pairs as the value of paramsattribute,asshowninthefollowingexamplelisting:

Examplelisting10-13–Specifyingmultiplerequestparametername-valuepairsasthevalueofparamsattribute@RequestMapping(params={"x=a","y=b"})publicvoidperform(){.....}Intheaboveexamplelisting,theperformmethodisinvokedonlyiftherequestcontainsparametersnamedxandywithvaluesaandb,respectively.

You can also map requests to a controller or controller method based on the existence of a requestparameterintherequest.Allyouneedtodoistosimplyspecifythenameoftherequestparameterasthevalueof params attribute. For instance, the performmethod shownhere is invoked irrespective of thevalueofrequestparameterx:

Examplelisting10-14–performmethodisinvokedifrequestparameterxisfound

@RequestMapping(params="x")publicvoidperform(){.....}Tomap requests to a controller or controllermethod if a request parameter does not exist, use the !operator. For example, the following performmethod is invoked if request parameter named x is notfoundintherequest:

Examplelisting10-15–performmethodisinvokedifrequestparameterxisnotfound

@RequestMapping(params="!x")publicvoidperform(){.....}Youcanuse !=operator tomap requests to a controller or controllermethod if thevalueof a requestparameterisnotequaltothespecifiedvalue,asshownhere:

Examplelisting10-16–performmethodisinvokedifthevalueofrequestparameterxisnotequaltoa

@RequestMapping(params="x!=a")publicvoidperform(){.....}Intheaboveexamplelisting,performmethodisinvokedonlyiftherequestcontainsarequestparameternamedx,andthevalueofxisnotequaltoa.

Page 359: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

MappingrequestsbasedontheMIMEtypeoftherequest

TheContent-TyperequestheaderspecifiestheMIMEtypeoftherequest.@RequestMapping’sconsumesattributespecifiestheMIMEtypeoftherequestthatacontrolleroracontrollermethodhandles.So,ifthevalueofconsumesattributematchesthevalueoftheContent-Typerequestheader,therequestismappedtothatparticularcontrollerorcontrollermethod.

The following example listing shows that the performmethod is invoked if the Content-Type requestheader’svalueisapplication/json:

Example listing 10-17 – perform method is invoked if the value of Content-Type header isapplication/json

@RequestMapping(consumes="application/json")publicvoidperform(){.....}Aswiththeparamsattribute,youcanuse!operatortospecifytheconditionthataContent-Typeheadervalueisnotpresent.Forinstance,thefollowingperformmethodisinvokediftheContent-Typeheader’svalueisnotapplication/json:

Example listing 10-18 – perform method is invoked if the value of Content-Type header is notapplication/json

@RequestMapping(consumes="!application/json")publicvoidperform(){.....}Youcanspecifyanarrayofvaluesintheconsumesattribute,inwhichcasetherequestismappedtothecontrollerorthecontrollermethodiftheContent-Typevaluematchesoneofthevaluesspecifiedbytheconsumesattribute.Inthefollowingexamplelisting,theperformmethodisinvokediftheContent-Typeisapplication/jsonortext/plain:

Examplelisting10-19–performmethodisinvokedifContent-Typeisapplication/jsonortext/plain

@RequestMapping(consumes={"application/json","text/plain")publicvoidperform(){.....}

MappingrequestsbasedontheacceptableMIMEtypeoftheresponse

TheAccept request header specifies the acceptableMIME type of the response.@RequestMapping’sproduces attribute specifies the acceptableMIME type of the response. So, if the value of producesattributevaluematchestheAcceptrequestheader, therequest ismappedtothatparticularcontrollerorcontrollermethod.

ThefollowingexamplelistingshowsthattheperformmethodisinvokediftheAccept requestheader’svalueisapplication/json:

Examplelisting10-20–performmethodisinvokedifthevalueofAcceptheaderisapplication/json

@RequestMapping(produces="application/json")publicvoidperform(){.....}Aswith the consumes attribute, you can use ! operator to specify the condition that anAccept header

Page 360: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

valueisnotpresentintherequest.Ifyouspecifyanarrayofvaluesfortheproducesattribute,requestismappedtothecontrollerorthecontrollermethodif theAcceptheadervaluematchesoneof thevaluesspecifiedbytheproducesattribute.

Mappingrequestsbasedonarequestheadervalue

To map requests based on request headers, you can use @RequestMapping’s headers attribute. ThefollowingexamplelistingshowsthattherequestismappedtotheperformmethodifthevalueofContent-Typeheaderistext/plain:

Examplelisting10-21–performmethodisinvokedifthevalueofContent-Typeheaderistext/plain

@RequestMapping(headers="Content-Type=text/plain")publicvoidperform(){.....}Aswiththeparamsattribute,youcanuse!and!=operatorswhilespecifyingvalueofheadersattribute.Forinstance,thefollowingexamplelistingshowsthattherequestismappedtotheperformmethodifthevalueofContent-Typeheaderisnotequaltoapplication/json,theCache-Controlheaderdoesn’texistintherequest,andtheFromheaderexistsintherequestwithanyvalue:

Examplelisting10-22–Using!and!=operatorsforspecifyingvalueofheadersattribute

@RequestMapping(headers={"Content-Type!=application/json","!Cache-Control","From"})publicvoidperform(){.....}Now,thatwehavelookedat theattributesof@RequestMappingannotation, let’s lookat theargumentsthatyoucanpassto@RequestMappingannotatedmethods.

@RequestMappingannotatedmethodsarguments@RequestMappingannotatedmethodscanhaveflexiblemethodsignatures.Theargument typesthatcanbe 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,andsoon.Toviewacompletelistofargumentsthatcanbepassedto@RequestMappingannotatedmethod,pleaserefer to@RequestMappingJavadoc.

As we discuss different SpringWebMVC features in this book, we’ll come across scenarios whichrequireustopassdifferentargumenttypesto@RequestMappingannotatedmethods.Fornow,we’lllookatascenarioinwhichweneedtosendHttpServletRequestobjectasanargument.

ThefollowingexamplelistingshowstheFixedDepositController’sviewFixedDepositDetailsmethodthatacceptsanargumentoftypeHttpServletRequest:

Examplelisting10-23–FixedDepositControllerclass-passingHttpServletRequestargumentProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importjavax.servlet.http.HttpServletRequest;

Page 361: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=view",method=RequestMethod.GET)publicModelAndViewviewFixedDepositDetails(HttpServletRequestrequest){FixedDepositDetailsfixedDepositDetails=fixedDepositService.getFixedDeposit(Integer.parseInt(request.getParameter("fixedDepositId")));.....}.....}TheviewFixedDepositDetailsmethod is invokedwhenyouclick theEdithyperlinkcorresponding toafixeddeposit(referfigure10-8).HttpServletRequestisusedbytheviewFixedDepositDetailsmethodtoobtainthefixedDepositIdrequestparameterthatuniquelyidentifiesafixeddepositinthesystem.

Let’snowlookatthereturntypesthataresupportedfor@RequestMappingannotatedmethods.

@RequestMappingannotatedmethodsreturntypesThe supported return types for @RequestMapping annotated methods include ModelAndView,org.springframework.web.servlet.View,String,java.util.concurrent.Callable,void,andsoon.Toviewacomplete list of return types supported for @RequestMapping annotated methods, please refer to@RequestMappingJavadoc.

As we discuss different SpringWebMVC features in this book, we’ll come across scenarios whichrequire@RequestMappingannotatedmethods tohavedifferent return types. In this section,we’ll onlylookatexamplesthatshowmethodsthathaveStringorModelAndViewasreturntypes.

ThefollowingexamplelistingshowsFixedDepositController’sshowOpenFixedDepositFormmethodthatrenderstheHTMLformforopeninganewfixeddeposit(referfigure10-9):

Examplelisting10-24–FixedDepositControllerclass-ModelAndViewreturntypeexampleProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importorg.springframework.ui.ModelMap;.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=createFDForm",method=RequestMethod.POST)publicModelAndViewshowOpenFixedDepositForm(){FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();fixedDepositDetails.setEmail("Youmustenteravalidemail");ModelMapmodelData=newModelMap();modelData.addAttribute(fixedDepositDetails);returnnewModelAndView("createFixedDepositForm",modelData);

Page 362: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

}.....}TheshowOpenFixedDepositFormmethod returns aModelAndView object that contains an instance ofFixedDepositDetailsasamodelattributeandcreateFixedDepositFormstringvalueastheviewname.

If you compare the above example listing with 10-1 and 10-6, you’ll notice that theshowOpenFixedDepositFormmethodusesSpring’sModelMap object instead of java.util.Map to storemodel attributes.ModelMap is an implementation of java.util.Map interface that allows you to storemodelattributeswithoutexplicitlyspecifyingtheirnames.ModelMapautomaticallygeneratesthenameofthemodelattributebasedonapre-definedstrategy.For instance, ifyouaddacustomJavaobjectasamodelattribute,thename(beginningwithlowercasefirstletter)oftheobject’sclassisusedasthenameofthemodelattribute.Intheaboveexamplelisting,whenaninstanceofFixedDepositDetailsisaddedtotheModelMap,itisstoredintheModelMapwiththenamefixedDepositDetails.

Whena@RequestMappingannotatedmethodreturnsastringvalue, it isconsideredas thenameof theviewthatisresolvedtoanactualview(like,JSPpageorservlet)bytheViewResolverconfiguredfortheweb application. The following example listing shows the configuration ofInternalResourceViewResolverinch10-bankappproject:

Examplelisting10-25–bankapp-config.xml–ViewResolverconfigurationProject–ch10-bankappSourcelocation-src/main/webapp/WEB-INF/spring

<beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="/WEB-INF/jsp/"/><propertyname="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-3tolearnmoreabouttheInternalResourceViewResolverconfigurationshownabove.

If the string value returned by the@RequestMapping annotated method has the prefix redirect:, it istreated as a redirect URL and not as a view name. The following example listing showsFixedDepositController’scloseFixedDepositmethodthatisresponsibleforclosingafixeddepositwhenauserclickstheClosebutton(referfigure10-9):

Examplelisting10-26–FixedDepositControllerclass-StringreturntypeexampleProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

@RequestMapping(params="fdAction=close",method=RequestMethod.GET)publicStringcloseFixedDeposit(.....intfdId){fixedDepositService.closeFixedDeposit(fdId);return"redirect:/fixedDeposit/list";}

Page 363: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

FixedDepositController’s closeFixedDeposit method closes the fixed deposit identified by the fdIdargumentandreturnsredirect:/fixedDeposit/liststringvalue.Asthereturnedstringvalueisprefixedwithredirect:,theuserisredirectedtothe/fixedDeposit/listURLthatshowsthelistoffixeddeposits(referfigure10-8).

Let’snowlookatthe@RequestParamannotationthatallowsyoutoassignarequestparametervaluetoacontrollermethodargument.

Passingrequestparameterstocontrollermethodsusing@RequestParamWesawinexamplelisting10-23thatwecanpassHttpServletRequestobjecttoacontrollermethodanduseittoretrieverequestparameters.InsteadofpassingHttpServletRequestobjecttoacontrollermethod,you can annotate a method argument with @RequestParam annotation to assign value of a requestparametertothemethodargument.

NOTEYoushouldnotethatthe@RequestParamannotationcanonlybeusedifthemethodisannotatedwith@RequestMappingor@ModelAttribute(explainedinchapter11)annotation.

ThefollowingexamplelistingshowsFixedDepositController’scloseFixedDepositmethodthatisinvokedwhenauserclickstheClosebutton(referfigure10-8)tocloseafixeddeposit:

Examplelisting10-27–FixedDepositControllerclass-@RequestParamusageProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importorg.springframework.web.bind.annotation.RequestParam;.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=close",method=RequestMethod.GET)publicStringcloseFixedDeposit(@RequestParam(value="fixedDepositId")intfdId){fixedDepositService.closeFixedDeposit(fdId);return"redirect:/fixedDeposit/list";}.....}@RequestParam’svalueattributespecifiesthenameoftherequestparameterwhosevalueisassignedtothemethodargument.Intheaboveexamplelisting,@RequestParamannotationisusedtoassignthevalueof fixedDepositId request parameter to fdIdmethod argument.As the type of the fdId argument is int,SpringisresponsibleforconvertingthefixedDepositIdrequestparametertointtype.Bydefault,SpringautomaticallyprovidestypeconversionforsimpleJavatypes,likeint,long,java.util.Date,andsoon.Toconvert request parameters to custom Java types (like Address), you need to register customPropertyEditorswithSpring’sWebDataBinder instance or org.springframework.format.FormatterswithSpring’sFormattingConversionService instance.We’ll learnmoreaboutWebDataBinder in chapter 11,andFormatterandFormattingConversionServiceinchapter13.

Page 364: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Let’snowlookathowyoucanaccessalltherequestparametersinacontrollermethod.

Passingalltherequestparameterstoacontrollermethod

Topassalltherequestparameterstoacontrollermethod,defineanargumentoftypeMap<String,String>orMultiValueMap<String,String>(anobjectprovidedbySpringthatimplementsjava.util.Mapinterface)andannotateitwith@RequestParamannotation.

ThefollowingexamplelistingshowsFixedDepositController’sopenFixedDepositmethodthatcreatesafixed deposit when a user enters fixed deposit details and clicks the Save button on the ‘Open fixeddeposit’formforopeningfixeddeposits(referfigure10-9):

Examplelisting10-28–FixedDepositControllerclass–accessingallrequestparametersProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importjava.util.Map;.....@RequestMapping(value="/fixedDeposit")publicclassFixedDepositController{.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicModelAndViewopenFixedDeposit(@RequestParamMap<String,String>params){StringdepositAmount=params.get("depositAmount");Stringtenure=params.get("tenure");.....}}In the above example listing, params argument of type Map<String, String> is annotated [email protected]@RequestParamannotationisnotspecified.If@RequestParam’svalueattributeisnotspecifiedandthetypeofthemethodargumentisMap<String,String> orMultiValueMap<String, String>, Spring copies all the requests parameters into the methodargument.Eachrequestparameter’svalueisstoredintheMap(orMultiValueMap)withthenameoftherequestparameterasthekey.

The following example listing shows FixedDepositController’s editFixedDeposit method that isresponsibleformakingchangestoanexistingfixeddeposit:

Examplelisting10-29–FixedDepositControllerclass–accessingallrequestparametersProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importorg.springframework.util.MultiValueMap;.....

Page 365: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicclassFixedDepositController{.....@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)publicModelAndVieweditFixedDeposit(@RequestParamMultiValueMap<String,String>params){StringdepositAmount=params.get("depositAmount").get(0);Stringtenure=params.get("tenure").get(0);.....}}In the above example listing, editFixedDeposit’s params argument is of type MultiValueMap<String,String>,andisannotatedwith@RequestParamannotation.IfanobjectisoftypeMultiValueMap<K,V>,thenitmeansthatKisthetypeofthekeyandList<V>isthetypeofthevalue.Astheparamsargumentisof typeMultiValueMap<String,String>, itmeans that thekey is of typeString and thevalue is of typeList<String>. When storing request parameters in MultiValueMap<String, String> type, Spring usesrequest parameter’s name as key and the value of the request parameter is added to the List<String>value.MultiValueMapisparticularlyusefulifyouhavemultiplerequestparameterswiththesamename.

AsthevaluecorrespondingtoarequestparameterisoftypeList<String>,callingparams.get(Stringkey)returnsaList<String>type.Forthisreason,get(0)iscalledonthereturnedList<String>togetthevalueof requestparametersdepositAmount, tenure,andsoon.Alternatively,youcanusegetFirst(String key)methodofMultiValueMaptoobtainthefirstelementfromtheList<String>value.

Let’snowtakeacloserlookatthevariousattributesof@RequestParamannotation.

Specifyingrequestparameternameusingvalueattribute

Wesawearlierthat@RequestParam’svalueattributespecifiesthenameoftherequestparameterwhosevalueisassignedtothemethodargument.Ifyoudon’tspecifythenameofarequestparameter,methodargumentnameisconsideredas thenameof therequestparametername.For instance, in thefollowingexamplelisting,valueofrequestparameternamedparamisassignedtotheparamargument:

Examplelisting10-30–@RequestParamusage-unspecifiedrequestparametername@RequestMapping(.....)publicStringdoSomething(@RequestParamStringparam){.....}Intheaboveexamplelisting,@RequestParamdoesn’tspecifythenameoftherequestparameterwhosevalue is assigned to the param argument; therefore, param is considered as the name of the requestparameter.

Specifyingrequestparameterisoptionalormandatorybyusingrequiredattribute

Bydefault,requestparameterspecifiedbythe@RequestParamannotationismandatory;ifthespecifiedrequest parameter is not found in the request, an exception is thrown.You can specify that the requestparameterisoptionalbysettingthevalueofrequiredattributetofalse,asshownhere:

Examplelisting10-31–@RequestParam’srequiredattribute

Page 366: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@RequestMapping(.....)publicStringperform(@RequestParam(value="myparam",required=false)Stringparam){.....}

Intheaboveexamplelisting,@RequestParam’srequiredattributevalueissettofalse,whichmeansthatthemyparamrequestparameter isoptional.Now, if themyparam requestparameter isnot found in therequest,it’llnotresultinanexception.Instead,anullvalueisassignedtotheparammethodargument.

SpecifyingdefaultvalueforarequestparameterusingdefaultValueattribute

@RequestParam’sdefaultValueattributespecifiesthedefaultvalueforarequestparameter.Iftherequestparameterspecifiedby@RequestParam’svalueattributeisnotfoundintherequest,thevaluespecifiedby thedefaultValue attribute is assigned to themethod argument.The following example listing showsusageofdefaultValueattribute:

Examplelisting10-32–@RequestParam’sdefaultValueattribute@RequestMapping(.....)publicStringperform(@RequestParam(value="location",defaultValue="earth")Stringparam){.....}In theaboveexample listing, if requestparameternamed location isnot found in therequest, thevalueearthisassignedtotheparammethodargument.

In this section, we looked at @RequestMapping and @RequestParam annotations to create theFixedDepositController of MyBank application. Let’s now look at how validation of form data isperformedintheFixedDepositControllerclass.

Page 367: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-8ValidationWesawearlierthatFixedDepositController’sshowOpenFixedDepositFormmethod(referexamplelisting10-24) renders createFixedDepositForm.jsp JSP page that shows the form for opening a new fixeddeposit. When the form is submitted, the data entered in the form is validated byFixedDepositController’sopenFixedDepositmethod(referexamplelisting10-28).Iferrorsarereportedduring validation, the createFixedDepositForm.jsp JSP page is rendered again with validation errormessagesandtheoriginalformdatathatwasenteredbytheuser(referfigure10-9).

Thefollowingexamplelistingshowsthe<form>elementofcreateFixedDepositForm.jspJSPpage:

Examplelisting10-33–createFixedDepositForm.jsp–<form>elementProject–ch10-bankappSourcelocation-src/main/webapp/WEB-INF/jsp

<formname="createFixedDepositForm"method="POST"action="${pageContext.request.contextPath}/fixedDeposit?fdAction=create">.....<inputtype="submit"value="Save"/></form>Intheaboveexamplelisting,<form>element’smethodattributespecifiesPOSTastheHTTPmethod,andactionattributespecifies/fixedDeposit?fdAction=createastheURLtowhichtheformissubmittedwhenthe user clicks the Save button. Submission of the form results in the invocation ofFixedDepositController’sopenFixedDepositmethod.

ThefollowingexamplelistingshowshowthevalidationisperformedbytheopenFixedDepositmethod,andhowtheoriginalformdataenteredbytheuserisshownagainincaseofvalidationerrors:

Examplelisting10-34–FixedDepositController’sopenFixedDepositmethodProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;.....importorg.apache.commons.lang3.math.NumberUtils;@RequestMapping(value="/fixedDeposit")publicclassFixedDepositController{.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicModelAndViewopenFixedDeposit(@RequestParamMap<String,String>params){StringdepositAmount=params.get("depositAmount");.....Map<String,Object>modelData=newHashMap<String,Object>();if(!NumberUtils.isNumber(depositAmount)){modelData.put("error.depositAmount","enteravalidnumber");}elseif(NumberUtils.toInt(depositAmount)<1000){

Page 368: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

modelData.put("error.depositAmount","mustbegreaterthanorequalto1000");}.....FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();fixedDepositDetails.setDepositAmount(depositAmount);.....if(modelData.size()>0){//--thismeanstherearevalidationerrorsmodelData.put("fixedDepositDetails",fixedDepositDetails);returnnewModelAndView("createFixedDepositForm",modelData);}else{fixedDepositService.saveFixedDeposit(fixedDepositDetails);returnnewModelAndView("redirect:/fixedDeposit/list");}}.....}TheopenFixedDepositmethodvalidatesdepositamount,tenureandemailinformationenteredbytheuser.Notice that to simplify validation of data, NumberUtils class of Apache Commons Lang(http://commons.apache.org/proper/commons-lang/) libraryhasbeenused.ThemodelDatavariable isajava.util.MapobjectthatstoresmodelattributesthatwewanttopasstothecreateFixedDepositForm.jspJSPpageincaseofvalidationerrors.

As we want to show validation error messages and the original form data if validation fails, thevalidationerrormessagesandtheoriginalformdataarestoredinmodelData.Forinstance,ifthedepositamount entered by the user fails validation, an appropriate validation error message is stored in themodelDatawithnameerror.depositAmount.ThevaluesenteredbytheuseraresetonanewinstanceofFixedDepositDetails object. If validation errors are reported, the newly created FixedDepositDetailsinstanceisaddedtothemodelDatawithnamefixedDepositDetails,andthecreateFixedDepositForm.jspJSP page is rendered. Alternatively, if no validation errors are reported, the newly createdFixedDepositDetailsobjectissavedinthedatasource,andthepagethatshowsthecompletelistoffixeddepositsisrendered.

AsweareusingFixedDepositDetailsobject to store theoriginal formdataenteredby theuser,all theattributesofFixedDepositDetailshavebeendefinedoftypeString,asshownhere:

Examplelisting10-35–FixedDepositDetailsclassProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/domain

packagesample.spring.chapter10.domain;publicclassFixedDepositDetails{privatelongid;//--idvalueissetbythesystemprivateStringdepositAmount;privateStringtenure;privateStringemail;

Page 369: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

//--gettersandsettersforfields.....}AsdepositAmountandtenurefieldsaredefinedoftypeString,wehadtowriteextralogictoconvertthemintonumericvaluesforperformingnumericalcomparisons.Inchapter11,we’lllookathowSpringWebMVCsimplifiesbindingformdatatoformbackingobjects(likeFixedDepositDetails)andre-displayingtheoriginalformdataincaseofvalidationerrors.

The following fragments from the createFixedDepositForm.jsp JSP page demonstrate how validationerrormessagesandtheoriginalformdataaredisplayedintheMyBankapplication:

Examplelisting10-36–createFixedDepositForm.jspProject–ch10-bankappSourcelocation-src/main/webapp/WEB-INF/jsp

<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%><formname="createFixedDepositForm"method="POST"action="${pageContext.request.contextPath}/fixedDeposit?fdAction=create">.....<tdclass="td"><b>Amount(inUSD):</b></td><tdclass="td"><inputtype="text"name="depositAmount"value="${requestScope.fixedDepositDetails.depositAmount}"/><fontstyle="color:#C11B17;"><c:outvalue="${requestScope['error.depositAmount']}"/></font></td>.....<inputtype="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 examplelisting10-34),weaddedaFixedDepositDetailsinstanceasamodelattributenamedfixedDepositDetails;therefore, the${requestScope.fixedDepositDetails.depositAmount}expressionshows theoriginalvaluethattheuserenteredforthedepositAmountfield.

The expression ${requestScope['error.depositAmount']} refers to the error.depositAmount requestattribute. In the openFixedDeposit method (refer example listing 10-34), we saw that theerror.depositAmountcontainsvalidationerrormessagecorrespondingtothefixeddepositamountenteredbytheuser;therefore,the<c:outvalue="${requestScope['error.depositAmount']}"/>elementshowsthevalidationerrormessagecorrespondingtothefixeddepositamountenteredbytheuser.

Let’snowlookathowtohandleexceptionsinSpringWebMVCapplications.

Page 370: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-9Handlingexceptionsusing@ExceptionHandlerannotation@ExceptionHandlerannotationisusedinanannotatedcontroller toidentifythemethodresponsibleforhandling exceptions thrown by the controller. Spring’s HandlerExceptionResolver is responsible formapping an exception to an appropriate controllermethod responsible for handling the exception.Youshould note that the <annotation-driven> element of Spring’s mvc schema configures an instance ofExceptionHandlerExceptionResolver (a HandlerExceptionResolver implementation) that maps anexceptiontoanappropriate@ExceptionHandlerannotatedmethod.

Thefollowingexamplelistingshowsusageof@ExceptionHandlerannotationinch10-bankappproject:

Examplelisting10-37–@ExceptionHandlerannotationusageProject–ch10-bankappSourcelocation-src/main/java/sample/spring/chapter10/web

packagesample.spring.chapter10.web;importorg.springframework.web.bind.annotation.ExceptionHandler;.....@Controller@RequestMapping(value="/fixedDeposit")publicclassFixedDepositController{.....@ExceptionHandlerpublicStringhandleException(Exceptionex){return"error";}}

TheaboveexamplelistingshowsthattheFixedDepositController’shandleExceptionmethodisannotatedwith@ExceptionHandlerannotation.Thismeans that thehandleExceptionmethod is invokedbySpringWeb MVC to handle exceptions thrown during execution of FixedDepositController controller.@ExceptionHandler methods typically render an error page containing error details. An@ExceptionHandler annotation’s value attribute specifies the list of exceptions that the@ExceptionHandlerannotatedmethodhandles.Ifthevalueattributeisnotspecified,theexceptiontypesspecified asmethodarguments arehandledby the@ExceptionHandler annotatedmethod. In the aboveexamplelisting,thehandleExceptionmethodhandlesexceptionsoftypejava.lang.Exception.

Like@RequestMappingmethods,@ExceptionHandlermethodscanhaveflexiblemethodsignatures.Thereturn types supported for @ExceptionHandler methods include ModelAndView, View, String, void,Model, and so on. The argument types supported for @ExceptionHandler methods includeHttpServletRequest,HttpServletResponse,HttpSession,andsoon.Referto@ExceptionHandlerJavadocforthecompletelistofsupportedargumentsandreturntypes.

The view information returned by an @ExceptionHandler annotated method is used by theDispatcherServlettorenderanappropriateerrorpage.Forinstance,inexamplelisting10-37,theerrorstringvaluereturnedbythehandleExceptionmethod isusedby theDispatcherServlet to render /WEB-

Page 371: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

INF/jsp/error.jsppage.Ifthe@ExceptionHandlermethoddoesn’treturnanyviewinformation(thatis,thereturn type is void or Model), Spring’s RequestToViewNameTranslator class (refer section 11-2 ofchapter11fordetails)isusedtodeterminetheviewtoberendered.

You can define multiple @ExceptionHandler annotated methods in your controller class for handlingdifferentexceptiontypes.Thevalueattributeof@ExceptionHandlerannotationallowsyoutospecifytheexception types that are handled by the method. The following example listing shows that themyExceptionHandlermethod handles exceptions of type IOException and FileNotFoundException, andmyOtherExceptionHandlermethodhandlesexceptionsoftypeTimeoutException:

Examplelisting10-38–Specifyingthetypeofexceptionshandledbyan@[email protected]{.....@ExceptionHandler(value={IOException.class,FileNotFoundException.class})publicStringmyExceptionHandler(){return"someError";}@ExceptionHandler(value=TimeoutException.class)publicStringmyOtherExceptionHandler(){return"otherError";}}

IfMyControllerthrowsanexceptionoftypeIOExceptionorFileNotFoundException(oranexceptionthatisasubtypeofIOExceptionorFileNotFoundException), themyExceptionHandlermethod is invoked tohandletheexception.IfMyControllerthrowsanexceptionoftypeTimeoutException(oranexceptionthatis a subtype of TimeoutException), the myOtherExceptionHandler method is invoked to handle theexception.

Let’snowlookathowSpring’sContextLoaderListenerisusedtoloadrootwebapplicationcontextXMLfile(s).

Page 372: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-11LoadingrootwebapplicationcontextXMLfile(s)Asmentionedatthebeginningofthischapter,therootwebapplicationcontextfiledefinesbeansthatareshared by all the servlets and filters of theweb application.The following example listing shows theconfigurationofContextLoaderListener:

Examplelisting10-39–ContextLoaderListenerconfigurationProject–ch10-bankappSourcelocation-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 (aServletContextListener) 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 aninstanceoftherootWebApplicationContextwithwhichthebeansloadedfromtherootwebapplicationcontextXMLfile(s)areregistered.

In the above example listing, contextConfigLocation parameter specifies /META-INF/spring/applicationContext.xml file as the rootweb application contextXML file.You can specifymultipleapplicationcontextXMLfilesseparatedbycommaornewlineorwhitespaceorsemicolon. Ifyou don’t specify the contextConfigLocation parameter, the ContextLoaderListener treats /WEB-INF/applicationContext.xmlfileastherootwebapplicationcontextXMLfile.

Page 373: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

10-12SummaryInthischapter,welookedatsomeoftheimportantobjectsofasimpleSpringWebMVCapplication.Wealso looked at how to use@Controller,@RequestMapping,@RequestParam and@ExceptionHandlerannotations to create annotated controllers. In the next chapter,we’ll look at howSpring transparentlybindsrequestparameterstoformbackingobjectsandperformsvalidation.

Page 374: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter11–ValidationanddatabindinginSpringWebMVC

Page 375: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

11-1IntroductionIn 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 wasretrievedfromtherequest(referexamplelisting10-23,10-28and10-29)andexplicitlysetontheformbacking object (whichwas FixedDepositDetails object).Also, the validation logicwaswritten in thecontrollermethoditself(referexamplelisting10-34).

Inthischapter,we’lldiscuss:

·@ModelAttributeand@SessionAttributesannotationsthatareusefulwhendealingwithmodelattributes

·howSpring’sWebDataBindersimplifiesbindingformdatatoformbackingobjects

· validating form backing objects using Spring Validation API and JSR 303’s constraintannotations

·Spring’sformtaglibrarythatsimplifieswritingJSPpages

Let’sfirstlookatthe@ModelAttributeannotationthatisusedforaddingandretrievingmodelattributestoandfromSpring’sModelobject.

Page 376: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

11-2 Adding and retrieving model attributes using@ModelAttributeannotationInthepreviouschapter,wesawthata@RequestMappingmethodstoresmodelattributesinaHashMap(or ModelMap) instance and returns these model attributes via ModelAndView object. The modelattributesreturnedbya@RequestMappingmethodarestoredinSpring’sModelobject.

Amodelattributemayrepresentaformbackingobjectorareferencedata.FixedDepositDetailsobjectintheMyBankwebapplicationisanexampleofaformbackingobject;whentheformforopeninganewfixed deposit is submitted, the information contained in the form is stored in the FixedDepositDetailsobject. Typically, domain objects or entities in an application are used as form backing objects.Referencedatareferstotheadditionalinformation(otherthantheformbackingobject)requiredbytheview.Forinstance,ifyouaddausercategory(likemilitarypersonnel,seniorcitizen,andsoon)toeachfixeddeposit,theformforopeningnewfixeddepositswouldneedtoshowacomboboxdisplayingthelistofcategories.Thelistofcategorieswouldbethereferencedataneededfordisplayingtheformforopeningnewfixeddeposits.

@ModelAttribute annotation is used on methods and method arguments to store and retrieve modelattributesfromSpring’sModelobject, respectively.@ModelAttributeannotationonamethod indicatesthatthemethodaddsoneormoremodelattributestotheModelobject.And,@ModelAttributeannotationon amethod argument is used to retrieve amodel attribute from theModel object and assign it to themethodargument.

IMPORT chapter 11/ch11-bankapp (This project shows the MyBank web application that uses@ModelAttribute annotation andSpring’s form tag library. TheMyBankweb application functionalityofferedby ch11-bankapp and ch10-bankapp projects is the same. If you deploy the project onTomcatserverandaccesstheURLhttp://localhost:8080/ch11-bankapp,you’llseethelistoffixeddepositsinthesystem.)

Let’sfirstlookat@ModelAttributeannotatedmethods.

Addingmodelattributesusingmethod-level@ModelAttributeannotationThefollowingexamplelistingshowsFixedDepositController’sgetNewFixedDepositDetailsmethod thatisannotatedwith@ModelAttributeannotation:

Examplelisting11-1–@ModelAttributeannotationusageatmethodlevelProject–ch11-bankappSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;importorg.springframework.web.bind.annotation.ModelAttribute;importsample.spring.chapter11.domain.FixedDepositDetails;.....@Controller@RequestMapping(value="/fixedDeposit").....

Page 377: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicclassFixedDepositController{privatestaticLoggerlogger=Logger.getLogger(FixedDepositController.class);.....@ModelAttribute(value="newFixedDepositDetails")publicFixedDepositDetailsgetNewFixedDepositDetails(){FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();fixedDepositDetails.setEmail("Youmustenteravalidemail");logger.info("getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetails");returnfixedDepositDetails;}.....}

The getNewFixedDepositDetails method creates and returns a new instance of FixedDepositDetailsobject. As the getNewFixedDepositDetailsmethod is annotatedwith@ModelAttribute annotation, thereturnedFixedDepositDetails instanceisaddedto theModelobject.@ModelAttribute’svalueattributespecifiesthatthereturnedFixedDepositDetailsobjectisstoredwithnamenewFixedDepositDetailsintheModel object. Notice that the getNewFixedDepositDetails method logs the following message -‘getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetails’.

NOTEYoushouldnotethatthescopeofmodelattributesisrequest.Thismeansthatthemodelattributesarelostwhenarequestcompletes,orifarequestisredirected.

Later in this section, we’ll see how the createFixedDepositForm.jsp JSP page (refersrc/main/webapp/WEB-INF/jsp/createFixedDepositForm.jspfile)ofch11-bankappprojectusesSpring’sform tag library to access the FixedDepositDetails object named newFixedDepositDetails from theModelobject.

Ifyoudon’tspecify@ModelAttribute’svalueattribute,thereturnedobjectisstoredintheModelobjectusingthesimplenameofthereturnedobject’stype.Inthefollowingexamplelisting,theSampleobjectreturnedbythegetSamplemethodisstoredwithnamesampleintheModelobject:

Examplelisting11-2–@ModelAttributeusage–valueattributeisnotspecifiedimportorg.springframework.ui.Model;.....publicclassSampleController{@ModelAttributepublicSamplegetSample(){returnnewSample();}}

A@ModelAttributeannotatedmethodacceptssametypesofargumentsasa@RequestMappingmethod.Thefollowingexample listingshowsa@ModelAttributeannotatedmethod thatacceptsanargumentoftypeHttpServletRequest:

Page 378: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting11-3–@ModelAttributeannotatedmethodthatacceptsHttpServletRequestasargument@ModelAttribute(value="myObject")publicSomeObjectdoSomething(HttpServletRequestrequest){.....}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 requestparameterstoa@ModelAttributeannotatedmethod,asshowninthefollowingexamplelisting:

Examplelisting11-4–Passingrequestparameterstoa@ModelAttributeannotatedmethod@ModelAttribute(value="myObject")publicSomeObjectdoSomething(@RequestParam("someArg")Stringmyarg){.....}

As@RequestMappingand@ModelAttributeannotatedmethodscanacceptModelobjectsasargument,youcandirectlyaddmodelattributes to theModelobject ina@ModelAttributeor@RequestMappingannotatedmethod. The following example listing shows a@ModelAttributemethod that directly addsmodelattributestotheModelobject:

Examplelisting11-5–AddingmodelattributesdirectlytoModelobjectimportorg.springframework.ui.Model;.....publicclassSampleWebController{@ModelAttributepublicvoiddoSomething(Modelmodel){model.addAttribute("myobject",newMyObject());model.addAttribute("otherobject",newOtherObject());}}

Intheaboveexamplelisting,theModelobjectispassedasanargumenttothedoSomethingmethodthatdirectly addsmodel attributes to theModel object.As the doSomethingmethod addsmodel attributesdirectly to the Model object, the doSomething method’s return type is specified as void, and the@ModelAttribute’svalueattributeisnotspecified.

It is possible to have a single method annotated with both @RequestMapping and @ModelAttributeannotations. The following example listing shows FixedDepositController’s listFixedDeposits methodthatisannotatedwithboth@RequestMappingand@ModelAttributeannotations:

Examplelisting11-6–@ModelAttributeand@RequestMappingannotationsonthesamemethodProject–ch11-bankappSourcelocation-src/main/java/sample/spring/chapter11/web

Page 379: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

packagesample.spring.chapter11.web;.....@Controller@RequestMapping(value="/fixedDeposit").....publicclassFixedDepositController{privatestaticLoggerlogger=Logger.getLogger(FixedDepositController.class);@RequestMapping(value="/list",method=RequestMethod.GET)@ModelAttribute(value="fdList")publicList<FixedDepositDetails>listFixedDeposits(){logger.info("listFixedDeposits()method:Gettinglistoffixeddeposits");returnfixedDepositService.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 thesystem.Whenamethodisannotatedwithboth@RequestMappingand@ModelAttributeannotations,thevalue returned by themethod is considered as amodel attribute, and not as a view name. In such ascenario,viewnameisdeterminedbySpring’sRequestToViewNameTranslatorclassthatdeterminestheview to render based on the requestURI of the incoming request. Later in this chapter,we’ll discussRequestToViewNameTranslator in detail. In example listing 11-6, notice that the listFixedDepositsmethodlogsthefollowingmessage–‘listFixedDeposits()method:Gettinglistoffixeddeposits’.

Itisimportanttonotethatyoucandefinemultiplemethodsannotatedwith@ModelAttributeannotationinacontroller.Whenarequestisdispatchedtoa@RequestMappingannotatedmethodofacontroller,allthe@ModelAttribute annotated methods of that controller are invoked before the @RequestMappingannotated method is invoked. The following example listing shows a controller that defines@RequestMappingand@ModelAttributeannotatedmethods:

Examplelisting11-7–@RequestMappingmethodisinvokedafterallthe@ModelAttributemethodsareinvoked@RequestMapping("/mycontroller")publicclassMyController{@RequestMapping("/perform")publicStringperform(){.....}@ModelAttribute(value="a")publicAgetA(){.....}@ModelAttribute(value="b")publicBgetB(){.....}

Page 380: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

}

Intheaboveexamplelisting,ifarequestismappedtoMyController’sperformmethod,SpringWebMVCwillfirstinvokegetAandgetBmethods,followedbyinvokingtheperformmethod.

Ifamethod isannotatedwithboth@RequestMappingand@ModelAttributeannotations, themethod isinvoked only once for processing the request. The following example listing shows a controller thatdefinesamethodthatisannotatedwithboth@RequestMappingand@ModelAttributeannotations:

Examplelisting11-8–Methodannotatedwithboth@RequestMappingand@ModelAttributeannotationsisinvokedonlyonceforprocessingtherequest@RequestMapping("/mycontroller")publicclassMyController{@RequestMapping("/perform")@ModelAttributepublicStringperform(){.....}@ModelAttribute(value="a")publicAgetA(){.....}@ModelAttribute(value="b")publicBgetB(){.....}}

Intheaboveexamplelisting,ifarequestismappedtoMyController’sperformmethod,SpringWebMVCwill first invoke getA and getB methods, followed by invoking the perform method. As the performmethod is annotated with both @RequestMapping and @ModelAttribute annotations, Spring’sRequestToViewNameTranslator class is used for determining the name of the view to render after theperformmethodisexecuted.

If you now deploy the ch11-bankapp project on Tomcat and go to http://localhost:8080/ch11-bankapp/fixedDeposit/listURL,you’llseeawebpageshowingthelistoffixeddeposits.Also,you’llseethefollowingsequenceofmessagesontheconsole:INFOsample.spring.chapter11.web.FixedDepositController–getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetailsINFOsample.spring.chapter11.web.FixedDepositController–listFixedDeposits()method:Gettinglistoffixeddeposits

The above output shows that the getNewFixedDepositDetails method (which is annotated with@ModelAttributeannotation)isinvokedfirst,followedbythelistFixedDeposits(whichisannotatedwithboth@ModelAttributeand@RequestMappingannotation).

Let’s now look at howmodel attributes are retrieved from theModel object using@ModelAttributeannotationonamethodargument.

Retrievingmodelattributesusing@ModelAttributeannotation

Page 381: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

You can use @ModelAttribute annotation on arguments of a @RequestMapping annotated method toretrievemodelattributesfromtheModelobject.

The following example listing shows FixedDepositController’s openFixedDeposit method that uses@ModelAttributeannotationtoretrievenewFixedDepositDetailsobjectfromtheModelobject:

Examplelisting11-9–@ModelAttributeannotationonamethodargumentProject–ch11-bankappSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;.....@Controller@RequestMapping(value="/fixedDeposit").....publicclassFixedDepositController{.....@ModelAttribute(value="newFixedDepositDetails")publicFixedDepositDetailsgetNewFixedDepositDetails(){.....logger.info("getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetails");.....}.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit(@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,.....){.....fixedDepositService.saveFixedDeposit(fixedDepositDetails);logger.info("openFixedDeposit()method:Fixeddepositdetailssuccessfullysaved.Redirectingtoshowthelistoffixeddeposits.");.....}}.....}

Intheaboveexamplelisting,@ModelAttributeannotatedgetNewFixedDepositDetailsmethodisinvokedbefore@RequestMapping annotated openFixedDeposit method.When the getNewFixedDepositDetailsmethod is invoked, the returnedFixedDepositDetails instance is stored in theModel objectwith namenewFixedDepositDetails. Now, the openFixedDeposit method’s fixedDepositDetails argument isannotated with @ModelAttribute(value="newFixedDepositDetails"); therefore, thenewFixedDepositDetails object is obtained from the Model object and assigned to thefixedDepositDetailsargument.

Page 382: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

If you look at the FixedDepositController’s openFixedDepositmethod, you’ll notice thatwe havenotwrittenany logic toobtainvaluesof tenure,amountandemail fields fromthe requestandpopulate thenewFixedDepositDetailsinstance.ThisisbecausetheSpring’sWebDataBinderobject(explainedlaterinthis chapter) is responsible for transparently retrieving request parameters from the request andpopulating the fields (with matching names) of newFixedDepositDetails instance. For instance, if arequestparameternamedtenureisfoundintherequest,WebDataBindersetsthevalueoftenurefieldofnewFixedDepositDetailsinstancetothevalueoftenurerequestparameter.

Figure 11-1 summarizes the sequence of actions that are performed by Spring when a request isdispatchedtoFixedDepositController’sopenFixedDepositmethod.

Figure 11-1 Order in which @ModelAttribute and @RequestMapping annotated methods ofFixedDepositControllerareinvoked

In theabovefigure, theRequestMappingHandlerAdapterobjectofSpringWebMVCis responsible forinvoking @ModelAttribute and @RequestMapping annotated methods of a controller. At first, thegetNewFixedDepositDetailsmethodisinvokedandthereturnedFixedDepositDetailsinstanceisstoredinthe Model object with name newFixedDepositDetails. Next, the newFixedDepositDetails instance isretrievedfromtheModelandpassedasanargumenttotheopenFixedDepositmethod.

Let’snowlookatwhattimesduringtheprocessingofarequesta@ModelAttributeannotatedmethodisinvoked.

Requestprocessingand@ModelAttributeannotatedmethodsIn example listing 11-6, we saw that the execution of listFixedDeposits method logs the followingmessage:

listFixedDeposits()method:Gettinglistoffixeddeposits

In example listing 11-9, we saw that the execution of getNewFixedDepositDetails method logs the

Page 383: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

followingmessage:

getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetails

And,theopenFixedDepositmethodlogsthefollowingmessage:

openFixedDeposit()method: Fixed deposit details successfully saved. Redirecting to show the list offixeddeposits

To see the order in which the listFixedDeposits, getNewFixedDepositDetails and openFixedDepositmethodsareinvoked,deploythech11-bankappprojectandfollowthesesteps:

1. Go to http://localhost:8080/ch11-bankapp/fixedDeposit/list URL. You’ll see the list of fixeddepositsinthesystemandthe‘CreatenewFixedDeposit’button(referfigure10-8ofchapter10).

2.Clickthe‘CreatenewFixedDeposit’buttonthatshowstheHTMLformforopeninganewfixeddeposit(referfigure10-9ofchapter10).

3. Enter fixeddepositdetailsandclick the‘Save’button. Ifnovalidationerrorsare found in theentereddata, the fixeddepositdetailsare successfully savedand the listof fixeddeposits in thesystem(whichincludesthenewlycreatedfixeddeposit)isdisplayedonceagain.

The following table describes the actions performed by you and the correspondingmessages that areprintedbytheMyBankapplicationontheconsole:

Action Messagesprintedontheconsole

Gotohttp://localhost:8080/ch11-bankapp/fixedDeposit/listURL

getNewFixedDepositDetails() method: Returning a new instance ofFixedDepositDetails

listFixedDeposits()method:Gettinglistoffixeddeposits

Clickthe‘CreatenewFixedDeposit’button

getNewFixedDepositDetails() method: Returning a new instance ofFixedDepositDetails

showOpenFixedDepositForm()method:Showingformforopeninganewfixeddeposit

Enter fixed deposit details and clickthe‘Save’button

getNewFixedDepositDetails() method: Returning a new instance ofFixedDepositDetails

openFixedDeposit() method: Fixed deposit details successfully saved.Redirectingtoshowthelistoffixeddeposits.

getNewFixedDepositDetails() method: Returning a new instance ofFixedDepositDetails

listFixedDeposits()method:Gettinglistoffixeddeposits

Theabovetableshowsthatthe@ModelAttributeannotatedgetNewFixedDepositDetailsmethodiscalledbeforeeachinvocationof@RequestMappingannotatedmethodoftheFixedDepositControllerclass.Asthe getNewFixedDepositDetails method creates a new instance of FixedDepositDetails object, a newinstance of FixedDepositDetails object is created each time a request is handled by theFixedDepositController.

Ifa@ModelAttributeannotatedmethodfiresSQLqueriesorinvokesanexternalwebservicetopopulatethemodelattribute returnedby themethod,multiple invocationsof@ModelAttribute annotatedmethodwilladverselyaffecttheperformanceoftheapplication.Laterinthischapter,we’llseethatyoucanuse@SessionAttributes annotation to avoidmultiple invocations of a@ModelAttribute annotatedmethod.@SessionAttributes annotation instructs Spring to cache the object returned by the @ModelAttribute

Page 384: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

annotatedmethod.

Let’s now look at a scenario inwhich themodel attribute referred by the@ModelAttribute annotatedmethodargumentisnotfoundintheModelobject.

Behaviorof@ModelAttributeannotatedmethodargumentsWe saw earlier that the@ModelAttribute annotation can be used on amethod argument to retrieve amodelattributefromtheModelobject.Ifthemodelattributespecifiedbythe@ModelAttributeannotationis not found in theModel, Spring automatically creates a new instance of themethod argument type,assigns it to themethodargumentandalsoputs it into theModelobject.To allowSpring to create aninstance of themethod argument type, the Java class of themethod argument typemust provide a no-argumentconstructor.

Let’sconsiderthefollowingSomeControllercontrollerthatdefinesasingle@RequestMappingmethod,doSomething:

Examplelisting11-10–@ModelAttributeargumentisnotavailableintheModelobject

@Controller@RequestMapping(value="/some")publicclassSomeController{.....@RequestMapping("/do")publicvoiddoSomething(@ModelAttribute("myObj")MyObjectmyObject){logger.info(myObject);.....}}

The above example listing shows that the SomeController class doesn’t define any@ModelAttributeannotatedmethodthataddsanobjectnamedmyObjoftypeMyObjectintheModel.Forthisreason,whenarequestfordoSomethingmethodisreceived,SpringcreatesaninstanceofMyObject,assignsit tothemyObjectargumentandalsoputsthenewlycreatedMyObjectinstanceintotheModelobject.

Let’snowlookatSpring’sRequestToViewNameTranslatorobject.

RequestToViewNameTranslatorRequestToViewNameTranslatordeterminestheviewtoberenderedwhena@RequestMappingannotatedmethoddoesn’texplicitlyspecifytheviewtoberendered.

We saw earlier that when a @RequestMapping method is also annotated with @ModelAttributeannotation, thevalue returnedby themethod isconsideredasamodelattribute. Insuchasituation, theRequestToViewNameTranslatorobjectisresponsiblefordeterminingtheviewtoberenderedbasedonthe incoming web request. Similarly, if a @RequestMapping annotated method returns void,org.springframework.ui.Model or java.util.Map, the RequestToViewNameTranslator object determinestheviewtoberendered.

DefaultRequestToViewNameTranslator is an implementation of RequestToViewNameTranslator that is

Page 385: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

usedbydefaultbyDispatcherServlet todetermine theview tobe renderedwhennoview isexplicitlyreturnedbya@RequestMappingmethod.DefaultRequestToViewNameTranslatorusestherequestURItodetermine the name of the logical view to render.DefaultRequestToViewNameTranslator removes theleadingandtrailingslashesandthefileextensionfromtheURItodeterminetheviewname.Forinstance,iftheURLishttp://localhost:8080/doSomething.htm,theviewnamebecomesdoSomething.

In case of MyBank web application, the FixedDepositController’s listFixedDeposits method (referexamplelisting11-6orFixedDepositController.javafileofch11-bankappproject)isannotatedwithboth@RequestMapping and @ModelAttribute; therefore, RequestToViewNameTranslator is used by theDispatcherServlettodeterminetheviewtorender.AsthelistFixedDepositsmethodismappedtorequestURI/fixedDeposit/list,RequestToViewNameTranslatorreturns/fixedDeposit/listastheviewname.TheViewResolver configured in theweb application contextXML file ofMyBankweb application (referbankapp-config.xml file of ch11-bankapp project) maps /fixedDeposit/list view name to /WEB-INF/jsp/fixedDeposit/list.jspJSPview.

Let’snowlookat@SessionAttributesannotation.

Page 386: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

11-3Cachingmodelattributesusing@SessionAttributesannotationIn the previous section, we saw that all the@ModelAttribute annotated methods of a controller arealwaysinvokedbeforethe@RequestMappingannotatedmethod.Thisbehaviormaynotbeacceptableinsituations inwhich@ModelAttributemethods obtain data from the database or from an external webservice to populate themodel attribute. In such scenarios, you can annotate your controller classwith@SessionAttributesannotationthatspecifiesthemodelattributesthatarestoredinHttpSessionbetweenrequests.

If@SessionAttributes annotation is used, a@ModelAttribute annotatedmethod is invoked only if themodel attribute specified by the @ModelAttribute annotation is not found in the HttpSession. Also,@ModelAttribute annotation on amethod argumentwill result in creation of a new instance ofmodelattributeonlyifthemodelattributeisnotfoundintheHttpSession.

IMPORTchapter11/ch11-session-attributes(Thisprojectshowsamodifiedversionofch11-bankappprojectthatuses@SessionAttributesannotationtotemporarilystoremodelattributesinHttpSession.TheMyBankwebapplicationfunctionalityofferedbych11-session-attributesandch10-bankappprojectsarethe same. If you deploy the project on Tomcat server and access theURL http://localhost:8080/ch11-session-attributes,you’llseethelistoffixeddepositsinthesystem.)

Thefollowingexample listingshowsusageof@SessionAttributesannotation inch11-session-attributesproject to temporarily storenewFixedDepositDetails and editableFixedDepositDetailsmodel attributesinHttpSession:

Examplelisting11-11–@SessionAttributesannotationusageProject–ch11-session-attributesSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;importorg.springframework.web.bind.annotation.SessionAttributes;.....@SessionAttributes(value={"newFixedDepositDetails","editableFixedDepositDetails"})publicclassFixedDepositController{.....@ModelAttribute(value="newFixedDepositDetails")publicFixedDepositDetailsgetNewFixedDepositDetails(){FixedDepositDetailsfixedDepositDetails=newFixedDepositDetails();fixedDepositDetails.setEmail("Youmustenteravalidemail");returnfixedDepositDetails;}.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit(@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,.....){.....}

Page 387: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....@RequestMapping(params="fdAction=view",method=RequestMethod.GET)publicModelAndViewviewFixedDepositDetails(@RequestParam(value="fixedDepositId")intfixedDepositId){FixedDepositDetailsfixedDepositDetails=fixedDepositService.getFixedDeposit(fixedDepositId);Map<String,Object>modelMap=newHashMap<String,Object>();modelMap.put("editableFixedDepositDetails",fixedDepositDetails);.....returnnewModelAndView("editFixedDepositForm",modelMap);}}

@SessionAttributes annotation’s value attribute specifies names of the model attributes that aretemporarily stored in HttpSession. In the above example listing, model attributes namednewFixedDepositDetails and editableFixedDepositDetails are stored inHttpSession between requests.The newFixedDepositDetails model attribute is returned by @ModelAttribute annotatedgetNewFixedDepositDetailsmethod,andtheeditableFixedDepositDetailsmodelattributeisreturnedbythe@RequestMappingannotatedviewFixedDepositDetailsmethod.

A controller contributesmodel attributes via@ModelAttribute annotatedmethods,@RequestMappingmethods (that returnModelAndView,Model orMap), and by directly adding model attributes to theModelobject.ThemodelattributescontributedbythecontrollerthroughanyapproacharecandidateforstorageintheHttpSessionby@SessionAttributesannotation.

When using@SessionAttributes annotation, you should ensure that the model attributes stored in theHttpSession are removedwhen they are no longer required.For instance, thenewFixedDepositDetailsmodel attribute represents an instanceofFixedDepositDetails that is usedby the ‘Open fixeddeposit’form to show the default value(s) of Email form field as ‘You must enter a valid email’ (refergetNewFixedDepositDetails 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 thenewFixedDepositDetails instance (refer openFixedDepositmethod in example listing 11-11).After thefixed deposit is successfully created, the newFixedDepositDetails instance is no longer required;therefore, it must be removed from the HttpSession. Similarly, editableFixedDepositDetails modelattributeisnotrequiredafteryouhavesuccessfullymodifieddetailsofafixeddeposit.

You can instruct Spring to remove all the model attributes stored in HttpSession by callingsetComplete method of Spring’s SessionStatus object. The following example listing showsFixedDepositController’sopenFixedDeposit and editFixedDepositmethods that invoke SessionStatus’ssetCompletemethodafterafixeddepositissuccessfullycreatedormodified:

Examplelisting11-12–RemovingmodelattributesfromHttpSessionusingSessionStatusobjectProject–ch11-session-attributesSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;

Page 388: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importorg.springframework.web.bind.support.SessionStatus;.....@SessionAttributes(value={"newFixedDepositDetails","editableFixedDepositDetails"})publicclassFixedDepositController{.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit(@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,.....,SessionStatussessionStatus){fixedDepositService.saveFixedDeposit(fixedDepositDetails);sessionStatus.setComplete();}}@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)publicStringeditFixedDeposit(@ModelAttribute("editableFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,.....,SessionStatussessionStatus){fixedDepositService.editFixedDeposit(fixedDepositDetails);sessionStatus.setComplete();.....}}.....}

TheaboveexamplelistingshowsthatbothopenFixedDepositandeditFixedDepositmethodsaredefinedtoacceptanargumentof typeSessionStatus.Whena@RequestMapping annotatedmethod specifies anargumentoftypeSessionStatus,Springsuppliesan instanceofSessionStatus to themethod.Thecall tosetComplete method instructs Spring to remove the current controller’s model attributes from theHttpSessionobject.

Inexample listing11-11and11-12,wesaw that the@SessionAttributes’svalue attribute specifies thenamesofmodelattributesthataretemporarilystoredinHttpSession.IfyouwantthatonlycertaintypesofmodelattributesarestoredinHttpSession,youcanuse@SessionAttributes’stypesattribute.Forinstance,the following @SessionAttributes annotation specifies that attributes named x and y, and all modelattributesthatareoftypeMyObject,aretemporarilystoredinHttpSession:

@SessionAttributes(value={"x","y"},types={MyObject.class})

You can see the order inwhich listFixedDeposits, getNewFixedDepositDetails and openFixedDepositmethodsare invokedbydeployingch11-session-attributesprojectandperform theactionsdescribed inthefollowingtable:

Action Messagesprintedontheconsole

Gotohttp://localhost:8080/ch11-session-attributes/fixedDeposit/listURL

getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetails

listFixedDeposits()method:Gettinglistoffixeddeposits

Page 389: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Clickthe‘CreatenewFixedDeposit’button

showOpenFixedDepositForm()method:Showingformforopeninganewfixeddeposit

Enterfixeddepositdetailsandclickthe‘Save’button

openFixedDeposit()method:Fixeddepositdetailssuccessfullysaved.Redirectingtoshowthelistoffixeddeposits.

getNewFixedDepositDetails()method:ReturninganewinstanceofFixedDepositDetails

listFixedDeposits()method:Gettinglistoffixeddeposits

In ch11-bankapp project, we saw that the @ModelAttribute annotated getNewFixedDepositDetailsmethod of FixedDepositController was invoked each time a request was dispatched toFixedDepositController.TheabovetableshowsthatthegetNewFixedDepositDetailsmethodisinvokedwhen request is handled by the FixedDepositController for the first time. As the openFixedDepositmethod removes the model attributes stored in the HttpSession, request to listFixedDeposits methodresultsininvocationofgetNewFixedDepositDetailsmethodonceagain.

Now,thatwehaveseenhowtouse@ModelAttributeand@SessionAttributesannotations, let’s lookathowdatabindingisperformedinSpringWebMVCapplications.

Page 390: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

11-4DatabindingsupportinSpringWhenaformissubmittedinaSpringWebMVCapplication,requestparameterscontainedintherequestareautomaticallysetonthemodelattributethatactsastheformbackingobject.Thisprocessofsettingrequestparametersontheformbackingobjectisreferredtoasdatabinding.Inthissection,we’lllookatSpring’sWebDataBinderinstancethatbindsrequestparameterstoformbackingobjects.

IMPORT chapter 11/ch11-data-binding (This project shows a modified version of ch11-session-attributesprojectthatshowshowtoregisterPropertyEditorimplementationswithSpringcontainer.IfyoudeploytheprojectonTomcatserverandaccesstheURLhttp://localhost:8080/ch11-data-binding,you’llseethelistoffixeddepositsinthesystem.)

ThefollowingexamplelistingshowstheFixedDepositDetailsclassofch11-data-bindingproject:

Examplelisting11-13–FixedDepositDetailsclassProject–ch11-data-bindingSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.domain;importjava.util.Date;publicclassFixedDepositDetails{.....privatelongdepositAmount;privateDatematurityDate;.....publicvoidsetDepositAmount(longdepositAmount){this.depositAmount=depositAmount;}publicvoidsetMaturityDate(DatematurityDate){this.maturityDate=maturityDate;}.....}

The above example listing shows that thedepositAmount andmaturityDate fields are of type long andjava.util.Date,respectively.ThevaluesofdepositAmountandmaturityDatefieldsaresetwhenthe‘Openfixeddeposit’formofch11-data-bindingprojectissubmitted.Thefollowingfigureshowsthe‘Openfixeddeposit’formofch11-data-bindingprojectthatisusedforopeningnewfixeddeposits:

Page 391: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure11-2‘Openfixeddeposit’formforopeningnewfixeddeposits

Intheabovefigure,‘Amount(inUSD)’and‘Maturitydate’formfieldscorrespondtodepositAmountandmaturityDate fields of FixedDepositDetails class (refer example listing 11-13). One of the importantthingstonoteisthatthe‘Maturitydate’fieldacceptsadateintheformat‘MM-dd-yyyy’,like01-27-2013.AsdepositAmountfieldisoftypelong,andmaturityDateisoftypejava.util.Date,Spring’sdatabindingmechanism is responsible for doing the type conversion from String to the type defined by theFixedDepositDetailsinstance.

ThefollowingexamplelistingshowsFixedDepositController’sopenFixedDepositmethodthatisinvokedwhenauserfillsthe‘Openfixeddeposit’formandclicksthe‘Save’button(referfigure11-2):

Examplelisting11-14–FixedDepositController-AutomaticdatabindingexampleProject–ch11-data-bindingSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;@Controller.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit( @ModelAttribute(value = "newFixedDepositDetails") FixedDepositDetailsfixedDepositDetails,BindingResultbindingResult,SessionStatussessionStatus){....}.....}

In the above example listing, the@ModelAttribute annotatedFixedDepositDetails argument representstheformbackingobjectonwhichtherequestparametersaresetwhenthe‘Openfixeddeposit’ formissubmitted. Spring’s WebDataBinder instance binds request parameters to the FixedDepositDetailsinstance.

Page 392: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Let’snowlookathowWebDataBinderperformsdatabinding.

WebDataBinder–databinderforwebrequestparametersWebDataBinderusestherequestparameternametofindthecorrespondingJavaBean-stylesettermethodontheformbackingobject.IfaJavaBean-stylesettermethodisfound,WebDataBinderinvokesthesettermethodandpassestherequestparametervalueasanargumenttothesettermethod.Ifthesettermethodisdefined to accept a non-String type argument, WebDataBinder uses an appropriate PropertyEditor toperformthetypeconversion.

The following example listing shows the MyObject class that acts as a form backing object in anapplication:

Examplelisting11-15–MyObjectclass–aformbackingobject

publicclassMyObject{privateStringx;privateNy;.....publicvoidsetX(Stringx){this.x=x;}publicvoidsetY(Ny){this.y=y;}}

TheaboveexamplelistingshowsthattheMyObjectclassdefinespropertiesnamedxandyoftypeStringandN,respectively.

The following figure shows howWebDataBinder binds request parameters named x and y to x and ypropertiesofMyObjectinstance:

Page 393: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure11-3WebDataBinderperformsdatabindingbyusingregisteredPropertyEditors toperformtypeconversion

TheabovefigureshowsthattheWebDataBinderusesaPropertyEditortoconvertStringvaluebtotypeN,beforecallingthesetYmethodofMyObjectinstance.

Springprovidesacoupleofbuilt-inPropertyEditorimplementationsthatareusedbyWebDataBinderforconverting String type request parameter value to the type defined by the form backing object. Forinstance,CustomNumberEditor,FileEditor,CustomDateEditor are some of the built-in PropertyEditorsprovided by Spring. For a complete list of built-in PropertyEditors, refer toorg.springframework.beans.propertyeditorspackage.

CustomNumberEditorisusedforconvertingaStringvaluetoajava.lang.Numbertype,likeInteger,Long,Double,andsoon.CustomDateEditorisusedforconvertingaStringvaluetoajava.util.Datetype.Youcanpassajava.text.DateFormatinstancetoCustomDateEditor tospecify thedate format tobeusedforparsing and rendering dates. Both these PropertyEditors are required in ch11-data-binding projectbecause we need to convert request parameter values to depositAmount (which is of type long) andmaturityDate (which is of type java.util.Date). CustomNumberEditor is pre-registered with theWebDataBinderinstancebutyouneedtoexplicitlyregisterCustomDateEditor.

Let’s now look at how you can configure a WebDataBinder instance and register a PropertyEditorimplementationwithit.

ConfiguringaWebDataBinderinstanceYoucanconfigureaWebDataBinderinstanceby:

·definingan@InitBinderannotatedmethodinthecontrollerclass

·configuringaWebBindingInitializerimplementationinthewebapplicationcontextXMLfile

·definingan@InitBinderannotatedmethodina@ControllerAdviceannotatedclass

Let’s look at each of the above mentioned approach for configuring a WebDataBinder instance andregisteringaPropertyEditorwithit.

Definingan@InitBinderannotatedmethodinthecontrollerclass

An@InitBinderannotatedmethodinacontrollerclassspecifiesthatthemethodinitializesaninstanceofWebDataBinderthatwillbeusedbythecontrollerduringdatabinding.Thevalueattributeof@InitBinderannotationspecifies thename(s)of themodelattribute towhichtheinitializedWebDataBinder instanceapplies.

ThefollowingexamplelistingshowsFixedDepositController’sinitBinder_Newmethodthatisannotatedwith@InitBinder:

Examplelisting11-16–FixedDepositController-@InitBinderannotationusageProject–ch11-data-bindingSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;

Page 394: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importjava.text.SimpleDateFormat;importorg.springframework.beans.propertyeditors.CustomDateEditor;importorg.springframework.web.bind.WebDataBinder;importorg.springframework.web.bind.annotation.InitBinder;@Controller.....publicclassFixedDepositController{.....@ModelAttribute(value="newFixedDepositDetails")publicFixedDepositDetailsgetNewFixedDepositDetails(){.....}@InitBinder(value="newFixedDepositDetails")publicvoidinitBinder_New(WebDataBinderwebDataBinder){webDataBinder.registerCustomEditor(Date.class,newCustomDateEditor(newSimpleDateFormat("MM-dd-yyyy"),false));}.....}

In the above example listing, the @InitBinder annotation’s value attribute is set tonewFixedDepositDetails,whichmeansthattheWebDataBinderinitializedbytheinitBinder_Newmethodapplies only to the newFixedDepositDetails model attribute. An @InitBinder annotated method canacceptsamesetofarguments(likeHttpServletRequest,SessionStatus,andsoon)[email protected],an@InitBinderannotatedmethodcan’tbedefined toacceptmodelattributesandBindingResult(orErrors)objectsasarguments.Typically,WebDataBinderinstance,alongwithSpring’sWebRequestor java.util.Locale instance, ispassed [email protected]@InitBindermethodmustbevoid.

WebDataBinder’s registerCustomEditor method is used for registering a PropertyEditor with theWebDataBinderinstance.Inexamplelisting11-16,initBinder_NewmethodregistersCustomDateEditor(aPropertyEditor)withtheWebDataBinderinstance.

You can define an@InitBinder annotatedmethod for eachmodel attribute of a controller, or you candefineasingle@InitBinderannotatedmethodthatappliestoallthemodelattributesofthecontroller.Ifyoudon’tspecifythevalueattributeof@InitBinderannotation,theWebDataBinderinstanceinitializedbythemethodisapplicabletoallthemodelattributesofthecontroller.

ConfiguringaWebBindingInitializerimplementation

AWebDataBinder instance is first initialized byRequestMappingHandlerAdapter, followed by furtherinitializationbyWebBindingInitializerand@InitBindermethods.

The <annotation-driven> element of Spring’s mvc schema creates an instance of Spring’sRequestMappingHandlerAdapterthatinitializestheWebDataBinder.YoucansupplyanimplementationofSpring’s WebBindingInitializer interface to RequestMappingHandlerAdapter to further initialize

Page 395: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

WebDataBinderinstances.Youcanadditionallyuse@InitBindermethodsinacontrollerclasstofurtherinitializeWebDataBinderinstances.

The following figure shows the sequence in which RequestMappingHandlerAdapter,WebBindingInitializerand@InitBindermethodsinitializeaWebDataBinderinstance:

Figure 11-4 The sequence in which a WebDataBinder instance is initialized byRequestMappingHandlerAdapter,WebBindingInitializerand@InitBindermethodsofacontrollerclass

WebDataBinder initializationbyan@InitBindermethodofacontrollerclass isapplicableonly to thatcontroller’smodelattributes.For instance, ifyouusean@InitBindermethod incontrollerX to set theCustomDateEditorpropertyeditoron theWebDataBinder instance, then theCustomDateEditor propertyeditor will be available only to themodel attributes of controller X during data binding. InMyBankapplication, the CustomDateEditor was required only by the model attributes of theFixedDepositController; therefore, we used @InitBinder annotated methods in theFixedDepositControllerclasstoregisterCustomDateEditorwithWebDataBinderinstance.

Spring’s WebBindingInitializer is a callback interface whose implementation is responsible forinitializingaWebDataBinderwiththeconfigurationthatappliestoallthecontrollers(andtherebytoallthemodel attributes) in the application.Let’s lookathow to configure a customWebBindingInitializerwhenusing<annotation-driven>elementofSpring’smvcschema.

The <annotation-driven> element of Spring’s mvc schema creates and registersRequestMappingHandlerAdapterandRequestMappingHandlerMappingobjectswiththeSpringcontainer.The other objects that are configured by <annotation-driven> element are LocalValidatorFactoryBean(explained in section 11-5) andFormattingConversionServiceFactoryBean (explained in section 13-5).The <annotation-driven> element provides couple of attributes that help you customizeRequestMappingHandlerAdapterandRequestMappingHandlerMappingobjects.If thecustomizationyouwant to make to RequestMappingHandlerAdapter or RequestMappingHandlerMapping object is notprovidedbythe<annotation-driven>element,theonlyoptionistoremove<annotation-driven>elementand explicitly configureRequestMappingHandlerAdapter andRequestMappingHandlerMapping objectsinthewebapplicationcontextXMLfile.As<annotation-driven>elementdoesn’tprovideanyoptiontosupply a customWebBindingInitializer instance to the RequestMappingHandlerAdapter object, you’ll

Page 396: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

have to explicitly configure RequestMappingHandlerAdapter and RequestMappingHandlerMappingobjectsinthewebapplicationcontextXMLfile.

The followingexample listing showshowyoucanuseSpring’sConfigurableWebBindingInitializer (animplementationofWebBindingInitializer)tomakeCustomDateEditorpropertyeditoravailabletoallthecontrollersintheMyBankapplication:

Examplelisting11-17–WebBindingInitializerconfiguration

<beanid="handlerAdapter"class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><propertyname="webBindingInitializer"ref="myInitializer"/></bean><beanid="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/><beanid="myInitializer"class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"><propertyname="propertyEditorRegistrars"><list><beanclass="mypackage.MyPropertyEditorRegistrar"/></list></property></bean>The above example listing shows that RequestMappingHandlerAdapter andRequestMappingHandlerMappingbeansareexplicitlydefinedinthewebapplicationcontextXMLfile.The RequestMappingHandlerAdapter’s webBindingInitializer property refers to theConfigurableWebBindingInitializer bean that implements WebBindingInitializer interface.ConfigurableWebBindingInitializer’spropertyEditorRegistrarspropertyspecifiesclassesthatregisteroneor more PropertyEditors with WebDataBinder. The following example listing shows howMyPropertyEditorRegistrarclassregistersCustomDateEditorpropertyeditorwithWebDataBinder:

Examplelisting11-18–MyPropertyEditorRegistrarclass

importorg.springframework.beans.PropertyEditorRegistrar;importorg.springframework.beans.PropertyEditorRegistry;importorg.springframework.beans.propertyeditors.CustomDateEditor;publicclassMyPropertyEditorRegistrarimplementsPropertyEditorRegistrar{@OverridepublicvoidregisterCustomEditors(PropertyEditorRegistryregistry){registry.registerCustomEditor(Date.class,newCustomDateEditor(newSimpleDateFormat("MM-dd-yyyy"),false));}

Page 397: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

}

The above example listing shows that the MyPropertyEditorRegistrar class implements Spring’sPropertyEditorRegistrar interface, and provides implementation for registerCustomEditors methoddefined in the PropertyEditorRegistrar interface. The PropertyEditorRegistry instance passed to theregisterCustomEditors method is used for registering property editors. PropertyEditorRegistry’sregisterCustomEditor method is used for registering a PropertyEditor implementation with theWebDataBinder.Intheaboveexamplelisting,PropertyEditorRegistry’sregisterCustomEditorisusedforregisteringtheCustomDateEditorpropertyeditorwiththeWebDataBinder.

As we saw, usingWebBindingInitializer for initializingWebDataBinder is quite an involved task. Asimpler alternative to using WebBindingInitializer is to define @InitBinder annotated methods in a@ControllerAdviceannotatedclass.

Definingan@InitBindermethodina@ControllerAdviceannotatedclass

Like @Service, @Controller and @Repository annotations, @ControllerAdvice annotation is [email protected]@ControllerAdviceannotationonaclassindicatesthatthe class provides support to controllers. You can define @InitBinder, @ModelAttribute and@ExceptionHandler annotatedmethods in the@ControllerAdvice annotated class, and these annotatedmethodsapply toall the annotated controllers in the application.Aswith@Service,@Controller and@Repositoryannotations,<classpath-scanning>elementofSpring’scontextschemaautomaticallydetectsandregisters@ControllerAdviceannotatedclasseswiththeSpringcontainer.

Ifyounoticethatyouareduplicating@InitBinder,@ModelAttributeand@ExceptionHandlermethodsinmultiplecontrollers, thenconsiderdefiningsuchmethods [email protected], if you want to initialize the WebDataBinder with the configuration that applies to multiplecontrollersintheapplication,thendefinean@InitBindermethodina@ControllerAdviceannotatedclassinsteadofdefiningan@InitBindermethodinmultiplecontrollerclasses.

ThefollowingtablesummarizesthethreeapproachesthatwediscussedforinitializingWebDataBinder:@InitBindermethodincontrollerclass WebBindingInitializer @InitBinder method in

@ControllerAdviceclass

Requires defining an @InitBindermethodinacontroller

Requires explicitly configuringRequestMappingHandlerAdapterinthewebapplicationcontextXMLfile

Requires defining an @InitBindermethod in a @ControllerAdviceannotatedclass

WebDataBinderinitializationappliesonly to the controller that containsthe@InitBindermethod

WebDataBinder initialization applies to alltheannotatedcontrollersintheapplication

WebDataBinder initialization appliestoalltheannotatedcontrollersintheapplication

Let’snowlookathowyoucanallowordisallowfieldsofamodelattributefromparticipatinginthedatabindingprocess.

AllowingordisallowingfieldsfromdatabindingprocessWebDataBinder allowsyou to specify fieldsof amodel attribute that are allowedordisallowed fromparticipatinginthedatabindingprocess.Itisstronglyrecommendedthatyouspecifythefieldsofamodelattribute that are allowed or disallowed from the data binding processes, as failing to do so maycompromisethesecurityofyourapplication.Let’slookatascenarioinwhichwewouldliketoallowordisallowfieldsfromdatabinding.

Page 398: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

InMyBankapplication,whenauserselectsafixeddepositforediting,thedetailsoftheselectedfixeddepositareloadedfromthedatastoreandtemporarilycachedintheHttpSession.Theusermakeschangestothefixeddepositandsavesthechanges.Thefollowingexamplelistingshowsthe@RequestMappingmethodsthatareresponsibleforloadingtheselectedfixeddepositandsavingtheupdatedfixeddepositinformation:

Examplelisting11-19–FixedDepositControllerProject–ch11-data-bindingSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;.....@SessionAttributes(value={"newFixedDepositDetails","editableFixedDepositDetails"})publicclassFixedDepositController{.....@RequestMapping(params="fdAction=view",method=RequestMethod.GET)publicModelAndViewviewFixedDepositDetails(@RequestParam(value="fixedDepositId")intfixedDepositId){FixedDepositDetailsfixedDepositDetails=fixedDepositService.getFixedDeposit(fixedDepositId);Map<String,Object>modelMap=newHashMap<String,Object>();modelMap.put("editableFixedDepositDetails",fixedDepositDetails);.....returnnewModelAndView("editFixedDepositForm",modelMap);}.....@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)publicStringeditFixedDeposit(@ModelAttribute("editableFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,){.....}}

InMyBank application, a fixed deposit is uniquely identified by the id field of FixedDepositDetailsobject (refer FixedDepositDetails class of ch11-data-binding project). When a user selects a fixeddeposit for editing, the id field value is passed to the viewFixedDepositDetails method via thefixedDepositIdrequestparameter.TheviewFixedDepositDetailsmethodusesthevalueoffixedDepositIdrequestparametertoloadfixeddepositdetailsandshowthemonthe‘Editfixeddeposit’form,asshowninthefollowingfigure:

Page 399: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure11-5‘Editfixeddeposit’formforeditinganexistingfixeddeposit

Astheidvalue(thatcorrespondstoidattributeofFixedDepositDetailsobject)uniquelyidentifiesafixeddepositinthesystem,the‘Editfixeddeposit’formdoesn’tprovideanymechanismtochangeit.Whentheuser clicks the ‘Save’ button, the FixedDepositController’s editFixedDeposit method is invoked. TheeditFixedDepositmethodsavesthechangestothefixeddepositdetail.

WhenFixedDepositController’seditFixedDepositmethodisinvoked,theWebDataBinderinstancebindsrequest parameter values to the fields of editableFixedDepositDetails model attribute – theFixedDepositDetailsobjectthatwasloadedbyviewFixedDepositDetailsmethodandtemporarilystoredinHttpSession(refer@SessionAttributesannotationinexamplelisting11-19).Ifamalicioususersendsarequestparameternamedidwithvalue10,thentheWebDataBinderwillblindlygoaheadandsettheidattributeofFixedDepositDetailsobjectto10duringdatabinding.ThisisnotdesirablebecausechangingidattributeofaFixedDepositDetailsobjectwillcompromiseapplicationdata.

WebDataBinderprovidessetAllowedFieldsandsetDisallowedFieldsmethodsthatyoucanusetosetthenamesofmodelattributefieldsthatcanandcannotparticipateinthedatabindingprocess.ThefollowingexamplelistingshowstheFixedDepositController’sinitBinder_EditmethodthatspecifiesthattheidfieldofeditableFixedDepositDetailsmodelattributemustnotparticipateinthedatabindingprocess:

Examplelisting11-20–FixedDepositController–WebDataBinder’ssetDisallowedFieldsmethodProject–ch11-data-bindingSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)publicStringeditFixedDeposit(@ModelAttribute("editableFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,.....){.....}

Page 400: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....@InitBinder(value="editableFixedDepositDetails")publicvoidinitBinder_Edit(WebDataBinderwebDataBinder){webDataBinder.registerCustomEditor(Date.class,newCustomDateEditor(newSimpleDateFormat("MM-dd-yyyy"),false));webDataBinder.setDisallowedFields("id");}}

In the above example listing, the initBinder_Edit method initializes WebDataBinder instance for theeditableFixedDepositDetails model attribute. As the setDisallowedFields method specifies that the idfieldofeditableFixedDepositDetailsmodelattributeisdisallowedtoparticipateinthebindingprocess,theidfieldisnotsetevenifarequestparameternamedidiscontainedintherequest.

Let’snowlookatSpring’sBindingResultobject thatexposeserrors thatoccurduringdatabindingandvalidation.

InspectingdatabindingandvalidationerrorsusingBindingResultobjectSpring’sBindingResultobjectprovidesacontrollermethodwiththeresultsofbindingrequestparameterstothemodelattribute’sfields.Forinstance,ifanytypeconversionerroroccursduringdatabinding,theyarereportedbytheBindingResultobject.

ThefollowingexamplelistingshowsFixedDepositController’sopenFixedDepositmethodthatcreatesafixeddepositonlyifnoerrorsarereportedbytheBindingResultobject:

Example listing 11-21 – FixedDepositController – checking for binding and validation errors usingBindingResultProject–ch11-data-bindingSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;importorg.springframework.validation.BindingResult;importorg.springframework.web.bind.annotation.ModelAttribute;.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit(@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,BindingResultbindingResult,SessionStatussessionStatus){.....if(bindingResult.hasErrors()){return"createFixedDepositForm";}else{fixedDepositService.saveFixedDeposit(fixedDepositDetails);

Page 401: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

sessionStatus.setComplete();return"redirect:/fixedDeposit/list";}}.....}

In the above example listing, the BindingResult’s hasErrors method returns true if the BindingResultobject holds one ormore data binding or validation errors. In section 11-5,we’ll see howvalidationerrors are stored in the BindingResult object. If errors are reported by the BindingResult object, theopenFixedDepositmethodrendersthe‘Createfixeddeposit’formwithappropriateerrormessages.Ifnoerrorsarereported,thefixeddepositdetailsaresavedinthedatastore.

Youshouldnote that theBindingResultargumentmust immediately follow themodelattributeargumentwhoseBindingResultobjectyouwanttoaccessinthecontrollermethod.Forinstance,inexamplelisting11-21,theBindingResultargumentimmediatelyfollowsthenewFixedDepositDetailsmodelattribute.ThefollowingexamplelistingshowsanincorrectorderingofthemodelattributeandtheBindingResultobjectfortheopenFixedDepositmethod:

Examplelisting11-22–IncorrectorderingofthemodelattributeandtheBindingResultobject.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit( @ModelAttribute(value = "newFixedDepositDetails") FixedDepositDetailsfixedDepositDetails,SessionStatussessionStatus,BindingResultbindingResult){.....}.....}

In the above example listing, the ordering of the newFixedDepositDetails model attribute and theBindingResultobjectisincorrectbecausetheSessionStatusargumentisdefinedbetweenthem.

Ifacontrollermethodacceptsmultiplemodelattributes,theBindingResultobjectcorrespondingtoeachmodelattributeisspecifiedimmediatelyaftereachmodelattributeargument,asshowninthefollowingexamplelisting:

Examplelisting11-23–MultiplemodelattributesandtheirBindingResultobjects@RequestMappingpublicStringdoSomething(@ModelAttribute(value="a")AObjectaObj,BindingResultbindingResultA,@ModelAttribute(value="b")BObjectbObj,BindingResultbindingResultB,){.....

Page 402: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

}

Theaboveexample listingshows thatbothmodelattributesaandbare immediately followedby theircorrespondingBindingResultobjects.

Now,thatwehaveseenthedatabindingprocess,let’slookathowvalidationisperformedinSpringWebMVCapplications.

Page 403: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

11-5ValidationsupportinSpringIntheprevioussection,wesawthattheWebDataBinderbindsrequestparameterstomodelattributes.Thenextstepinrequestprocessingistovalidatemodelattributes.InSpringWebMVCapplications,youcanvalidate model attributes using Spring Validation API (discussed in section 6-9 of chapter 6) or byspecifyingJSR303(BeanValidationAPI)constraints(discussedinsection6-10ofchapter6)onfieldsofmodelattributes.

NOTE In this chapter, SpringValidationAPI and JSR 303 (BeanValidationAPI) have been used tovalidateformbackingobjects(whicharemodelattributes)intheweblayeroftheapplication.YoushouldnotethatbothJSR303(BeanValidationAPI)andSpringValidationAPIcanbeusedtovalidateobjectsinanyapplicationlayer.

Let’sfirstlookathowtovalidatemodelattributesusingSpringValidationAPI’sValidatorinterface.

ValidatingmodelattributesusingSpring’sValidatorinterfaceThefollowingexamplelistingshowstheFixedDepositDetailsValidatorclassofMyBankapplicationthatvalidatesFixedDepositDetailsobject:

Examplelisting11-24–FixedDepositDetailsValidator–Spring’sValidatorinterfaceusageProject–ch11-data-bindingSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;importorg.springframework.validation.*;importsample.spring.chapter11.domain.FixedDepositDetails;publicclassFixedDepositDetailsValidatorimplementsValidator{publicbooleansupports(Class<?>clazz){returnFixedDepositDetails.class.isAssignableFrom(clazz);}publicvoidvalidate(Objecttarget,Errorserrors){FixedDepositDetailsfixedDepositDetails=(FixedDepositDetails)target;longdepositAmount=fixedDepositDetails.getDepositAmount();.....if(depositAmount<1000){errors.rejectValue("depositAmount","error.depositAmount.less","mustbegreaterthanorequalto1000");}if(email==null||"".equalsIgnoreCase(email)){ValidationUtils.rejectIfEmptyOrWhitespace(errors,"email","error.email.blank","mustnotbeblank");}

Page 404: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....}}

Spring’sValidator interface defines supports andvalidatemethods.The supportsmethod checks if thesupplied object instance (represented by the clazz attribute) can be validated. If the supports methodreturns true, the validate method is used to validate the object. In the above example listing, theFixedDepositDetailsValidator’s supports method checks if the supplied object instance is of typeFixedDepositDetails. If the supports method returns true, the FixedDepositDetailsValidator’s validatemethod validates the object. The validate method accepts the object instance to be validated, and anErrors instance.Errors instancestoresandexposeserrors thatoccurduringvalidation.Errors instanceprovides multiple reject and rejectValue methods to register errors with the Errors instance. TherejectValuemethodsareusedtoreportfield-levelerrors,andrejectmethodsareusedtoreporterrorsthatapply to the object being validated. Spring’s ValidationUtils class is a utility class that providesconveniencemethodstoinvokeaValidator,andforrejectingemptyfields.

The following figure describes the parameters thatwere passed to the rejectValuemethod in examplelisting11-24toreportavalidationerrorcorrespondingtoFixedDepositDetails’sdepositAmountfield:

Figure11-6DescriptionofparametersthatarepassedtorejectValuemethodofErrorsinstancetoreportvalidationerrorcorrespondingtodepositAmountfieldofFixedDepositDetails

Theabovefigureshowsthatfieldname,errorcode(whichisbasicallyamessagekey)andadefaulterrormessageispassedtotherejectValuemethod.Inchapter13,we’llseehowthemessagekeysareusedbyJSPpagestoshowmessagesfromresourcebundles.

Youcanvalidatemodelattributesby:

§explicitlyinvokingvalidatemethodonValidatorimplementation

§settingValidatorimplementationonWebDataBinder,andannotatingthemodelattributeargumentinthe@RequestMappingmethodwithJSR303’s@Validannotation

Let’slookateachoftheabovementionedapproachesindetail.

Page 405: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Validatingmodelattributesbyexplicitlycallingvalidatemethod

The followingexample listing shows theFixedDepositController’sopenFixedDepositmethod that usesFixedDepositDetailsValidator (refer example listing 11-24) to validate FixedDepositDetails modelattribute:

Example listing 11-25 – FixedDepositController – validation by explicitly invokingFixedDepositDetailsValidator’svalidatemethodProject–ch11-data-bindingSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit( @ModelAttribute(value = "newFixedDepositDetails") FixedDepositDetailsfixedDepositDetails,BindingResultbindingResult,SessionStatussessionStatus){newFixedDepositDetailsValidator().validate(fixedDepositDetails,bindingResult);if(bindingResult.hasErrors()){logger.info("openFixedDeposit()method:Validationerrors-re-displayingformforopeninganewfixeddeposit");return"createFixedDepositForm";}.....}}

The above example listing shows that the openFixedDeposit method creates an instance ofFixedDepositDetailsValidator and invokes its validatemethod.AsBindingResult is a sub-interface ofErrors, you can pass a BindingResult objectwhere Errors object is expected. The openFixedDepositmethod passes the fixedDepositDetails model attribute and the BindingResult object to the validatemethod.AsBindingResultalreadycontainsdatabindingerrors,passingBindingResultobjecttovalidatemethodaddsvalidationerrorsalsototheBindingResultobject.

InvokingmodelattributesvalidationusingJSR303’s@Validannotation

You can instruct Spring to automatically validate a model attribute argument passed to a@RequestMappingmethodbyaddingJSR303’s@Validannotationtothemodelattributeargument,andsettingthevalidatorforthemodelattributeontheWebDataBinderinstance.

The followingexample listingshowshowFixedDepositController’sopenFixedDepositmethodcanuse@ValidannotationtovalidateFixedDepositDetailsmodelattribute:

Examplelisting11-26–FixedDepositController–invokingvalidationusing@Validannotation

Page 406: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importjavax.validation.Valid;.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit(@Valid@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,BindingResultbindingResult,SessionStatussessionStatus){if(bindingResult.hasErrors()){logger.info("openFixedDeposit()method:Validationerrors-re-displayingformforopeninganewfixeddeposit");return"createFixedDepositForm";}.....}.....@InitBinder(value="newFixedDepositDetails")publicvoidinitBinder_New(WebDataBinderwebDataBinder){webDataBinder.registerCustomEditor(Date.class,newCustomDateEditor(newSimpleDateFormat("MM-dd-yyyy"),false));webDataBinder.setValidator(newFixedDepositDetailsValidator());}.....}

Intheaboveexamplelisting,theinitBinder_NewmethodcallsWebDataBinder’ssetValidatormethod tosetFixedDepositDetailsValidatorasthevalidatorfornewFixedDepositDetailsmodelattribute,andintheopenFixedDeposit method the newFixedDepositDetails model attribute is annotated with JSR 303’[email protected],bothdatabindingandvalidationareperformedonthenewFixedDepositDetailsmodelattribute,andtheresultsofdatabindingandvalidationaremadeavailableviatheBindingResultargument.

Itisimportanttonotethatif@InitBinderannotationspecifiesnameofthemodelattribute,thevalidatorsetontheWebDataBinderappliesonlytothatparticularmodelattribute.Forinstance,inexamplelisting11-26,theFixedDepositDetailsValidatorappliesonlytothenewFixedDepositDetailsmodelattribute.Ifavalidator applies to multiple controllers in the application, consider defining an@InitBinder methodinside a@ControllerAdvice annotated class (or useWebBindingInitializer) to set a validator on theWebDataBinder.

Let’snow lookathowconstraints are specifiedonpropertiesof JavaBeanscomponentusing JSR303annotations.

SpecifyingconstraintsusingJSR303annotationsJSR303(BeanValidationAPI)definesannotationsthatyoucanusetospecifyconstraintsonpropertiesof

Page 407: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

JavaBeanscomponents.

IMPORT chapter 11/ch11-jsr303-validation (This project shows a modified version of ch11-data-bindingprojectthatusesJSR303annotationstospecifyconstraintsonFixedDepositDetailsobject.Ifyoudeploy the project on Tomcat server and access theURL http://localhost:8080/ch11-jsr303-validation,you’llseethelistoffixeddepositsinthesystem.)

The following example listing shows the FixedDepositDetails class that uses JSR 303 annotations tospecifyconstraintsonitsfields:

Examplelisting11-27–FixedDepositDetails–specifyingJSR303constraintsProject–ch11-jsr303-validationSourcelocation-src/main/java/sample/spring/chapter11/domain

packagesample.spring.chapter11.domain;importjavax.validation.constraints.*;publicclassFixedDepositDetails{privatelongid;@Min(1000)@Max(500000)privatelongdepositAmount;@Email@Size(min=10,max=25)privateStringemail;@NotNullprivateDatematurityDate;.....}

@Min,@Max,@Email,@Size, and@NotNull are some of the annotations defined by JSR 303. Theabove example listing shows that by using JSR 303 annotations FixedDepositDetails class clearlyspecifies theconstraints that applyon its fields.On theotherhand, ifyouareusingSpring’sValidatorimplementation to validate an object, constraints are contained in the Validator implementation (referexamplelisting11-24).

The following table describes the constraints enforced by JSR 303 annotations on theFixedDepositDetailsobjectshowninexamplelisting11-27:

JSR303annotation Constraintdescription

@NotNull Theannotatedfieldmustnotbenull.Forinstance,maturityDatefieldmustnotbenull.

@MinTheannotatedfield’svaluemustbegreaterthanorequaltothespecifiedminimumvalue.

For instance, @Min(1000) annotation on depositAmount field of FixedDepositDetails objectmeansthatdepositAmount’svaluemustbegreaterthanorequalto1000.

@MaxTheannotatedfield’svaluemustbelessthanorequaltothespecifiedvalue.

Page 408: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Forinstance,@Max(500000)annotationondepositAmount fieldofFixedDepositDetails objectmeansthatthedepositAmount’svaluemustbelessthanorequalto500000.

@Size

Theannotatedfield’ssizemustbebetweenthespecifiedminandmaxattributes.

For instance,@Size(min=5, max=100) annotation on email field of FixedDepositDetails objectmeansthatthesizeoftheemailfieldmustbegreaterthanorequalto5andlessthanorequalto100.

@EmailTheannotatedfield’svaluemustawell-formedemailaddress.

Forinstance,@EmailannotationontheemailfieldofFixedDepositDetailsobjectmeansthattheemailfield’svaluemustbeawell-formedemailaddress.

TouseJSR303annotations,ch11-jsr303-validationprojectspecifiesdependencyonJSR303APIJARfile(validation-api-1.0.0.GA)andHibernateValidatorframework(hibernate-validation-4.3.0.Final).TheHibernate Validator framework provides the reference implementation for JSR 303. The HibernateValidator framework provides additional constraint annotations that you can use along with JSR 303annotations. For instance, you can use Hibernate Validator’s @NotBlank annotation to specify that afield’svaluemustnotbenullorempty.

It is important tonote that JSR303alsoallowsyou tocreate customconstraints anduse them inyourapplication. For instance, you can create a @MyConstraint custom constraint and a correspondingvalidatortoenforcethatconstraintonobjects.

Now, that we have specified JSR 303 constraints on FixedDepositDetails class, let’s look at how tovalidateFixedDepositDetailsobject.

ValidatingobjectsthatuseJSR303annotationsIfaJSR303provider (likeHibernateValidator) is found in theapplication’sclasspath,and youhavespecified<annotation-driven>elementofSpring’smvcschemainthewebapplicationcontextXMLfile,then Spring automatically enables support for JSR 303. Behind the scenes, the <annotation-driven>element configures an instance of Spring’s LocalValidatorFactoryBean class that is responsible fordetectingthepresenceofaJSR303provider(likeHibernateValidator)intheapplication’sclasspathandinitializingit.

LocalValidatorFactoryBean implements JSR 303’s Validator andValidatorFactory interfaces, and alsoSpring’sValidator interface. For this reason, you can choose to validate an object by calling validatemethodofSpring’sValidatorinterfaceorbycallingvalidatemethodofJSR303’sValidator.Asdiscussedearlier, you can also instruct Spring to automatically validate amodel attribute argument passed to a@RequestMappingmethodbysimplyadding@Validannotationonthemodelattributeargument.

Validatingmodelattributesbyexplicitlycallingvalidatemethod

The following example listing shows the FixedDepositController class that uses Spring’sValidator tovalidatetheFixedDepositDetailsobject(referexamplelisting11-27)thatusesJSR303’sconstraints:

Example listing 11-28 – FixedDepositController – validating FixedDepositDetails using SpringValidationAPIProject–ch11-jsr303-validationSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;

Page 409: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

importjavax.validation.Valid;.....publicclassFixedDepositController{.....@AutowiredprivateValidatorvalidator;.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit(@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,BindingResultbindingResult,SessionStatussessionStatus){validator.validate(fixedDepositDetails,bindingResult);if(bindingResult.hasErrors()){.....}.....}.....}

In the above example listing, the LocalValidatorFactoryBean (that implements Spring’s Validatorinterface) is autowired into FixedDepositController’s validator instance variable. In theopenFixedDeposit method, call to Validator’s validate method results in invocation ofLocalValidatorFactoryBean’s validate(Object, Errors) method to validate the FixedDepositDetailsinstance. TheBindingResult object is passed to the validatemethod to hold the validation errors.AnimportantpointtonoticeintheaboveexamplelistingisthattheFixedDepositControllerdoesn’tdirectlydealwithJSR303-specificAPItovalidateFixedDepositDetailsobject.Instead,SpringValidationAPIisusedtovalidateFixedDepositDetailsobject.

ThefollowingexamplelistingshowsanalternateversionofFixedDepositControllerthatusesJSR303-specificAPItovalidateFixedDepositDetailsobject:

Example listing 11-29 – FixedDepositController – validating FixedDepositDetails using JSR 303-specificAPIimportjavax.validation.ConstraintViolation;importjavax.validation.Validator;importjava.util.Set;.....publicclassFixedDepositController{.....@AutowiredprivateValidatorvalidator;.....@RequestMapping(params="fdAction=create",method=RequestMethod.POST)publicStringopenFixedDeposit(

Page 410: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@ModelAttribute(value="newFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,BindingResultbindingResult,SessionStatussessionStatus){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 Validatorinterface) is autowired into FixedDepositController’s validator instance variable. In theopenFixedDeposit method, call to Validator’s validate method results in invocation ofLocalValidatorFactoryBean’s validate(T) method to validate the FixedDepositDetails instance. Thevalidatemethodreturnsajava.util.Setobject thatcontainstheconstraintviolationsreportedbytheJSR303 provider. You can check the java.util.Set object returned by the validate method to find if anyconstraintviolationswerereported.

InvokingmodelattributesvalidationusingJSR303’s@Validannotation

You can instruct Spring to automatically validate a model attribute argument passed to a@RequestMappingmethodbyaddingJSR303’[email protected] example listing shows FixedDepositController’s editFixedDeposit method that uses@ValidannotationtovalidateeditableFixedDepositDetailsmodelattribute:

Examplelisting11-30–FixedDepositController–invokingvalidationusing@ValidannotationProject–ch11-jsr303-validationSourcelocation-src/main/java/sample/spring/chapter11/web

packagesample.spring.chapter11.web;importjavax.validation.Valid;.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=edit",method=RequestMethod.POST)publicStringeditFixedDeposit(@Valid@ModelAttribute("editableFixedDepositDetails")FixedDepositDetailsfixedDepositDetails,BindingResultbindingResult,SessionStatussessionStatus){if(bindingResult.hasErrors()){.....}.....}.....}

Page 411: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Intheaboveexamplelisting,@ValidannotationoneditableFixedDepositDetailsmodelattributeresultsinitsautomaticvalidationbySpring.TheconstraintviolationsreportedduringvalidationareaddedtotheBindingResultobjectalongwithanydatabindingerrors.

Let’snowlookathowSpring’sformtaglibrarysimplifieswritingformsinJSPpages.

Page 412: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

11-6Spring’sformtaglibrarySpring’s form tag library provides tags that simplify creating JSP pages for Spring Web MVCapplications.TheSpring’sformtaglibraryprovidestagstorendervariousinputformelementsandforbindingformdatatoformbackingobjects.

ThefollowingexamplelistingshowsthecreateFixedDepositForm.jspJSPpageofch11-jsr303-validationprojectthatusesSpring’sformtaglibrarytags:

Examplelisting11-31–createFixedDepositForm.jsp–Spring’sformtaglibraryusageProject–ch11-jsr303-validationSourcelocation-src/main/webapp/WEB-INF/jsp

<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%><%@taglibprefix="form"uri="http://www.springframework.org/tags/form"%><html>.....<form:formcommandName="newFixedDepositDetails"name="createFixedDepositForm"method="POST"action="${pageContext.request.contextPath}/fixedDeposit?fdAction=create">.....<tr><tdclass="td"><b>Amount(inUSD):</b></td><tdclass="td"><form:inputpath="depositAmount"/><fontstyle="color:#C11B17;"><form:errorspath="depositAmount"/></font></td></tr><tr><tdclass="td"><b>Maturitydate:</b></td><tdclass="td"><form:inputpath="maturityDate"/><fontstyle="color:#C11B17;"><form:errorspath="maturityDate"/></font></td></tr>.....<tdclass="td"><inputtype="submit"value="Save"/>.....</form:form></html>

In the above example listing, the following taglib directive makes the Spring’s form tag library tagsaccessibletotheJSPpage:

<%@taglibprefix="form"uri="http://www.springframework.org/tags/form"%>

Spring’sformtaglibrary’s<form>tagrendersanHTMLformthatbindsformfieldstothepropertiesofmodel attribute identified by the commandName attribute. The <form> tag contains <input> tags thatcorrespond to thepropertiesof themodelattribute specifiedby thecommandNameattribute.When the

Page 413: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

formisrendered,propertiesarereadfromthemodelattributeanddisplayedby<input>tags.And,whentheformissubmitted,thefieldvaluesintheformareboundtothecorrespondingpropertiesofthemodelattribute.

In example listing 11-31, the <form> tag renders an HTML form for opening a fixed deposit. ThecommandNameattribute’svalueisnewFixedDepositDetails,whichmeansthattheformfieldsaremappedtothepropertiesofthenewFixedDepositDetailsmodelattribute.ThenameattributespecifiesthenameoftheHTMLformrenderedbythe<form>tag.ThemethodattributespecifiestheHTTPmethodtouseforsendingformdatawhentheformissubmitted.TheactionattributespecifiestheURLtowhichtheformdataissentwhentheformissubmitted.TheURLspecifiedbytheactionattributemustmaptoaunique@RequestMappingannotatedmethodinyourSpringWebMVCapplication.Inexamplelisting11-31,theURL ${pageContext.request.contextPath}/fixedDeposit?fdAction=create maps toFixedDepositController’s openFixedDeposit method (refer FixedDepositController.java file of ch11-jsr303-validation project). You should note that the expression ${pageContext.request.contextPath}returnsthecontextpathofthewebapplication.

The<input>tagofSpring’sformtaglibraryrendersanHTML<input>elementwithtypeattributesettotext.Thepathattributespecifiesthepropertyofthemodelattributetowhichthefieldismapped.Whenthe form is rendered, the value of the property is displayed by the input field.And,when the form issubmitted,thevalueofthepropertyissettothevalueenteredbytheuserintheinputfield.

The<errors>tagofSpring’sformtaglibraryshowsdatabindingandvalidationerrormessagesthatwereadded to theBindingResult during data binding and validation. If youwant to display errormessagescorrespondingtoaparticularproperty,specifythenameofthepropertyasthevalueofthepathattribute.Ifyouwant todisplayall theerrormessages stored in theBindingResult object, specifyvalueofpathattributeas*.

ThecreateFixedDepositForm.jsppageusesonlyasubsetofSpring’sformtaglibrarytags.ThefollowingtableshowstheothertagsthatSpring’sformtaglibraryoffers:

Tag Description

<checkbox>

RendersanHTMLcheckbox(thatis,<inputtype="checkbox"/>)

AsthevalueofanHTMLcheckboxisnotsenttotheserverifthecheckboxisunchecked,the<checkbox> tag additionally renders a hidden field corresponding to each checkbox to allowsendingthestateofthecheckboxtotheserver.

Example:<form:checkboxpath="myProperty"/>

Thepathattributespecifiesthenameofthepropertytowhichthecheckboxvalueisbound.

<checkboxes>

RendersmultipleHTMLcheckboxes.

Example:<form:checkboxespath="myPropertyList"items="${someList}"/>

Thepathattributespecifiesthenameofthepropertytowhichtheselectedcheckboxesvaluesarebound.Theitemsattributespecifiesthenameofthemodelattributethatcontainsthelistofoptionstoshowascheckboxes.

<radiobutton>

RendersanHTMLradiobutton(thatis,<inputtype="radio"/>)

Example:<form:radiobuttonpath="myProperty"value="myValue"/>

Thepathattributespecifiesthenameofthepropertytowhichtheradiobuttonisbound,andthevalueattributespecifiesthevalueassignedtotheradiobutton.

<radiobuttons>

RendersmultipleHTMLradiobuttons.

Example:<form:radiobuttonspath="myProperty"items="${myValues}"/>

Theitemsattributespecifiesthelistofoptionstoshowasradiobuttons,andthepathattributespecifiesthepropertytowhichtheselectedradiobuttonsvaluesarebound.

Page 414: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<password> RendersanHTMLpasswordfield(thatis,<inputtype="password"/>)

<select>

RendersanHTML<select>element.

Example:<form:selectpath="book"items="${books}"/>

Theitemsattributespecifies themodelattributeproperty thatcontains the list of options todisplayintheHTML<select>element.Thepathattributespecifiesthepropertytowhichtheselectedoptionisbound.

<option>

RendersanHTML<option>element.

Example:

<form:selectpath="book">

<form:optionvalue="GettingstartedwithSpringFramework"/>

<form:optionvalue="GettingstartedwithSpringWebMVC"/>

</form:select>

<options> RendersmultipleHTML<option>elements.

<textarea> RendersanHTML<textarea>element.

<hidden> RendersanHTMLhiddeninputfield(thatis,<inputtype="hidden"/>)

Let’snowlookatHTML5supportinSpring’sformtaglibrary.

HTML5supportinSpring’sformtaglibraryStartingwithSpring3.0,theformtaglibraryallowsyoutouseHTML5-specificattributesinthetags.Forinstance,thefollowing<textarea>tagusesHTML5’srequiredattribute:

<form:textareapath="myProperty"required="required"/>

Therequired="required" attribute specifies that it ismandatory for theuser to enter information in thetextarea.TheuseofrequiredattributesavestheefforttowritetheJavaScriptcodetoperformclient-sidevalidationformandatoryfields. If theuserdoesn’tenteranyinformationin the textareaandattempts tosubmittheform,thewebbrowsershowsamessagesayingthatthetextareaisrequiredandmustnotbeleftblank.

InHTML5youcanspecifytypeattribute’svalueasemail,datetime,date,month,week,time,range,color,reset,andsoon.StartingwithSpring3.1,<input>tagsupportsspecifyingtypeattributevalueotherthantext.Forinstance,thefollowing<input>tagspecifiestypeattribute’svalueasemail:

<form:inputpath="myProperty"type="email"/>

Whenauserattemptstosubmittheformcontainingafieldoftypeemail,thewebbrowserchecksthattheemail type field contains a valid email address. If the email type field doesn’t contain a valid emailaddress,thewebbrowsershowsamessageindicatingthatthefielddoesn’tcontainavalidemailaddress.Asthewebbrowserperformsthevalidation,youdon’tneedtowritetheJavaScriptcodetovalidatetheemailaddress.

Page 415: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

11-7SummaryWelookedatmanycorefeaturesofSpringWebMVCinthischapter.Welookedat@ModelAttributeand@SessionAttributesannotationswhicharemostcommonlyusedindevelopingannotatedcontrollers.Wealsotookanin-depthlookathowSpringperformsdatabindingandvalidation.Inthenextchapter,we’lllookathowtodevelopRESTfulwebservicesusingSpringWebMVC.

Page 416: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter12–DevelopingRESTfulwebservicesusingSpringWebMVC

Page 417: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

12-1IntroductionRepresentational State Transfer (also referred to as REST) is an architectural-style in which anapplicationdefinesresources thatareuniquely identifiedbyURIs (UniformResource Identifier). Theclients of a REST-style application interact with a resource by sendingHTTPGET, POST, PUT andDELETEmethod requests to theURI towhich the resource ismapped.The following figure shows aREST-styleapplicationthatisaccessedbyitsclients:

Figure12-1REST-styleapplicationdefinesxandyresourcesthatareuniquelyidentifiedby/resource2and/resource1URIs,respectively.

TheabovefigureshowsaREST-styleapplicationthatconsistsoftworesources–xandy.Theresourcexismappedto/resource2URIandtheyresourceismappedto/resource1URI.Aclientcaninteractwithresourcex by sendingHTTP requests to /resource2URI, and can interactwith resource y by sendingHTTPrequeststo/resource1URI.

IfawebservicefollowstheRESTarchitectural-style,itisreferredtoasaRESTfulwebservice.InthecontextofRESTfulwebservices,youcanthinkofaresourceas thedataexposedby thewebservice.TheclientcanperformCRUD(CREATE,READ,UPDATEandDELETE)operationsontheexposeddatabysendingHTTPrequeststotheRESTfulwebservice.TheclientandtheRESTfulwebserviceexchangerepresentation of the data, which could be inXML, JSON (JavaScriptObject Notation) format, or asimplestring,oranyotherMIMEtypesupportedbytheHTTPprotocol.

RESTfulwebservicesaresimpler to implementandaremorescalablecomparedtoSOAP-basedwebservices.InSOAP-basedwebservices,requestsandresponsesarealwaysinXMLformat.InRESTfulwebservices,youcanuseJSON(JavaScriptObjectNotation),XML,plaintext,andsoon,forrequestsandresponses.Inthischapter,we’lllookathowSpringWebMVCsimplifiesdevelopingandaccessingRESTfulwebservices.

Let’sbeginbylookingattherequirementsofaRESTfulwebservicethatwe’llimplementusingSpringWebMVC.

Page 418: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

12-2FixeddepositwebserviceWe saw earlier that theMyBankweb application provides the functionality to display a list of fixeddeposits,andtocreate,editandclosefixeddeposits.Asthefixeddepositrelatedfunctionalitymayalsobeaccessedbyotherapplications,thefixeddepositrelatedfunctionalityneedstobetakenoutfromtheMyBankweb application and deployed as a RESTfulweb service. Let’s call this newRESTfulwebserviceasFixedDepositWS.

ThefollowingfigureshowsthattheFixedDepositWSwebserviceisaccessedbyMyBankandSettlementapplications:

Figure12-2MyBankandSettlementapplicationsaccessFixedDepositWSwebservice

The above figure shows thatMyBank and Settlementweb applications interact with FixedDepositWSweb service by exchanging data in JSON format. We’ll soon see that JSON represents a simpleralternativetoXMLforexchangingdatabetweenapplications.

Let’s now look at how to implement FixedDepositWS web service as a RESTful web service usingSpringWebMVC.

Page 419: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

12-3ImplementingaRESTfulwebserviceusingSpringWebMVCTodevelopaRESTfulwebservice,youneedtodothefollowing:

·identifyresourcesthatareexposedbythewebservice

·specifyURIscorrespondingtotheidentifiedresources

·identifyoperationsthatcanbeperformedontheresources

·mapHTTPmethodstotheidentifiedoperations

IncaseofFixedDepositWSwebservice,fixeddepositdatarepresentstheresourceexposedbythewebservice.IftheFixedDepositWSwebservicemapsfixeddepositsinthesystemto/fixedDepositsURI,aFixedDepositWSwebserviceclientcanperformactionsonfixeddepositsbysendingHTTPrequeststo/fixedDepositsURI.

InRESTfulwebservice, theHTTPmethodusedbyclientsforinteractingwitharesourceindicatestheoperation to be performed on the resource. GET retrieves the resource state, POST creates a newresource, PUT modifies the resource state and DELETE deletes the resource. The following figuresshowstheactionsperformedbytheFixedDepositWSwebservicewhenaclientsendsGET,POST,PUTandDELETEHTTPrequeststothe/fixedDepositsURI:

Figure12-3HTTP requests are sentby theFixedDepositWS’sclient to /fixedDepositsURI to interactwithfixeddepositdata

The above figure shows that the client of FixedDepositWSweb service sendsGET, POST, PUT andDELETEHTTPrequeststo/fixedDepositsURItointeractwiththefixeddepositdata.Theidquerystringparameteruniquely identifiesa fixeddeposit in the system.The following tabledefines thepurposeofeachrequestshownintheabovefigure:

HTTPmethod URI Purpose

GET /fixedDeposits Retrieve details of all the fixed deposits in the system. The FixedDepositWSwebservicesendstheresponseinJSONformat.

GET /fixedDeposits?id=123 Retrievedetailsofthefixeddepositwhoseidis123.TheFixedDepositWSwebservicesendstheresponseinJSONformat.

POST /fixedDeposits Create a new fixed deposit in the system. The web service client sends the

Page 420: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

detailsofthefixeddeposittobecreatedinJSONformat.

PUT /fixedDeposits?id=123 Modifies the fixed depositwhose id is 123. Theweb service client sends themodifieddetailsofthefixeddepositinJSONformat.

DELETE /fixedDeposits?id=123 Removesthefixeddepositwhoseidis123.

Theabove table shows that theFixedDepositWSand its clients exchange information in JSONformat.Beforedelving into thedetailsofhowto implementFixedDepositWS, let’s lookathowthedata lookslikeinJSONformat.

JSON(JavaScriptObjectNotation)JSONisatext-baseddataformatthatisusedbyapplicationsforexchangingstructureddata.AsJSONrepresentationofdataismorecompactcomparedtoXML,JSONservesasasimpleralternativetoXML.To simplify conversion of Java objects to JSON and vice versa, you can use JSON libraries likeFlexJson(http://flexjson.sourceforge.net/)andJackson(https://github.com/FasterXML/jackson).

Let’ssayaPersonclassdefines firstNameand lastNameattributes. Ifyoucreatean instanceofPersonobjectandset firstNametoMyfirstnameand lastNametoMylastname, the representationof thePersonobjectinJSONformatwouldlooklikethis:

Examplelisting12-1–PersonobjectrepresentationinJSONformat{"firstName":Myfirstname,"lastName":"Mylastname"}

TheaboveexamplelistingshowsthateachattributeofPersonobjectisrepresentedas<attribute-name>:<attribute-value>inJSONformat.

YoucanalsorepresentacollectionofJavaobjectsinJSONformat.ThefollowingexamplelistingshowshowyoucanrepresentacollectionofPersonobjectsinJSONformat:

Examplelisting12-2–CollectionofPersonobjectsrepresentedinJSONformat[{"firstName":Myfirstname,"lastName":"Mylastname"},{"firstName":Yourfirstname,"lastName":"Yourlastname"}]Youdon’tneedtowritecodetoconvertanobjectintoJSONrepresentationandviceversa.Instead,theRESTfulwebserviceanditsclientscanmakeuseofFlexJsonorJacksonlibrarytoperformconversion.

Page 421: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Aswe’llsoonsee,SpringWebMVCusesJacksonforconvertingJSONtoJavaobjectsandviceversa.

Let’snowlookattheimplementationofFixedDepositWSwebserviceusingSpringWebMVC.

IMPORT chapter 12/ch12-webservice (This project shows the implementation of FixedDepositWSRESTfulwebserviceusingSpringWebMVC.Laterinthischapter,we’llseehowFixedDepositWSwebserviceisaccessedbyitsclients.)

FixedDepositWSwebserviceimplementationSpringWebMVC annotations, like@Controller,@RequestMapping,@RequestParam, @PathVariable@ResponseBody,@RequestBody, and so on, support buildingRESTfulweb services. In this section,we’lllookatusageofsomeoftheseannotationsindevelopingtheFixedDepositWSwebservice.

In FixedDepositWS web service, the FixedDepositController (a Spring Web MVC controller) isresponsible for handling web service requests. FixedDepositController is like any other SpringWebMVCcontrollerwiththeexceptionthatits@RequestMappingmethodsdon’trenderviews.Thefollowingexamplelistingshowsthat@Controllerand@RequestMappingannotationsareusedtomapwebrequeststoappropriatemethodsofFixedDepositControllerclass:

Examplelisting12-3–FixedDepositController–webservicerequesthandlerProject–ch12-webserviceSourcelocation-src/main/java/sample/spring/chapter12/web

packagesample.spring.chapter12.web;importorg.springframework.http.ResponseEntity;.....@Controller@RequestMapping(value="/fixedDeposits")publicclassFixedDepositController{.....@RequestMapping(method=RequestMethod.GET)publicResponseEntity<List<FixedDepositDetails>>getFixedDepositList(){.....}@RequestMapping(method=RequestMethod.GET,params="id") publicResponseEntity<FixedDepositDetails> getFixedDeposit(@RequestParam("id") int id) {.....}.....}

ThegetFixedDepositListmethodreturnsthelistoffixeddepositsinthesystem,andthegetFixedDepositmethodreturnsdetailsofthefixeddepositidentifiedbytheidargument.Theaboveexamplelistingshowsthat the @RequestMapping annotation is used at the class- and method-level to map requests togetFixedDepositListandgetFixedDepositmethods.ThegetFixedDepositListmethod is invokedwhenaclientapplicationsendsanHTTPGETrequestto/fixedDepositsURI,andthegetFixedDepositmethodisinvoked 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

Page 422: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

invoked.

ThefollowingtablesummarizesthemappingofrequestURIsandHTTPmethodstothemethodsdefinedintheFixedDepositControllerclass:

HTTPmethod URI FixedDepositControllermethod

GET /fixedDeposits getFixedDepositList

GET /fixedDeposits?id=123 getFixedDeposit

POST /fixedDeposits openFixedDeposit

PUT /fixedDeposits?id=123 editFixedDeposit

DELETE /fixedDeposits?id=123 closeFixedDeposit

Wesawinchapter10and11that@RequestMappingannotatedmethodsreturnviewinformationthat isused by the DispatcherServlet to render a view (like JSP or servlet). In RESTful web services,@RequestMappingmethodsreturndata(andnottheviewinformation)totheclientapplications.Forthisreason,thegetFixedDepositListandgetFixedDepositmethodshavebeendefinedtoreturnobjectsoftypeResponseEntity. Let’s now look at the usage of ResponseEntity object in the FixedDepositControllerclass.

SpecifyingHTTPresponseusingResponseEntity

ResponseEntityrepresentsanHTTPresponseconsistingofheaders,bodyandstatuscode.TheobjectthatyousetasbodyontheResponseEntityobjectiswrittentotheHTTPresponsebodybySpringWebMVC.

The following example listing shows how the ResponseEntity object is created byFixedDepositController’sgetFixedDepositListmethod:

Examplelisting12-4–FixedDepositController–creatingResponseEntityinstanceProject–ch12-webserviceSourcelocation-src/main/java/sample/spring/chapter12/web

packagesample.spring.chapter12.web;importorg.springframework.http.HttpStatus;importorg.springframework.http.ResponseEntity;.....publicclassFixedDepositController{.....@RequestMapping(method=RequestMethod.GET)publicResponseEntity<List<FixedDepositDetails>>getFixedDepositList(){.....returnnewResponseEntity<List<FixedDepositDetails>>(fixedDepositService.getFixedDeposits(),HttpStatus.OK);}.....}

Intheaboveexamplelisting,thefixeddepositlistpassedtotheResponseEntityconstructoriswrittento

Page 423: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

theHTTPresponsebody.TheHttpStatusisanenumtypethatdefinesHTTPstatuscodes.TheconstantOKrefers to the HTTP status code 200. Notice that the return type of the getFixedDepositList method isResponseEntity<List<FixedDepositDetails>>, which means that an object of typeList<FixedDepositDetails>iswrittentotheHTTPresponsebody.SpringWebMVCusesanappropriateHttpMessageConverter(explainedinsection12-5)toconverttheList<FixedDepositDetails>objectintotheformatexpectedbytheclientapplication.

NOTELaterinthischapter,we’llseethatclientapplicationscanuseSpring’sRestTemplate to invokemethodsdefinedintheFixedDepositControllerandtoretrievetheobjectswrittentotheHTTPresponsebody.

Allthe@RequestMappingannotatedmethodsofFixedDepositControllerclassdefineResponseEntityastheir return type. If you don’t need to send HTTP status code in the response, you can use Spring’sHttpEntity class instead of ResponseEntity. HttpEntity represents an HTTP request or response, andResponseEntityisasubclassofHttpEntitythataddsanHTTPstatuscodetotheresponse.

ThefollowingexamplelistingshowsamodifiedversionofgetFixedDepositListmethodthatcreatesandreturnsaninstanceofHttpEntity:

Examplelisting12-5–FixedDepositController–usingHttpEntityinsteadofResponseEntityimportorg.springframework.http.HttpStatus;importorg.springframework.http.HttpEntity;.....publicclassFixedDepositController{.....@RequestMapping(method=RequestMethod.GET)publicHttpEntity<List<FixedDepositDetails>>getFixedDepositList(){.....returnnewHttpEntity<List<FixedDepositDetails>>(fixedDepositService.getFixedDeposits());}.....}

TheaboveexamplelistingshowsthatthefixeddepositsfoundinthesystemarepassedtotheHttpEntityconstructor. As in case of ResponseEntity (refer example listing 12-4), fixed deposits passed to theHttpEntityarewrittentotheHTTPresponsebody.

BothHttpEntity and ResponseEntity objects allow you to set HTTP response headers. The followingexamplelistingshowsascenarioinwhichsome-headerheaderissetontheHTTPresponse:

Examplelisting12-6–HttpHeadersusageimportorg.springframework.http.HttpHeaders;.....@RequestMapping(method=RequestMethod.GET)publicHttpEntity<String>doSomething(){HttpHeadersresponseHeaders=newHttpHeaders();

Page 424: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

responseHeaders.set("some-header","some-value");returnnewHttpEntity<String>("Helloworld!",responseHeaders);}.....

Spring’sHttpHeadersobjectcontainstheheadersthataresetontheHTTPresponse.Intheaboveexamplelisting,HttpHeader’ssetmethodsetssome-header responseheader (withvalue some-value).When thedoSomethingmethod is invoked, the ‘Helloworld!’ string iswritten to the response body, and some-headerheaderiswrittentotheHTTPresponse.

As@RequestMappingmethodscanbedefined toacceptHttpServletResponseobjectasargument, let’slookathowyoucandirectlysetresponsebodyandheadersontheHttpServletResponseobject.

SpecifyingHTTPresponseusingHttpServletResponse

The following example listing shows a @RequestMapping method which writes directly to theHttpServletResponseobject:

Examplelisting12-7–SettingresponseonHttpServletResponseimportjavax.servlet.http.HttpServletResponse;.....@RequestMapping(method=RequestMethod.GET)publicvoiddoSomething(HttpServletResponseresponse)throwsIOException{response.setHeader("some-header","some-value");response.setStatus(200);response.getWriter().write("Helloworld!");}.....

Instead of directly writing response to HttpServletResponse, you should use ResponseEntity (orHttpEntity)objecttoimprovethetestabilityofthecontrollers.

Let’snowlookatSpring’s@ResponseBodymethod-levelannotation thatwrites thereturnvalueof themethodtoHTTPresponsebody.

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 @RequestMappingmethodsofthecontroller.

BindingreturnedvalueofamethodtoHTTPresponsebodyusing@ResponseBody

Thefollowingexamplelistingshowsusageof@ResponseBodyannotation:

Examplelisting12-8–@ResponseBodyannotationusageimportorg.springframework.web.bind.annotation.ResponseBody;

Page 425: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....@RequestMapping(method=RequestMethod.GET)@ResponseBodypublicStringdoSomething(){return"Helloworld!";}.....

In the above example listing, the ‘Helloworld !’ string value returned by the doSomethingmethod iswrittentotheHTTPresponsebody.Insection10-7ofchapter10,wediscussedthatifthereturntypeofa@RequestMappingannotatedmethod isString, the returnedvalue is treatedas thenameof theview torender.Intheaboveexamplelisting,the@ResponseBodyannotationonthedoSomethingmethodinstructsSpringWebMVCtowritethestringvaluetotheHTTPresponsebodyinsteadoftreatingthestringvalueastheviewname.YoushouldnotethatSpringusesanappropriateHttpMessageConverter(explainedinsection12-5)implementationtowritethevaluereturnedbythe@ResponseBodyannotatedmethodtotheHTTPresponsebody.

Now, thatwe have seen differentways inwhich a@RequestMappingmethod canwrite to theHTTPresponse, let’s look at how a@RequestMappingmethod can read information from theHTTP requestbodyusing@RequestBodyannotation.

BindingHTTPrequestbodytoamethodparameterusing@RequestBody

A@RequestMapping annotated method can use@RequestBody method-parameter level annotation tobind HTTP request body to the method parameter. Spring Web MVC uses an appropriateHttpMessageConverter(explainedinsection12-5)implementationtoconverttheHTTPrequestbodytothemethodparametertype.Thefollowingexamplelistingshowsusageof@RequestBodyannotation inMyBankapplication’sFixedDepositController:

Examplelisting12-9–@RequestBodyannotationusageProject–ch12-webserviceSourcelocation-src/main/java/sample/spring/chapter12/web

packagesample.spring.chapter12.web;.....importorg.springframework.web.bind.annotation.RequestBody;.....@Controller@RequestMapping(value="/fixedDeposits")publicclassFixedDepositController{.....@RequestMapping(method=RequestMethod.POST)publicResponseEntity<FixedDepositDetails>openFixedDeposit(@RequestBodyFixedDepositDetailsfixedDepositDetails,BindingResultbindingResult){newFixedDepositDetailsValidator().validate(fixedDepositDetails,bindingResult);.....

Page 426: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

}.....}

In the above example listing, the FixedDepositDetails type method argument is annotated with@RequestBody annotation. SpringWebMVC is responsible for converting theHTTP request body toFixedDepositDetailstypeobject.Intheaboveexamplelisting,FixedDepositDetailsValidatorclassisanimplementation of Spring’s Validator interface that validates the FixedDepositDetails object beforeattemptingtocreatethefixeddeposit.

An alternative to using @RequestBody annotation is to directly read HTTP request body from theHttpServletRequestobjectandconverttherequestbodycontenttotheJavatyperequiredbythemethod.Spring’s @RequestBody annotation simplifies the conversion because it uses an appropriateHttpMessageConverterimplementationtoconvertHTTPrequestbodytotheobjecttypeexpectedbythe@RequestMappingmethod.

Let’snowlookatthe@ResponseStatusannotationthatallowsyoutosetHTTPresponsestatus.

SettingHTTPresponsestatususing@ResponseStatus

You can use the @ResponseStatus annotation to specify the HTTP response status returned by [email protected]@ResponseStatusannotation:

Examplelisting12-10–@ResponseStatusannotationusageimportorg.springframework.web.bind.annotation.ResponseStatus;publicclassSomeController{@RequestMapping(method=RequestMethod.GET)@ResponseStatus(value=HttpStatus.OK)@ResponseBodypublicSomeObjectdoSomething(){.....}}

AsthedoSomethingmethodisannotatedwith@ResponseBodyannotation, theSomeObject returnedbythedoSomethingmethodiswrittentotheHTTPresponsebody.And,the@ResponseStatusannotationsetstheHTTPresponsestatuscodeto200(representedbyHttpStatus.OKconstant).

Let’s now look at how the@ExceptionHandler annotation is used in FixedDepositWSweb service tohandleexceptions.

Handlingexceptionsusing@ExceptionHandler

In section 10-9 of chapter 10, we saw that the@ExceptionHandler annotation identifies a controllermethod that is responsible for handling exceptions. Like @RequestMapping methods,@ExceptionHandlermethodsinRESTfulwebservicesareannotatedwith@ResponseBodyannotationor

Page 427: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

thereturntypeisdefinedasResponseEntity(orHttpEntity).

Thefollowingexamplelistingshowsusageof@ExceptionHandlerannotationinFixedDepositControllerclassofch12-webserviceproject:

Examplelisting12-11–@ExceptionHandlerannotationusageProject–ch12-webserviceSourcelocation-src/main/java/sample/spring/chapter12/web

packagesample.spring.chapter12.web;importsample.spring.chapter12.exception.ValidationException;.....publicclassFixedDepositController{.....@ExceptionHandler(ValidationException.class)@ResponseBody@ResponseStatus(value=HttpStatus.BAD_REQUEST)publicStringhandleException(Exceptionex){logger.info("handlingValidationException"+ex.getMessage());returnex.getMessage();}}

@ExceptionHandlerannotationonhandleExceptionmethodindicatesthatthehandleExceptionmethodisinvokedwhenValidationException is thrownby theFixedDepositController during request processing.As the handleException method is also annotated with @ResponseBody annotation, the exceptionmessagereturnedbythehandleExceptionmethodiswrittentotheHTTPresponsebody.@ResponseStatusonthehandleExceptionmethodresults insettingtheHTTPresponsestatuscodeto400(representedbyHttpStatus.BAD_REQUESTconstant).

Inthissection,wesawhowtoimplementFixedDepositWSwebserviceusingSpringWebMVC.Let’snowlookathowtoaccessFixedDepositWSwebserviceusingSpring’sRestTemplate.

Page 428: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

12-4AccessingRESTfulwebservicesusingRestTemplateSpring’s RestTemplate class simplifies accessing RESTful web services by taking care of managingHTTPconnectionsandhandlingHTTPerrors.

IMPORT chapter 12/ch12-webservice-client (This project represents a standalone Java applicationthat accesses FixedDepositWSRESTfulweb service using Spring’s RestTemplate (for synchronouslyaccessing the web service) and AsyncRestTemplate (for asynchronously accessing the web service)class. The ch12-webservice-client project assumes that the ch12-webservice project representing theFixedDepositWSRESTfulwebserviceisdeployedathttp://localhost:8080/ch12-webserviceURL.)

RestTemplateconfiguration

ThefollowingexamplelistingshowshowRestTemplateisconfiguredintheapplicationcontextXMLfileofch12-webservice-clientproject:

Examplelisting12-12–applicationContext.xml-RestTemplateconfigurationProject–ch12-webservice-clientSourcelocation-src/main/resources/META-INF/spring

<beans.....><beanid="restTemplate"class="org.springframework.web.client.RestTemplate"><propertyname="errorHandler"ref="errorHandler"/></bean><beanid="errorHandler"class="sample.spring.chapter12.MyErrorHandler"/>.....</beans>

RestTemplate’s errorHandler property refers to an implementation of Spring’s ResponseErrorHandlerinterface that inspects the HTTP response for errors and handles the response in case of errors.DefaultResponseErrorHandler is the default implementation of ResponseErrorHandler interface that isprovided out-of-the-box by Spring. If you don’t specify the errorHandler property, Spring uses theDefaultResponseErrorHandler implementation.The above example listing shows that theRestTemplateusesacustomresponseerrorhandler,MyErrorHandler.

ThefollowingexamplelistingshowstheimplementationofMyErrorHandlerclass:

Examplelisting12-13–MyErrorHandlerclass–HTTPresponseerrorhandlerProject–ch12-webservice-clientSourcelocation-src/main/java/sample/spring/chapter12

packagesample.spring.chapter12;importorg.apache.commons.io.IOUtils;importorg.springframework.http.client.ClientHttpResponse;importorg.springframework.web.client.DefaultResponseErrorHandler;

Page 429: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicclassMyErrorHandlerextendsDefaultResponseErrorHandler{privatestaticLoggerlogger=Logger.getLogger(MyErrorHandler.class);@OverridepublicvoidhandleError(ClientHttpResponseresponse)throwsIOException{logger.info("Statuscodereceivedfromthewebservice:"+response.getStatusCode());Stringbody=IOUtils.toString(response.getBody());logger.info("Responsebody:"+body);super.handleError(response);}}

Theaboveexample listingshowsthat theMyErrorHandlerclassextendsDefaultResponseErrorHandlerclassandoverrides thehandleErrormethod. If theHTTPresponse’s statuscode indicatesanerror, thehandleErrormethod is responsible for handling the response.TheClientHttpResponse argument to thehandleErrormethodrepresentstheHTTPresponsereceivedfromcallingtheRESTfulwebservice.Thecall to ClientHttpResponse’s getBody method returns the body of HTTP response as an InputStreamobject.MyErrorHandler’shandleErrormethodlogsinformationaboutthestatuscodeandthebodyoftheHTTP response, and delegates handling of the error to DefaultResponseErrorHandler’s handleErrormethod.The above example listing shows that theMyErrorHandler class usesApacheCommons IO’sIOUtilsclasstogetthecontentoftheHTTPresponsebodyasaString.

Now,thatwehaveseenhowaRestTemplateclassisconfigured,let’slookathowRestTemplateisusedbyclientapplicationstoaccessRESTfulwebservices.

AccessingFixedDepositWSwebserviceusingRestTemplate

ThefollowingexamplelistingshowstheFixedDepositWSClientclassthatusesRestTemplate toaccessFixedDepositWSwebservice:

Examplelisting12-14–FixedDepositWSClientclass–RestTemplateusageProject–ch12-webservice-clientSourcelocation-src/main/java/sample/spring/chapter12

packagesample.spring.chapter12;.....importorg.springframework.web.client.RestTemplate;publicclassFixedDepositWSClient{privatestaticApplicationContextcontext;publicstaticvoidmain(Stringargs[]){context=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");

Page 430: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

getFixedDepositList(context.getBean(RestTemplate.class));getFixedDeposit(context.getBean(RestTemplate.class));.....}privatestaticvoidgetFixedDepositList(RestTemplaterestTemplate){.....}.....}

TheaboveexamplelistingshowsthattheFixedDepositWSClient’smainmethodperformsthefollowingactions:

§bootstrapstheSpringcontainer(representedbytheApplicationContextobject)

§callsgetFixedDepositList,getFixedDeposit,andsoon,methods.ThesemethodsacceptaninstanceofRestTemplate,andareresponsibleforcallingtheFixedDepositWSwebservice.

ThefollowingexamplelistingshowstheimplementationofFixedDepositWSClient’sgetFixedDepositListmethodthatcallstheFixedDepositWSwebservicedeployedathttp://localhost:8080/ch12-webservicetoobtainthelistoffixeddepositsinthesystem:

Examplelisting12-15–FixedDepositWSClient’sgetFixedDepositListmethodProject–ch12-webservice-clientSourcelocation-src/main/java/sample/spring/chapter12

packagesample.spring.chapter12;.....importorg.springframework.core.ParameterizedTypeReference;importorg.springframework.http.*;importorg.springframework.web.client.RestTemplate;publicclassFixedDepositWSClient{.....privatestaticvoidgetFixedDepositList(RestTemplaterestTemplate){HttpHeadersheaders=newHttpHeaders();headers.add("Accept","application/json");HttpEntity<String>requestEntity=newHttpEntity<String>(headers);ParameterizedTypeReference<List<FixedDepositDetails>>typeRef=newParameterizedTypeReference<List<FixedDepositDetails>>(){};ResponseEntity<List<FixedDepositDetails>>responseEntity=restTemplate

Page 431: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.exchange("http://localhost:8080/ch12-webservice/fixedDeposits",HttpMethod.GET,requestEntity,typeRef);List<FixedDepositDetails>fixedDepositDetails=responseEntity.getBody();logger.info("Listoffixeddepositdetails:\n"+fixedDepositDetails);}.....}

Intheaboveexamplelisting,RestTemplate’sexchangemethodhasbeenusedtosendHTTPGETrequestto http://localhost:8080/ch12-webservice/fixedDeposits URL. As the FixedDepositWS web service isdeployed at http://localhost:8080/ch12-webservice URL, sending HTTP GET request tohttp://localhost:8080/ch12-webservice/fixedDeposits URL results in invocation ofFixedDepositController’s getFixedDepositList method. This is because the FixedDepositController’sgetFixedDepositList method is mapped to /fixedDeposits URI (refer example listing 12-3 orFixedDepositControllerclassofch12-webserviceproject).

In example listing 12-15, the HttpEntity object represents the request sent to the web service, theHttpHeadersobject represents the request headers in the request, and theParameterizedTypeReferenceobject represents thegeneric typeof the response received from theweb service.TheAccept requestheader’s value has been set to application/json to specify that the response from the FixedDepositWSwebserviceisexpectedinJSONformat.Onthewebservice-side,thevalueofAcceptheaderisusedbySpringWebMVCtochooseanappropriateHttpMessageConverter toconvert thevaluereturnedby the@ResponseBodyannotatedmethod into the format specifiedby theAccept header. For instance, if theAccept header value is application/json, Spring Web MVC usesMappingJackson2HttpMessageConverter (an implementation of HttpMessageConverter) to convert thevaluereturnedbythe@ResponseBodyannotatedmethodintoJSONformat.TheFixedDepositWSClientspecifies the value of Accept header as application/json; therefore, the value returned byFixedDepositController’sgetFixedDepositListmethodisconvertedtoJSONformat.

The RestTemplate’s exchange method returns an instance of ResponseEntity which represents theresponsereturnedby thewebservice.As thegeneric typeof theresponsereceivedfrominvocationofFixedDepositController’s getFixedDepositList is List<FixedDepositDetails>, an instance ofParameterizedTypeReference<List<FixedDepositDetails>>iscreatedandpassedtotheexchangemethod.YoucancallResponseEntity’sgetBodymethodtoretrievetheresponsereturnedbythewebservice.Inexample listing 12-15, ResponseEntity’s getBody method returns an object of typeList<FixedDepositDetails>thatrepresentsthelistoffixeddepositsreturnedbytheFixedDepositWSwebservice.

The following figure shows the role played by MappingJackson2HttpMessageConverter whenFixedDepositWSClientinvokesFixedDepositController’sgetFixedDepositListmethod:

Page 432: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure 12-4 FixedDepositWSClient’s getFixedDepositList method uses RestTemplate to send a webrequesttoFixedDepositWSwebservice

TheabovefigureshowsthatMappingJackson2HttpMessageConverterisusedtoconvertthereturnvalueof FixedDepositController’s getFixedDepositList method into JSON format. Also,MappingJackson2HttpMessageConverter is used by the RestTemplate to convert the JSON responsereceivedfromtheFixedDepositControllertoaJavaobjectoftypeList<FixedDepositDetails>.

Inexample listing12-15,RestTemplate’sexchangemethodwasused to sendanHTTPGET request toFixedDepositWSwebservice.TheexchangemethodistypicallyusediftheHTTPresponsefromthewebserviceneedstobeconvertedtoaJavagenerictype,andtosendHTTPrequestheaders.RestTemplatealsodefinesHTTPmethod-specificmethodsthatsimplifywritingRESTfulclients.Forinstance,youcanusegetForEntitymethodtosendHTTPGETrequest,postForEntitytosendHTTPPOSTrequest,deletetosendHTTPDELETErequest,andsoon.

The followingexample listing showsFixedDepositWSClient’sopenFixedDepositmethod that sends anHTTPPOSTrequesttoFixedDepositWSwebservicetocreateanewfixeddeposit:

Examplelisting12-16–FixedDepositWSClient’sopenFixedDepositmethodProject–ch12-webservice-clientSourcelocation-src/main/java/sample/spring/chapter12

packagesample.spring.chapter12;importorg.springframework.http.ResponseEntity;importorg.springframework.web.client.RestTemplate;.....publicclassFixedDepositWSClient{.....privatestaticvoidopenFixedDeposit(RestTemplaterestTemplate){FixedDepositDetailsfdd=newFixedDepositDetails();fdd.setDepositAmount("9999");.....

Page 433: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

ResponseEntity<FixedDepositDetails>responseEntity=restTemplate.postForEntity("http://localhost:8080/ch12-webservice/fixedDeposits",fdd,FixedDepositDetails.class);FixedDepositDetailsfixedDepositDetails=responseEntity.getBody();.....}}

FixedDepositWSClient’sopenFixedDepositmethodsendsdetailsofthefixeddeposittobecreatedtotheFixedDepositWSwebservice. If the fixeddeposit iscreatedsuccessfully,FixedDepositWSreturns thenewly created FixedDepositDetails object containing the unique identifier assigned to it. The aboveexamplelistingshowsthatRestTemplate’spostForEntitymethodacceptswebserviceURL,objecttobePOSTed (which is FixedDepositDetails object), and the HTTP response type (which isFixedDepositDetails.class). Sending HTTP POST request to http://localhost:8080/ch12-webservice/fixedDeposits URL results in invocation of FixedDepositController’s openFixedDepositmethod(referexamplelisting12-9orFixedDepositControllerclassofch12-webserviceproject).

FixedDepositController’s openFixedDeposit method validates details of the fixed deposit beforeattempting to create the fixed deposit. FixedDepositDetailsValidator is responsible for validating thefixeddepositdetails.Ifthefixeddepositamountislessthan1000ortenureislessthan12monthsoriftheemail id specified is not well-formed, an exception is thrown by the openFixedDeposit method. Thefollowing example listing shows openFixedDeposit and handleException methods ofFixedDepositController:

Examplelisting12-17–openFixedDepositandhandleExceptionmethodsofFixedDepositControllerProject–ch12-webserviceSourcelocation-src/main/java/sample/spring/chapter12/web

packagesample.spring.chapter12.web;importorg.springframework.validation.BindingResult;importorg.springframework.web.bind.annotation.ExceptionHandler;importsample.spring.chapter12.exception.ValidationException;.....@Controller@RequestMapping(value="/fixedDeposits")publicclassFixedDepositController{.....@RequestMapping(method=RequestMethod.POST)publicResponseEntity<FixedDepositDetails>openFixedDeposit(@RequestBodyFixedDepositDetailsfixedDepositDetails,BindingResultbindingResult){newFixedDepositDetailsValidator().validate(fixedDepositDetails,bindingResult);

Page 434: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

if(bindingResult.hasErrors()){thrownewValidationException("Validationerrorsoccurred");}else{fixedDepositService.saveFixedDeposit(fixedDepositDetails);.....}@ExceptionHandler(ValidationException.class)@ResponseBody@ResponseStatus(value=HttpStatus.BAD_REQUEST)publicStringhandleException(Exceptionex){returnex.getMessage();}}.....}TheaboveexamplelistingshowsthattheopenFixedDepositmethodthrowsValidationExceptioniffixeddeposit fails validation. As the handleException method is annotated with@ExceptionHandler(ValidationException.class), the ValidationException thrown by theopenFixedDeposit method is handled by the handleException method. @ResponseBody and@ResponseStatus(value=HttpStatus.BAD_REQUEST) annotations specify that the exception messagereturned by the handleExceptionmethod is written to the response body and the status code is set toHttpStatus.BAD_REQUESTconstant(whichcorrespondstoHTTPstatuscode400).

FixedDepositWSClient’sopenInvalidFixedDepositmethodattemptstocreateafixeddepositwithdepositamount100,asshownhere:

Examplelisting12-18–FixedDepositWSClient-openInvalidFixedDepositmethodProject–ch12-webservice-clientSourcelocation-src/main/java/sample/spring/chapter12

privatestaticvoidopenInvalidFixedDeposit(RestTemplaterestTemplate){FixedDepositDetailsfdd=newFixedDepositDetails();fdd.setDepositAmount("100");fdd.setEmail("[email protected]");fdd.setTenure("12");ResponseEntity<FixedDepositDetails>responseEntity=restTemplate.postForEntity("http://localhost:8080/ch12-webservice/fixedDeposits",fdd,FixedDepositDetails.class);FixedDepositDetailsfixedDepositDetails=responseEntity.getBody();logger.info("Detailsofthenewlycreatedfixeddeposit:"+fixedDepositDetails);}

Page 435: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

The openInvalidFixedDeposit method uses RestTemplate to send request to FixedDepositController’sopenFixedDepositmethod.As the fixed deposit amount is specified as 100, FixedDepositController’sopenFixedDeposit method throws ValidationException (refer example listing 12-17).FixedDepositController’s handleException method (refer example listing 12-17) handles theValidationExceptionandsetstheHTTPresponsestatusto400.AstheresponsestatuscodereceivedbyRestTemplateis400,thehandlingofresponseisdelegatedtotheMyErrorHandlerimplementation(referexamplelisting12-12and12-13)thatweconfiguredfortheRestTemplate.

RestTemplateallowsclients tosynchronouslyaccessRESTfulwebservices.Let’snowlookathowtoasynchronouslyaccessRESTfulwebservicesusingSpring’sAsyncRestTemplate.

AsynchronouslyaccessingRESTfulwebservicesusingAsyncRestTemplate

ToallowclientstoasynchronouslyaccessRESTfulwebservices,SpringprovidesAsyncRestTemplate.The following example listing shows howAsyncRestTemplate is configured in the application contextXMLfileofch12-webservice-clientproject:

Examplelisting12-19–applicationContext.xml-AsyncRestTemplateconfigurationProject–ch12-webservice-clientSourcelocation-src/main/resources/META-INF/spring

<beans.....>.....<beanid="errorHandler"class="sample.spring.chapter12.MyErrorHandler"/><beanid="asyncRestTemplate"class="org.springframework.web.client.AsyncRestTemplate"><propertyname="errorHandler"ref="errorHandler"/></bean></beans>

If you compare the above example listing with the example listing 12-12, you’ll notice that bothAsyncRestTemplate and RestTemplate classes are configured in the same way; they use the sameMyErrorHandlerinstanceforhandlingHTTPerrors.

AsyncRestTemplate classdefinesmethods that are similar to themethodsdefinedby theRestTemplateclass. The following example listing shows the FixedDepositWSAsyncClient class that usesAsyncRestTemplatetoaccessFixedDepositWSwebservice:

Examplelisting12-20–FixedDepositWSAsyncClient-openFixedDepositmethodProject–ch12-webservice-clientSourcelocation-src/main/java/sample/spring/chapter12

packagesample.spring.chapter12;importorg.springframework.http.HttpEntity;importorg.springframework.util.concurrent.ListenableFuture;importorg.springframework.util.concurrent.ListenableFutureCallback;importorg.springframework.web.client.AsyncRestTemplate;

Page 436: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicclassFixedDepositWSAsyncClient{privatestaticApplicationContextcontext;publicstaticvoidmain(Stringargs[]){context=newClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");.....openFixedDeposit(context.getBean(AsyncRestTemplate.class));}privatestaticvoidopenFixedDeposit(AsyncRestTemplaterestTemplate){FixedDepositDetailsfdd=newFixedDepositDetails();fdd.setDepositAmount("9999");.....HttpEntity<FixedDepositDetails>requestEntity=newHttpEntity<FixedDepositDetails>(fdd);ListenableFuture<ResponseEntity<FixedDepositDetails>>futureResponseEntity=restTemplate.postForEntity("http://localhost:8080/ch12-webservice/fixedDeposits",requestEntity,FixedDepositDetails.class);futureResponseEntity.addCallback(newListenableFutureCallback<ResponseEntity<FixedDepositDetails>>(){@OverridepublicvoidonSuccess(ResponseEntity<FixedDepositDetails>entity){FixedDepositDetailsfixedDepositDetails=entity.getBody();}@OverridepublicvoidonFailure(Throwablet){}});}}TheaboveexamplelistingshowsthattheopenFixedDepositmethodusesAsyncRestTemplate tosendarequest to FixedDepositWSweb service. AsyncRestTemplate’s postForEntity method sends an HTTPPOSTrequesttoFixedDepositWSwebservicethatinvokesFixedDepositController’sopenFixedDepositmethod. If you compare the AsyncRestTemplate’s postForEntity method shown above with that ofRestTemplate’s postForEntity method (refer example listing 12-16), you’ll notice that theAsyncRestTemplate’s postForEntity returns an object of type ListenableFuture (that extendsjava.util.concurrent.Future interface). ListenableFuture’s addCallback method is used to register acallback that is triggered when the ListenableFuture task completes. ListenableFuture’s addCallbackmethod accepts an argument of type ListenableFutureCallback that defines onSuccess and onFailuremethods.TheonSuccessmethodiscalledwhentheListenableFuturetaskcompletessuccessfully,andtheonFailuremethodiscalledwhentheListenableFuturetaskfailstocomplete.

YoushouldnotethatbydefaultAsyncRestTemplateusesaSimpleAsyncTaskExecutor toasynchronously

Page 437: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

executeeachrequestinanewthread.YoucanpassaThreadPoolTaskExecutortoAsyncRestTemplate’sconstructor toasynchronously execute tasksusinga thread froma threadpool.Refer to section 8-6 ofchapter8tolearnmoreaboutSimpleAsyncTaskExecutorandThreadPoolTaskExecutor.

Let’snowlookatthepurposeservedbyHttpMessageConvertersinSpringWebMVC.

Page 438: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

12-5 Converting Java objects to HTTP requests and responses andviceversausingHttpMessageConverterHttpMessageConvertersareusedbySpringinthefollowingscenariostoperformconversion:

§ifamethodargument isannotatedwith@RequestBodyannotation,SpringconvertsHTTPrequestbodytotheJavatypeofthemethodargument

§ifamethodisannotatedwith@ResponseBodyannotation,SpringconvertsthereturnedJavaobjectfromthemethodtoHTTPresponsebody

§ifthereturntypeofamethodisHttpEntityorResponseEntity,SpringconvertstheobjectreturnedbythemethodtotheHTTPresponsebody

§objectspassedtoandreturnedfromthemethodsofRestTemplateandAsyncRestTemplateclasseslikegetForEntity,postForEntity,exchange, and so on, are converted toHTTP requests and fromHTTPresponsesbySpring

ThefollowingtabledescribessomeoftheHttpMessageConverterimplementationsthatareprovidedout-of-the-boxbySpringWebMVC:

HttpMessageConverterimplementation Description

StringHttpMessageConverter

convertsto/fromstrings

FormHttpMessageConverterconvertsformdatato/fromMultiValueMap<String,String> type.ThisHttpMessageConverterisusedbySpringwhendealingwithformdataandfileuploads.

MappingJackson2HttpMessageConverter convertsto/fromJSON

MarshallingHttpMessageConverter convertsto/fromXML

HttpMessageConverters mentioned in the above table are automatically registered with the Springcontainer by the <annotation-driven> element of Spring’s mvc schema. To view the complete list ofHttpMessageConvertersthatareregisteredbydefaultby<annotation-driven>element,refertotheSpringFrameworkreferencedocumentation.

Let’s now look at @PathVariable and @MatrixVariable annotations that further simplify developingRESTfulwebservicesusingSpringWebMVC.

Page 439: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

12-6@PathVariableand@MatrixVariableannotationsInstead of specifying the actual URI, a@RequestMapping annotation may specify aURI template toaccess specific parts of the request URI. A URI template contains variable names (specified withinbraces) whose values are derived from the actual request URI. For example, the URI templatehttp://www.somebank.com/fd/{fixeddeposit} contains the variable name fixeddeposit. If the requestactual request URI is http://www.somebank.com/fd/123, the value of {fixeddeposit} URI templatevariablebecomes123.

@PathVariable is a method argument level annotation that is used by @RequestMapping methods toassignvalueofaURItemplatevariabletothemethodargument.

IMPORT chapter 12/ch12-webservice-uritemplates and chapter 12/ch12-webservice-client-uritemplates(ch12-webservice-uritemplatesprojectisavariantofch12-webserviceprojectthatshowsthe implementation of FixedDepositWS RESTful web service using@PathVariable annotation. ch12-webservice-client-uritemplatesisavariantofch12-webservice-clientthataccessestheFixedDepositWSwebservicerepresentedbych12-webservice-uritemplatesproject.)

The following example listing showsusage of@PathVariable annotation in FixedDepositController ofch12-webservice-uritemplatesproject:

Examplelisting12-21–FixedDepositController-@PathVariableusageProject–ch12-webservice-uritemplatesSourcelocation-src/main/java/sample/spring/chapter12/web

packagesample.spring.chapter12.web;importorg.springframework.web.bind.annotation.PathVariable;.....@ControllerpublicclassFixedDepositController{.....@RequestMapping(value="/fixedDeposits/{fixedDepositId}",method=RequestMethod.GET)publicResponseEntity<FixedDepositDetails>getFixedDeposit(@PathVariable("fixedDepositId")intid){returnnewResponseEntity<FixedDepositDetails>(fixedDepositService.getFixedDeposit(id),HttpStatus.OK);}.....}InsteadofspecifyingtheactualURI,@RequestMappingannotationintheaboveexamplelistingspecifies/fixedDeposits/{fixedDepositId}URItemplate.Now,iftheincomingrequestURIis/fixedDeposits/1,thevalue of fixedDepositIdURI template variable is set to 1.As the@PathVariable annotation specifiesfixedDepositIdas thenameof theURI templatevariable,value1 isassigned to the id argumentof thegetFixedDepositmethod.

If a URI template defines multiple variables, the @RequestMapping method can define multiple

Page 440: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@PathVariableannotatedarguments,asshowninthefollowingexamplelisting:

Examplelisting12-22–MultipleURItemplatevariables@ControllerpublicclassSomeController{.....@RequestMapping(value="/users/{userId}/bankstatements/{statementId}",.....)publicvoidgetBankStatementForUser(@PathVariable("userId")Stringuser,@PathVariable("statementId")Stringstatement){.....}}Intheaboveexamplelisting,theURItemplatedefinesuserIdandstatementIdvariables.If theincomingrequestURIis/users/me/bankstatements/123,valuemeisassignedtotheuserargumentandvalue123isassignedtothestatementargument.

IfyouwanttoassignalltheURItemplatevariablesandtheirvaluestoamethodargument,youcanuse@PathVariableannotationonaMap<String,String>argument type, as shown in the followingexamplelisting:

Examplelisting12-23–AccessingallURItemplatevariablesandtheirvalues@ControllerpublicclassSomeController{.....@RequestMapping(value="/users/{userId}/bankstatements/{statementId}",.....)publicvoidgetBankStatementForUser(@PathVariableMap<String,String>allVariables){.....}}In theaboveexample listing,URItemplatevariables(userIdandstatementId)and theirvalues (meand123)areassignedtotheallVariablesmethodargument.

YoushouldnotethatURItemplatecanalsobespecifiedbyclasslevel@RequestMappingannotation,asshownhere:

Example listing 12-24 – URI template specified at both class and method level @RequestMappingannotations@Controller@RequestMapping(value="/service/{serviceId}",.....)publicclassSomeController{.....

Page 441: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@RequestMapping(value="/users/{userId}/bankstatements/{statementId}",.....)publicvoidgetBankStatementForUser(@PathVariableMap<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 themethod level @RequestMapping annotation. If the request URI is/service/bankingService/users/me/bankstatements/123, the allVariables argument contains details ofserviceId,userIdandstatementIdURItemplatevariables.

Thescenariosinwhichyoumaywanttohavefine-grainedcontroloverwhattoextractfromtherequestURI,youcanuse regular expressions inURI templates.The followingexample listing showsusageofregularexpressionstoextract123.jsonvaluefrom/statements/123.jsonrequestURI:

Examplelisting12-25–URItemplates–regularexpressionsusage@ControllerpublicclassSomeController{.....@RequestMapping(value="/bankestatement/{statementId:[\\d\\d\\d]}.{responseType:[a-z]}",..)publicvoidgetBankStatementForUser(@PathVariable("statementId")Stringstatement,@PathVariable("responseType")StringresponseTypeExtension){.....}}Regular expressions in URI templates are specified in the following format: {variable-name:regular-expression}.IftherequestURIis/statements/123.json,statementIdvariableisassignedthevalue123andresponseTypeisassignedthevaluejson.

NOTEYoucanalsouseAnt-stylepatternsinURItemplates.Forinstance,youcanspecifypatterns,like/myUrl/*/{myId}and/myUrl/**/{myId}asURItemplates.

So far in this section we have seen examples of how to use @PathVariable to selectively extractinformation from the request URI path. Let’s now look at@MatrixVariable annotation that is used toextractname-valuepairsfrompathsegments.

Matrix variables appear as name-value pairs in the request URI, and you can assign value of thesevariablestomethodarguments.Forinstance,intherequestURI/bankstatement/123;responseType=json,theresponseTypevariablerepresentsamatrixvariablewhosevalueisjson.

NOTEYou shouldnote thatbydefaultSpring removesmatrix variables from theURL.To ensure thatmatrix variables are not removed, set the enable-matrix-variables attribute of <annotation-driven>elementofSpringmvcschematotrue.Whenusingmatrixvariables,thepathsegmentsthatcontainmatrix

Page 442: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

variablesmustberepresentedbyURItemplatevariables.

Thefollowingexamplelistingshowsusageof@MatrixVariableannotation:

Examplelisting12-26–@MatrixVariableannotation@ControllerpublicclassSomeController{.....@RequestMapping(value="/bankestatement/{statementId}",..)publicvoidgetBankStatementForUser(@PathVariable("statementId")Stringstatement,@MatrixVariable("responseType")StringresponseTypeExtension){.....}}Intheaboveexamplelisting,iftherequestURIis/bankstatement/123;responseType=json,thevaluejsonis assigned to responseTypeExtension argument. The above example listing also shows a scenario inwhichboth@PathVariable and@MatrixVariable annotations are used to retrieve information from therequestURI.

As matrix variables can appear in any path segment of the request URI, you should specify the pathsegment from which the matrix variable should be retrieved. The following example listing shows ascenarioinwhichtwomatrixvariableswiththesamenamearepresentindifferentpathsegments:

Examplelisting12-27–@MatrixVariableannotation–multiplematrixvariableswiththesamename@ControllerpublicclassSomeController{.....@RequestMapping(value="/bankestatement/{statementId}/user/{userId}",..)publicvoidgetBankStatementForUser(@MatrixVariable(value="id",pathVar="statementId")intsomeId,@MatrixVariable(value="id",pathVar="userId")intsomeOtherId){.....}}ThepathVarattributeof@MatrixVariableannotationspecifiesthenameoftheURItemplatevariablethatcontains the matrix variable. So, if the request URI is /bankstatement/123;id=555/user/me;id=777, thevalue555isassignedtosomeId,andthevalue777isassignedtosomeOtherIdargument.

Asincaseof@PathVariableannotation,youcanannotateamethodargumenttypeofMap<String,String>with@MatrixVariable toassignall thematrixvariables to themethodargument.Unlike@PathVariableannotation,@MatrixVariable annotation allows you to specify a default value for the matrix variableusingdefaultValueattribute.Also,youcansetrequiredattributeof@MatrixVariableannotationtofalsetoindicatethatthematrixvariableisoptional.Bydefault,thevalueofrequiredattributeissettotrue.Iftherequiredattributeissettotrue,andthematrixvariable isnotfoundin therequest, thenanexceptionis

Page 443: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

thrown.

Page 444: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

12-7SummaryInthischapter,welookedathowtodevelopRESTfulwebservicesandaccessthem.WelookedathowtouseURItemplatesalongwith@PathVariableand@MatrixVariableannotationstoaccessinformationfrom the request URI. We also looked at how to access RESTful web services synchronously usingRestTemplateandasynchronouslyusingAsyncRestTemplate.

Page 445: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter13–MoreSpringWebMVC–internationalization,fileuploadandasynchronousrequestprocessing

Page 446: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

13-1IntroductionInearlierchapters,wesawthatSpringWebMVCsimplifiescreatingwebapplicationsandRESTfulwebservices.Inthischapter,we’lllookatsomemorefeaturesofferedbySpringWebMVCframeworkthatyoumayrequireinyourwebapplications.We’llparticularlylookat:

§pre-andpost-processingrequestsusinghandlerinterceptors

§internationalizingSpringWebMVCapplications

§asynchronouslyprocessingrequests

§performingtypeconversionandformatting,and

§uploadingfiles

IMPORTchapter13/ch13-bankapp(Thisprojectisavariantofch10-bankappprojectthatdemonstrateshowtoincorporateinternationalizationinMyBankwebapplication,andhowtousehandlerinterceptors.)

Let’sbeginbylookingathowtopre-andpost-processrequestsusinghandlerinterceptors.

Page 447: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

13-2Pre-andpost-processingrequestsusinghandlerinterceptorsHandlerinterceptorsallowyoutopre-andpost-processrequests.Theconceptofhandlerinterceptorsissimilartothatofservletfilters.HandlerinterceptorsimplementSpring’sHandlerInterceptorinterface.Ahandler interceptorcontains thepre-andpost-processing logic that is requiredbymultiplecontrollers.Forinstance,youcanusehandlerinterceptorsforlogging,securitychecks,changinglocale,andsoon.

Let’snowlookathowtoimplementandconfigurehandlerinterceptors.

ImplementingandconfiguringahandlerinterceptorYou can create handler interceptors by implementing HandlerInterceptor interface. HandlerInterceptorinterfacedefinesthefollowingmethods:

§preHandle–thismethodisexecutedbefore thecontrollerprocesses therequest. If thepreHandlemethod returns true, the controller is invoked bySpring to process the request. If the preHandlemethodreturnsfalse,thecontrollerisnotinvoked.

§postHandle–thismethodisexecutedafterthecontrollerprocessestherequest,butbeforetheviewisrenderedbytheDispatcherServlet.

§afterCompletion–thismethodisinvokedafterthecompletionofrequestprocessing(thatis,aftertheviewisrenderedbytheDispatcherServlet)todoanycleanup,ifrequired.

The following example listing shows MyRequestHandlerInterceptor class of ch13-bankapp thatimplementsHandlerInterceptorinterface:

Examplelisting13-1–MyRequestHandlerInterceptorProject–ch13-bankappSourcelocation-src/main/java/sample/spring/chapter13/web

packagesample.spring.chapter13.web;importorg.springframework.web.servlet.HandlerInterceptor;.....publicclassMyRequestHandlerInterceptorimplementsHandlerInterceptor{.....publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{logger.info("HTTPmethod-->"+request.getMethod());Enumeration<String>requestNames=request.getParameterNames();.....returntrue;}publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{logger.info("Statuscode-->"+response.getStatus());}

Page 448: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

publicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{logger.info("Requestprocessingcomplete");}}

In theaboveexample listing, thepreHandlemethod inspectseach incomingrequestand logs theHTTPmethodassociatedwith therequestand therequestparameterscontained in therequest.ThepreHandlemethodreturns true,whichmeans that the requestwillbeprocessedby thecontroller.ThepostHandlemethod logs the HTTP response status code. The afterCompletion method logs the message that therequestwassuccessfullyprocessed.

NOTE Instead of directly implementing theHandlerInterceptor interface, you can extend the abstractHandlerInterceptorAdapter class that provides empty implementations for postHandle andafterCompletionmethods,andthepreHandlemethodisdefinedtosimplyreturntrue.

The following example listing shows how handler interceptors are configured in the web applicationcontextXMLfile:

Examplelisting13-2–MyRequestHandlerInterceptorProject–ch13-bankappSourcelocation-src/main/webapp/WEB-INF/spring/bankapp-config.xml

<beans.....xmlns:mvc="http://www.springframework.org/schema/mvc".....><mvc:annotation-driven/><mvc:interceptors>.....<beanclass="sample.spring.chapter13.web.MyRequestHandlerInterceptor"/></mvc:interceptors></beans>The above example listing shows that the <interceptors> element of Spring’smvc schema is used forconfiguringhandlerinterceptors.The<interceptors>elementcanhavethefollowingsub-elements:

§ <bean> element of Spring’s beans schema - specifies a Spring bean that implements theHandlerInterceptor interface. A handler interceptor defined using <bean> element applies to allrequests.

§ <ref> element of Spring’s beans schema - refers to a Spring bean that implements theHandlerInterceptor interface. A handler interceptor defined using <ref> element applies to allrequests.

§ <interceptor> element of Spring’s mvc schema – specifies a Spring bean that implements theHandlerInterceptorinterface,andtherequestURIstowhichtheHandlerInterceptorapplies.

The following example listing shows a scenario inwhichMyRequestHandlerInterceptor ismapped to

Page 449: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

/audit/**requestURI:

Examplelisting13-3–<mvc:interceptor>usage<beans.....xmlns:mvc="http://www.springframework.org/schema/mvc".....><mvc:annotation-driven/><mvc:interceptors><mvc:interceptor><mvc:mappingpath="/audit/**"/><beanclass="sample.spring.chapter13.web.MyRequestHandlerInterceptor"/></mvc:interceptor></mvc:interceptors></beans>In the above example listing, <interceptor> element of Spring’s mvc schema is used for mappingMyRequestHandlerInterceptorto/audit/**URIpattern.The<mapping>elementofSpring’smvcschemaspecifies the request URI pattern to which the handler interceptor specified by the <bean> elementapplies.

Let’snowlookathowtointernationalizeaSpringWebMVCapplication.

Page 450: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

13-3InternationalizingusingresourcebundlesBeforedelvingintothedetailsofhowtointernationalizeSpringWebMVCapplications,let’slookattheinternationalizationandlocalizationrequirementsoftheMyBankwebapplication.

MyBankwebapplication’srequirementsIt is required that theMyBankweb application supports English (en_US locale) andGerman (de_DElocale) languages. The following figure shows one of the web pages ofMyBank web application inde_DElocale:

Figure13-1Webpagethatshowsthelistoffixeddepositsinde_DElocale.Ausercanselectalocalefromthegivenoptions.Theabovefigureshowsthatausercanchooseoneofthefollowinglanguages:English(US),German,orEnglish(Canada). If a user chooses German language option, the web pages are displayed in de_DElocale.IfauserchoosesEnglish(US)languageoption,thewebpagesaredisplayedinen_USlocale.IfauserchoosesEnglish(Canada)languageoption,thewebpagesaredisplayedinen_CAlocale.

Let’s now look at how to address internationalization and localization requirements of MyBank webapplication.

InternationalizingandlocalizingMyBankwebapplicationInSpringWebMVC,theDispatcherServletusesaLocaleResolverforautomaticallyresolvingmessagesbasedontheuser’slocale.Tosupportinternationalization,youneedtoconfigurethefollowingbeansinyourwebapplicationcontextXMLfile:

·LocaleResolver–resolvesthecurrentlocaleoftheuser

Page 451: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

·MessageSource–resolvesmessagesfromresourcebundlesbasedonthecurrentlocaleoftheuser

· LocaleChangeInterceptor – allows changing current locale on every request based on aconfigurablerequestparameter

The following example listing shows configuration of LocaleResolver, LocaleChangeInterceptor andMessageSourcebeansinthewebapplicationcontextXMLfileofch13-bankappproject:

Examplelisting13-4–bankapp-config.xmlProject–ch13-bankappSourcelocation-src/main/webapp/WEB-INF/spring

<beans.....><beanclass="org.springframework.web.servlet.i18n.CookieLocaleResolver"id="localeResolver"><propertyname="cookieName"value="mylocale"/></bean><beanclass="org.springframework.context.support.ReloadableResourceBundleMessageSource"id="messageSource"><propertyname="basenames"value="WEB-INF/i18n/messages"/></bean><mvc:interceptors>.....<beanclass="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"><propertyname="paramName"value="lang"/></bean></mvc:interceptors>.....</beans>Intheaboveexamplelisting,CookieLocaleResolver(animplementationofLocaleResolverinterface)hasbeen configured for locale resolution. If the locale information is stored in a cookie by the webapplication,CookieLocaleResolver isusedfor locale resolution.CookieLocaleResolver’s cookieNamepropertyspecifiesthenameofthecookiethatcontainsthelocaleinformation.Ifthecookieisnotfoundinthe 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 LocaleResolverimplementations that you can use: AcceptHeaderLocaleResolver (returns the locale specified by theAccept-Language request header), SessionLocaleResolver (returns the locale information stored in theHttpSessionoftheuser)andFixedLocaleResolver(alwaysreturnsafixeddefaultlocale).

Inadditiontoknowinguser’slocale,youmayalsowanttoknowuser’stimezonetoconvertdateandtimein user’s time zone. LocaleContextResolver (introduced in Spring 4.0) not only provides the localeinformation but also the time zone information of the user. CookieLocaleResolver,SessionLocaleResolver and FixedLocaleResolver implement the LocaleContextResolver interface;

Page 452: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

therefore,ifyouareusinganyoftheseresolversyoucanobtainuser’stimezoneinyourcontrollersusinggetTimeZonemethodofLocaleContextHolder(orRequestContextUtils)class.Ifyouonlywanttoobtainthe locale information in your controllers, you can use getLocalemethod of LocaleContextHolder (orRequestContextUtils)class.

Spring provides a LocaleChangeInterceptor (a HandlerInterceptor) that uses a configurable requestparameter(specifiedbyparamNameproperty)tochangethecurrentlocaleoneveryrequest.Inexamplelisting13-4,theparamNameproperty isset to lang.LocaleResolverdefinesasetLocalemethod that isused by the LocaleChangeInterceptor to change the current locale. If you don’t want to useLocaleChangeInterceptor, thenyoucanchange theuser’s locale inyourcontrollerbycalling setLocalemethodofLocaleContextHolder(orRequestContextUtils)class.

Oncetheuser’slocaleisresolved,SpringusestheconfiguredMessageSourceimplementationtoresolvemessages.Springprovidesthefollowingbuilt-inimplementationsofMessageSourceinterface:

§ResourceBundleMessageSource–aMessageSourceimplementationthataccessesresourcebundlesusingthespecifiedbasenames

§ ReloadableResourceBundleMessageSource – similar to ResourceBundleMessageSourceimplementation.Thisimplementationsupportsreloadingofresourcebundles.

Example listing 13-4 shows that the MyBank web application usesReloadableResourceBundleMessageSource.ThebasenamespropertyissettoWEB-INF/i18n/messages,which means that the ReloadableResourceBundleMessageSource looks for resource bundles namedmessages inside WEB-INF/i18n folder. So, if the user’s locale is resolved to en_US, theReloadableResourceBundleMessageSourcewill resolvemessages from themessages_en_US.propertiesfile.

Ifyoulookat/src/main/webapp/WEB-INF/i18nfolderofch13-bankappproject,you’llfindthefollowingpropertiesfiles:messages.properties,messages_en_US.propertiesandmessages_de_DE.properties.Themessages_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.propertiescontainsmessages and labels that are shownwhenno locale-specific resource bundles are found.Asthere is no messages_en_CA.properties file corresponding to en_CA locale, selecting theEnglish(Canada)option(referfigure13-1)showsmessagesfromthemessages.propertiesfile.

In figure 13-1,we saw thatwe can change the language of theMyBankweb application by selectingEnglish(US), English(Canada) and German language options. We saw earlier that theLocaleChangeInterceptorcanchangethelocaleoftheMyBankwebapplicationifthelocaleinformationiscontainedinarequestparameternamedlang.Tosimplifychangingthelocale,langrequestparameterisappended to the hyperlinks shown by English(US), English(Canada) andGerman language options, asshownhere:

Examplelisting13-5–fixedDepositList.jspProject–ch13-bankappSourcelocation-src/main/webapp/WEB-INF/jsp

<b>Language:</b><ahref="${pageContext.request.contextPath}/fixedDeposit/list?lang=en_US">English(US)</a>|

Page 453: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<ahref="${pageContext.request.contextPath}/fixedDeposit/list?lang=de_DE">German</a>|<ahref="${pageContext.request.contextPath}/fixedDeposit/list?lang=en_CA">English(Canada)</a>Let’snowlookathowyoucanasynchronouslyprocessrequestsinSpringWebMVCapplications.

Page 454: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

13-4AsynchronouslyprocessingrequestsA @RequestMapping annotated method that returns a java.util.concurrent.Callable or Spring’sDeferredResult object processesweb requestsasynchronously. If a@RequestMappingmethod returnsCallable,SpringWebMVCtakescareofprocessing theCallable inanapplication thread(andnot theServletcontainerthread)toproducetheresult.Ifa@RequestMappingmethodreturnsDeferredResult, itisapplication’sresponsibilitytoprocesstheDeferredResultinanapplicationthread(andnottheServletcontainerthread)toproducetheresult.BeforedelvingintothedetailofhowCallableandDeferredResultreturn values are processed, let’s look at how to configure aSpringWebMVCapplication to supportasynchronousrequestprocessing.

IMPORT chapter 13/ch13-async-bankapp (This project is a variant of ch10-bankapp project thatasynchronouslyprocessesrequests.@RequestMappingmethodsdefinedintheFixedDepositControllerofthis project return Callable. You should deploy and run the ch13-async-bankapp project to seeasynchronousrequestprocessinginaction.)

AsynchronousrequestprocessingconfigurationAsasynchronousrequestprocessing inSpringWebMVCisbasedonServlet3,web.xmlmust refer toServlet 3 XML schema. Also, <async-supported> element must be added to the DispatcherServletdefinition inweb.xml file to indicate that it supports asynchronous request processing. The followingexamplelistingshowstheweb.xmlfileofch13-async-bankappproject:

Examplelisting13-6–web.xml–asynchronousrequestprocessingconfigurationProject–ch13-async-bankappSourcelocation-src/main/webapp/WEB-INF

<web-app.....xsi:schemaLocation="java.sun.com/xml/ns/javaeejava.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>Theaboveexamplelistingshowsthatthebankappservletisconfiguredtosupportasynchronousrequestprocessing.Now,thebankappservletcanasynchronouslyprocesswebrequests.

ReturningCallablefrom@RequestMappingmethodsThe following example listing shows the FixedDepositController whose @RequestMapping methodsreturnCallable:

Examplelisting13-7–FixedDepositController–returningCallablefrom@RequestMappingmethods

Page 455: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Project–ch13-async-bankappSourcelocation-src/main/java/sample/spring/chapter13/web

packagesample.spring.chapter13.web;importjava.util.concurrent.Callable;.....publicclassFixedDepositController{.....@RequestMapping(value="/list",method=RequestMethod.GET)publicCallable<ModelAndView>listFixedDeposits(){returnnewCallable<ModelAndView>(){@OverridepublicModelAndViewcall()throwsException{Thread.sleep(5000);Map<String,List<FixedDepositDetails>>modelData=newHashMap<String,List<FixedDepositDetails>>();modelData.put("fdList",fixedDepositService.getFixedDeposits());returnnewModelAndView("fixedDepositList",modelData);}};}.....}TheaboveexamplelistingshowsthatthelistFixedDepositsmethodreturnsaCallable<T>object,whereTisthetypeoftheresultthatisasynchronouslycomputed.TheCallable’scallmethodcontainsthelogicthat needs to be executed asynchronously to produce the result. The call method shown in the aboveexamplelistinginvokesFixedDepositService’sgetFixedDepositsmethod,andreturnsaModelAndViewobjectcontainingthemodelandviewinformation.TheThread.sleepmethodisinvokedinthebeginningofcallmethodtosimulateascenarioinwhichtherequestprocessingtakestime.

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 isresponsibleforhandlingtheexception.Formoreinformationon@ExceptionHandlerannotation,refertosection10-9ofchapter10.

Examplelisting13-7showsthatifyouwanttoswitchfromsynchronousrequestprocessingapproachtoasynchronousrequestprocessing,youneedtomovethelogicfromthe@RequestMappingmethodtothecallmethodofCallable,andchangethereturntypeofthe@RequestMappingmethodtoCallable<T>.

Let’snowlookathowrequestsareasynchronouslyprocessedwhena@RequestMappingmethodreturnsaDeferredResultobject.

IMPORT chapter 13/ch13-async-webservice and ch13-async-webservice-client (The ch13-async-webservice project is a variant of FixedDepositWS web service (refer ch12-webservice project ofchapter12)thatasynchronouslyprocesseswebservicerequests.@RequestMappingmethodsdefinedin

Page 456: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

theFixedDepositControllerofthisprojectreturnaninstanceofDeferredResultobject.Thech13-async-webservice-client project is sameas theFixedDepositWSweb service client (refer ch12-webservice-clientprojectofchapter12)thatassumesthatthewebserviceisdeployedathttp://localhost:8080/ch13-async-webservice.)

ReturningDeferredResultfrom@RequestMappingmethodsADeferredResultinstancerepresentsaresultthatisasynchronouslycomputed.YousettheresultontheDeferredResultinstancebycallingitssetResultmethod.Typically,a@RequestMappingmethodstoresaDeferredResult instance in a Queue or a Map or any other data structure, and a separate thread isresponsibleforcomputingtheresultandsettingtheresultontheDeferredResultinstance.

Let’sfirstlookat@RequestMappingmethodsthatreturnDeferredResulttype.

@RequestMappingmethodimplementation

The following example listing shows the FixedDepositController whose @RequestMapping methodsreturnDeferredResultobjects:

Example listing 13-8 – FixedDepositController – returning DeferredResult from @RequestMappingmethodsProject–ch13-async-webserviceSourcelocation-src/main/java/sample/spring/chapter13/web

packagesample.spring.chapter13.web;importjava.util.Queue;importjava.util.concurrent.ConcurrentLinkedQueue;importorg.springframework.web.context.request.async.DeferredResult;.....@Controller@RequestMapping(value="/fixedDeposits")publicclassFixedDepositController{privatestaticfinalStringLIST_METHOD="getFixedDepositList";privatestaticfinalStringGET_FD_METHOD="getFixedDeposit";.....privatefinalQueue<ResultContext>deferredResultQueue=newConcurrentLinkedQueue<ResultContext>();.....@RequestMapping(method=RequestMethod.GET)publicDeferredResult<ResponseEntity<List<FixedDepositDetails>>>getFixedDepositList(){DeferredResult<ResponseEntity<List<FixedDepositDetails>>>dr=newDeferredResult<ResponseEntity<List<FixedDepositDetails>>>();ResultContext<ResponseEntity<List<FixedDepositDetails>>>resultContext=newResultContext<ResponseEntity<List<FixedDepositDetails>>>();resultContext.setDeferredResult(dr);resultContext.setMethodToInvoke(LIST_METHOD);

Page 457: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

resultContext.setArgs(newHashMap<String,Object>());deferredResultQueue.add(resultContext);returndr;}.....}Each@RequestMappingmethodofFixedDepositControllerperformsthesesteps:

Step1-createsaninstanceofDeferredResult<T>object,whereTrepresentsthetypeoftheresultthatisasynchronously computed. As the type of the result computed for the getFixedDepositList method isResponseEntity<List<FixedDepositDetails>>, an instance ofDeferredResult<ResponseEntity<List<FixedDepositDetails>>>iscreated.

Step2-createsaninstanceofResultContextobject.ResultContextobjectholdsDeferredResultinstancethatwecreatedinStep1,andotherdetailsthatarerequiredtoasynchronouslycomputetheresultfortheDeferredResult object. In case of FixedDepositController’s getFixedDepositList method, result isrepresentedby the listof fixeddepositsobtainedby invokingFixedDepositService’s getFixedDepositsmethod.

ThefollowingexamplelistingshowstheResultContextclass:

Examplelisting13-9–ResultContextclassforstoringDeferredResultandotherinformationProject–ch13-async-webserviceSourcelocation-src/main/java/sample/spring/chapter13/web

packagesample.spring.chapter13.web;importjava.util.Map;importorg.springframework.web.context.request.async.DeferredResult;publicclassResultContext<T>{privateStringmethodToInvoke;privateDeferredResult<T>deferredResult;privateMap<String,Object>args;publicvoidsetDeferredResult(DeferredResult<T>deferredResult){this.deferredResult=deferredResult;}.....}The deferredResult property refers to an instance of DeferredResult, the methodToInvoke propertyspecifies the name of the FixedDepositService method that is invoked to compute the result for theDeferredResultobject,andargsproperty(oftypejava.util.Map)specifiestheargumentstobepassedtothe FixedDepositService method. A separate thread (as explained later in this section) uses themethodToInvokeandargsproperties to invoke the specifiedFixedDepositServicemethod, and sets the

Page 458: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

returnedresultontheDeferredResultinstance.

AstheLIST_METHOD,GET_FD_METHOD,andsoon,constantsintheFixedDepositControllerclassrefertothenamesoftheFixedDepositServicemethods(referexamplelisting13-8),themethodToInvokeproperty is set to the one of these constants. In example listing 13-8, FixedDepositController’sgetFixedDepositListmethodsetsthemethodToInvokepropertytoLIST_METHODconstant(whosevalueis getFixedDeposits) because FixedDepositService’s getFixedDepositsmethod needs to be invoked toobtaintheresultfortheDeferredResultobjectreturnedbyFixedDepositController’sgetFixedDepositListmethod.

Step3-storestheResultContextinstancecreatedinStep2intoaQueue(refertodeferredResultQueueinstancevariableinexamplelisting13-8)

Step4-returnstheDeferredResultobjectcreatedinStep1

TheabovesequenceofstepssuggeststhatforeachwebrequestaninstanceofResultContextisstoredinthe deferredResultQueue. The following figure summarizes the actions that are performed byFixedDepositController’sgetFixedDepositListmethod.

Figure 13-2 FixedDepositController’s getFixedDepositList method adds a ResultContext object to thequeueandreturnsaDeferredResultobject

Let’s now look at how the result is computed for the DeferredResult instance contained inside theResultContextobject.

ComputingresultforaDeferredResultinstance

FixedDepositController’s processResults method is responsible for iterating over the ResultContextobjects stored in the deferredResultQueue (refer example listing 13-8), computing the result for each

Page 459: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

DeferredResultobject,andsettingtheresultontheDeferredResultobject.ThefollowingexamplelistingshowstheprocessResultsmethod:

Example listing 13-10 – processResults method – computing and setting results on DeferredResultobjectsProject–ch13-async-webserviceSourcelocation-src/main/java/sample/spring/chapter13/web

packagesample.spring.chapter13.web;importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.web.context.request.async.DeferredResult;@Controller@RequestMapping(value="/fixedDeposits")publicclassFixedDepositController{privatestaticfinalStringLIST_METHOD="getFixedDepositList";.....privatefinalQueue<ResultContext>deferredResultQueue=newConcurrentLinkedQueue<ResultContext>();@AutowiredprivateFixedDepositServicefixedDepositService;.....@Scheduled(fixedRate=10000)publicvoidprocessResults(){for(ResultContextresultContext:deferredResultQueue){if(resultContext.getMethodToInvoke()==LIST_METHOD){resultContext.getDeferredResult().setResult(newResponseEntity<List<FixedDepositDetails>>(fixedDepositService.getFixedDeposits(),HttpStatus.OK));}.....deferredResultQueue.remove(resultContext);}}}@Scheduled annotation (refer section 8-6 of chapter 8 for more details) on processResults methodspecifies that every 10 seconds an application thread is responsible for executing the processResultsmethod. The processResults method uses the method name and argument information stored in theResultContext instance to invoke the appropriate FixedDepositService’s method. The processResultsmethodthensetstheresultontheDeferredResultinstancebycallingitssetResultmethod.Intheend,theprocessResults method removes the ResultContext instance from the Queue. After processing aResultContextinstance,theprocessResultsmethodremovestheResultContextinstancefromtheQueuesothatitisnotre-processedbytheprocessResultsmethodwhenitexecutesagainafter10seconds.

Figure 13-3 summarizes the actions performed by FixedDepositController’s processResults method to

Page 460: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

computetheresultandsetitontheDeferredResultinstance.

Figure 13-3 The processResults method reads method name and argument information from theResultContextobjecttocomputetheresultfortheDeferredResultinstance

Let’s now look at how exceptions are handled when a @RequestMapping method returns aDeferredResultinstance.

ExceptionHandling

Ifyousetanobjectoftypejava.lang.ExceptionusingDeferredResult’ssetErrorResultmethod,theresultis handled by @ExceptionHandler annotated method of the controller (or by the configuredHandlerExceptionResolver bean). For more information on @ExceptionHandler annotation, refer tosection10-9ofchapter10.

The following example listing showsFixedDepositController’sopenFixedDepositmethod that opens anewfixeddeposit:

Examplelisting13-11–FixedDepositController’sopenFixedDepositmethodProject–ch13-async-webserviceSourcelocation-src/main/java/sample/spring/chapter13/web

Page 461: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

packagesample.spring.chapter13.web;@Controller@RequestMapping(value="/fixedDeposits")publicclassFixedDepositController{privatestaticfinalStringOPEN_FD_METHOD="openFixedDeposit";.....privatefinalQueue<ResultContext>deferredResultQueue=newConcurrentLinkedQueue<ResultContext>();@RequestMapping(method=RequestMethod.POST)publicDeferredResult<ResponseEntity<FixedDepositDetails>>openFixedDeposit(@RequestBodyFixedDepositDetailsfixedDepositDetails,BindingResultbindingResult){DeferredResult<ResponseEntity<FixedDepositDetails>>dr=newDeferredResult<ResponseEntity<FixedDepositDetails>>();ResultContext<ResponseEntity<FixedDepositDetails>>resultContext=newResultContext<ResponseEntity<FixedDepositDetails>>();resultContext.setDeferredResult(dr);resultContext.setMethodToInvoke(OPEN_FD_METHOD);Map<String,Object>args=newHashMap<String,Object>();args.put("fixedDepositDetails",fixedDepositDetails);args.put("bindingResult",bindingResult);resultContext.setArgs(args);deferredResultQueue.add(resultContext);returndr;}.....}Theaboveexample listingshows that thearguments (fixedDepositDetailsandbindingResult)passed totheopenFixedDepositmethodaresetontheResultContextinstancesothattheseargumentsareavailablewhen the processResults method executes the logic for opening a new fixed deposit. ThefixedDepositDetailsargumentcontainsthedetailsofthefixeddeposittobeopenedandthebindingResultargumentcontainstheresultsofdatabinding.

The following example listing showshow the processResultsmethod executes the logic for opening anewfixeddeposit:

Examplelisting13-12–FixedDepositController’sprocessResultsmethodProject–ch13-async-webserviceSourcelocation-src/main/java/sample/spring/chapter13/web

packagesample.spring.chapter13.web;

Page 462: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

@Controller@RequestMapping(value="/fixedDeposits")publicclassFixedDepositController{privatestaticfinalStringOPEN_FD_METHOD="openFixedDeposit";.....privatefinalQueue<ResultContext>deferredResultQueue=newConcurrentLinkedQueue<ResultContext>();@AutowiredprivateFixedDepositServicefixedDepositService;.....@ExceptionHandler(ValidationException.class)@ResponseBody@ResponseStatus(value=HttpStatus.BAD_REQUEST)publicStringhandleException(Exceptionex){logger.info("handlingValidationException"+ex.getMessage());returnex.getMessage();}@Scheduled(fixedRate=10000)publicvoidprocessResults(){for(ResultContextresultContext:deferredResultQueue){.....if(resultContext.getMethodToInvoke()==OPEN_FD_METHOD){FixedDepositDetailsfixedDepositDetails=(FixedDepositDetails)resultContext.getArgs().get("fixedDepositDetails");BindingResultbindingResult=(BindingResult)resultContext.getArgs().get("bindingResult");newFixedDepositDetailsValidator().validate(fixedDepositDetails,bindingResult);if(bindingResult.hasErrors()){logger.info("openFixedDeposit()method:Validationerrorsoccurred");resultContext.getDeferredResult().setErrorResult(newValidationException("Validationerrorsoccurred"));}else{fixedDepositService.saveFixedDeposit(fixedDepositDetails);resultContext.getDeferredResult().setResult(newResponseEntity<FixedDepositDetails>(fixedDepositDetails,HttpStatus.CREATED));}}.....}}}

Page 463: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Theaboveexamplelistingshowsthe@ExceptionHandlerannotatedhandleExceptionmethodthathandlesexceptionsoftypeValidationException.ThehandleExceptionmethodlogsthatavalidationexceptionhasoccurredandreturnstheexceptionmessage.

To open a new fixed deposit, the processResults method retrieves the fixedDepositDetails (of typeFixedDepositDetails) andbindingResult (of typeBindingResult) arguments from theResultContext andvalidates the fixedDepositDetails object by calling FixedDepositValidator’s validate method. Ifvalidation errors are reported, the processResults method invokes DeferredResult’s setErrorResultmethod to set ValidationException (of type java.lang.Exception) as the result. Setting theValidationExceptionusingDeferredResult’ssetErrorResultmethodwill cause handling of the result byFixedDepositController’shandleExceptionmethod.

It is recommended that you deploy the ch13-async-webservice project (which represents theFixedDepositWS RESTful web service) and access it by running the main method ofFixedDepositWSClient of ch13-async-webservice-client project (which represents a client ofFixedDepositWSRESTfulwebservice).TheFixedDepositWSClient’sopenInvalidFixedDepositmethodinvokes FixedDepositController’s openFixedDeposit web service method such that it results inValidationException.YoucancheckthelogstoverifythattheFixedDepositController’shandleExceptionmethodhandles the resultwhenprocessResultsmethod setsValidationException on theDeferredResultobjectbycallingDeferredResult’ssetErrorResultmethod.

Let’snowlookathowtosetdefaulttimeoutvalueforasynchronousrequests.

SettingdefaulttimeoutvalueYou can set the default timeout value of asynchronous requests by using default-timeout attribute of<async-support>element,asshownhere:

Examplelisting13-13–SettingdefaulttimeoutforasynchronousrequestsProject–ch13-async-webserviceSourcelocation–src/main/webapp/WEB-INF/spring/webservice-config.xml

<mvc:annotation-driven><mvc:async-supportdefault-timeout="10000">.....</mvc:async-support></mvc:annotation-driven>Intheaboveexamplelisting,defaulttimeoutforasynchronousrequestsissetto10seconds.Ifyoudon’tspecify the default timeout, the timeout for asynchronous requests depends on theServlet container onwhichyoudeployedyourwebapplication.

Let’snowlookathowyoucaninterceptasynchronousrequestsusingCallableProcessingInterceptorandDeferredResultProcessingInterceptor.

InterceptingasynchronousrequestsIfyouareusingCallabletoasynchronouslyprocessrequests,youcanuseCallableProcessingInterceptorcallback interface to intercept requestsbeforeandafter theCallable task isexecuted.For instance, thepostProcessmethodisexecutedaftertheCallablehasproducedtheresult,andthepreProcessmethodis

Page 464: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

called before the Callable task is executed. Similarly, if you are using DeferredResult, you can useDeferredResultProcessingInterceptorcallbackinterfacetointerceptprocessingofasynchronousrequests.

YoucanconfigureaCallableProcessingInterceptorusing<callable-interceptors>elementofSpring’smvcschema. And, you can configure a DeferredResultProcessingInterceptor using <deferred-result-interceptors> element of Spring’smvc schema. The following example listing shows configuration ofMyDeferredResultInterceptor(aDeferredResultProcessingInterceptorimplementation):

Examplelisting13-14–ConfiguringaDeferredResultProcessingInterceptorimplementationProject–ch13-async-webserviceSourcelocation–src/main/webapp/WEB-INF/spring/webservice-config.xml

<mvc:annotation-driven><mvc:async-supportdefault-timeout="30000"><mvc:deferred-result-interceptors><beanclass="sample.spring.chapter13.web.MyDeferredResultInterceptor"/></mvc:deferred-result-interceptors></mvc:async-support></mvc:annotation-driven>Let’snowlookatSpring’ssupportfortypeconversionandformatting.

Page 465: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

13-5TypeconversionandformattingsupportinSpringSpring’sConverter interface simplifies converting anobject type to anotherobject type.And,Spring’sFormatter interface is usefulwhenconverting anobject type to its localizedString representation, andvice versa. You can find a number of built-in Converter implementations in theorg.springframework.core.convert.supportpackageofspring-coreJARfile.Springalsoprovidesbuilt-inFormatters for java.lang.Number and java.util.Date types that you can find inorg.springframework.format.numberandorg.springframework.format.datetimepackages,respectively.

IMPORTchapter 13/ch13-converter-formatter-bankapp (This project is a variant of ch13-bankappprojectthatshowshowtocreatecustomConvertersandFormatters)

Let’sfirstlookathowtocreateacustomConverter.

CreatingacustomConverterAconverterimplementsSpring’sConverter<S,T>interface,whereS(referredtoasthesourcetype)isthetypeoftheobjectgiventotheconverter,andT(referredtoasthetargettype)isthetypeoftheobjecttowhichSisconvertedbytheconverter.Converterinterfacedefinesaconvertmethodthatprovidestheconversionlogic.

The following example listing shows the IdToFixedDepositDetailsConverter that converts an object oftypeString(representingthefixeddepositID)toanobjectoftypeFixedDepositDetails(representingthefixeddepositcorrespondingtothefixeddepositID):

Examplelisting13-15–ConverterimplementationProject–ch13-converter-formatter-bankappSourcelocation–src/main/java/sample/spring/chapter13/converter

packagesample.spring.chapter13.converter;importorg.springframework.core.convert.converter.Converter;.....publicclassIdToFixedDepositDetailsConverterimplementsConverter<String,FixedDepositDetails>{@AutowiredprivateFixedDepositServicefixedDepositService;@OverridepublicFixedDepositDetailsconvert(Stringsource){returnfixedDepositService.getFixedDeposit(Integer.parseInt(source));}}IdToFixedDepositDetailsConverterimplementsConverter<String,FixedDepositDetails>interface,whereStringisthesourcetypeandFixedDepositDetailsisthetargettype.IdToFixedDepositDetailsConverter’sconvertmethodusesFixedDepositService’sgetFixedDepositmethodtoretrievetheFixedDepositDetailsobjectcorrespondingtothefixeddepositID.

Page 466: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Let’snowlookathowtoconfigureanduseacustomconverter.

ConfiguringandusingacustomConverterTouseacustomconverter,youneedtoregisterthecustomconverterwithSpring’sConversionService.AConversionServiceactsasaregistryofConvertersandFormatters,andSpringdelegatestypeconversionresponsibility to the registered ConversionService. By default, the <annotation-driven> element ofSpring’smvcschemaautomatically registersSpring’sFormattingConversionService(an implementationofConversionService)withtheSpringcontainer.Springcomeswithacoupleofbuilt-inconvertersandformatters that are automatically registered with the FormattingConversionService. If you want tosubstituteadifferent implementationofConversionService,youcando sobyusingconversion-serviceattributeof<annotation-driven>element.

To register custom converters with the FormattingConversionService instance, configure Spring’sFormattingConversionServiceFactoryBean(aFactoryBean implementation that creates and configures aFormattingConversionService instance) and specify custom converters as part of the configuration, asshowninthefollowingexamplelisting:

Examplelisting13-16–RegisteringacustomConverterwithFormattingConversionServiceProject–ch13-converter-formatter-bankappSourcelocation–src/main/webapp/WEB-INF/spring

<mvc:annotation-drivenconversion-service="myConversionService"/><beanid="myConversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><propertyname="converters"><set><beanclass="sample.spring.chapter13.converter.IdToFixedDepositDetailsConverter"/></set></property>.....</bean>By default, FormattingConversionServiceFactoryBean registers only the built-in converters andformatterswiththeFormattingConversionServiceinstance.YouregistercustomconvertersandformattersusingFormattingConversionServiceFactoryBean’sconvertersandformattersproperties.AswewantourSpring application to use FormattingConversionService instance created by theFormattingConversionServiceFactoryBean, the conversion-service attribute of <annotation-driven>elementreferstotheFormattingConversionServiceFactoryBean.

Theconvertersand formatters registeredwith theFormattingConversionServiceareusedby theSpringcontainer to perform type conversion during data binding. In the following example listing,FixedDepositController’s viewFixedDepositDetails method shows a scenario in which the SpringcontainerusesIdToFixedDepositDetailsConverter<String,FixedDepositDetails>toconvertfixeddepositID(oftypeString)toFixedDepositDetailsinstance:

Examplelisting13-17–FixedDepositController’sviewFixedDepositDetailsmethodProject–ch13-converter-formatter-bankapp

Page 467: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Sourcelocation–src/main/java/sample/spring/chapter13/web

packagesample.spring.chapter13.web;.....publicclassFixedDepositController{.....@RequestMapping(params="fdAction=view",method=RequestMethod.GET)publicModelAndViewviewFixedDepositDetails(@RequestParam(value="fixedDepositId")FixedDepositDetailsfixedDepositDetails){.....}}@RequestParamannotationspecifiesthatthevalueoffixedDepositIdrequestparameterisassignedtothefixedDepositDetailsmethodargument.ThefixedDepositId requestparameteruniquely identifiesa fixeddeposit. As the fixedDepositId request parameter is of type String and method argument type isFixedDepositDetails, Spring uses IdToFixedDepositDetailsConverter<String, FixedDepositDetails> toperformthetypeconversion.

The use of ConversionService is not limited to the web layer. You can use ConversionService toprogrammaticallyperformtypeconversioninanylayerofyourapplication.Thefollowingexamplelistingshows a variant of FixedDepositController’s viewFixedDepositDetails method that usesConversionServicedirectlyforperformingtypeconversion:

Examplelisting13-18–Performingtypeconversionprogrammaticallyimportorg.springframework.core.convert.ConversionService;.....publicclassFixedDepositController{@AutowiredprivateConversionServiceconversionService;.....@RequestMapping(params="fdAction=view",method=RequestMethod.GET)publicModelAndViewviewFixedDepositDetails(HttpServletRequestrequest){StringfixedDepositId=request.getParameter("fixedDepositId");FixedDepositDetailsfixedDepositDetails=conversionService.convert(fixedDepositId,FixedDepositDetails.class);.....}}Intheaboveexamplelisting,ConversionService instance that is registeredwith theSpringcontainer isautowired into the FixedDepositController. The viewFixedDepositDetails method usesConversionService’sconvertmethodtoconvertfixedDepositId (of typeString) toFixedDepositDetails.Behind the scenes, ConversionService makes use of the IdToFixedDepositDetailsConverter<String,FixedDepositDetails>converterregisteredwithittoperformthetypeconversion.

Page 468: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

NowthatwehaveseenhowtocreateanduseacustomConverter,let’snowlookathowtocreateanduseacustomFormatter.

CreatingacustomFormatterAformatterconvertsanobjectoftypeTtoaStringvaluefordisplaypurposes,andparsesaStringvaluetotheobjecttypeT.AformatterimplementsSpring’sFormatter<T>interface,whereTisthetypeoftheobjectthattheformatterformats.ThismaysoundsimilartowhatPropertyEditorsdoinwebapplications.Aswe’llseeinthischapter,FormattersofferamorerobustalternativetoPropertyEditors.

NOTESpring’staglibrarytagsusetheformattersregisteredwiththeFormattingConversionServicetoperformtypeconversionduringdatabindingandrendering.

The following example listing shows theAmountFormatter that is used by theMyBank application todisplay fixed deposit amount in the currency that applies to the user’s locale, and to parse the fixeddepositamountenteredbytheuser.Forsimplicity,currencyconversionisnotappliedonthefixeddepositamount; the currency symbol that applies to the user’s locale is simply appended to the fixed depositamount.

Examplelisting13-19–AmountFormatter-aFormatterimplementationProject–ch13-converter-formatter-bankappSourcelocation–src/main/java/sample/spring/chapter13/formatter

packagesample.spring.chapter13.formatter;importjava.text.ParseException;importjava.util.Locale;importorg.springframework.format.Formatter;publicclassAmountFormatterimplementsFormatter<Long>{@OverridepublicStringprint(Longobject,Localelocale){StringreturnStr=object.toString()+"USD";if(locale.getLanguage().equals(newLocale("de").getLanguage())){returnStr=object.toString()+"EURO";}returnreturnStr;}@OverridepublicLongparse(Stringtext,Localelocale)throwsParseException{Stringstr[]=text.split("");returnLong.parseLong(str[0]);}}

Page 469: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

AmountFormatterimplementsFormatter<Long>interface,whichmeansthattheAmountFormatterappliesto Long type objects. The print method converts the Long type object (representing the fixed depositamount) to a String value that is displayed to the user.Based on the language code obtained from thelocale,theprintmethodsimplyappendsUSD(forenlanguagecode)orEURO(fordelanguagecode)tothefixeddepositamount.Forinstance,ifthefixeddepositamountis1000andthelanguagecodeisde,theprintmethodreturns‘1000EURO’.Theparsemethodtakesthefixeddepositamountenteredbytheuser(like,‘1000EURO’)andconvertsitintoaLongtypeobjectbysimplyextractingthefixeddepositamountfromtheuserenteredvalue.

Let’snowlookathowtoconfigureacustomformatter.

ConfiguringacustomFormatterYoucanregistercustomformatterswiththeFormattingConversionServiceusingtheformatterspropertyofFormattingConversionServiceFactoryBean,asshownhere:

Examplelisting13-20–RegisteringacustomFormatterwithFormattingConversionService<beans.....>.....<mvc:annotation-drivenconversion-service="myConversionService"/>.....<beanid="myConversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><propertyname="formatters"><set><beanclass="sample.spring.chapter13.formatter.AmountFormatter"/></set></property></bean></beans>AmountFormatterregisteredwiththeFormattingConversionServiceisappliedtoalltheLongtypefieldsduringdatabindingandrendering.

Youcancontrol thefieldsonwhichaFormatterappliesbyusingSpring’sAnnotationFormatterFactory.AnAnnotationFormatterFactory implementation creates formatters for fields that are annotated with aparticularannotation.Let’sseehowwecanuseAnnotationFormatterFactorytoformatonlytheLongtypefieldsannotatedwith@AmountFormatannotation.

CreatingAnnotationFormatterFactorytoformatonly@AmountFormatannotatedfieldsThefollowingexamplelistingshowsthedefinitionof@AmountFormatannotation:

Examplelisting13-21–AmountFormatannotationProject–ch13-converter-formatter-bankappSourcelocation–src/main/java/sample/spring/chapter13/formatter

packagesample.spring.chapter13.formatter;

Page 470: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

.....@Target(value={ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceAmountFormat{}In theaboveexample listing, the@Targetannotationspecifies that the@AmountFormat annotation canonlyappearonfields.

The following example listing shows the implementation of AnnotationFormatterFactory that createsformattersforfieldsannotatedwith@AmountFormatannotation:

Examplelisting13-22–AmountFormatAnnotationFormatterFactoryclassProject–ch13-converter-formatter-bankappSourcelocation–src/main/java/sample/spring/chapter13/formatter

packagesample.spring.chapter13.formatter;importorg.springframework.format.AnnotationFormatterFactory;importorg.springframework.format.Parser;importorg.springframework.format.Printer;publicclassAmountFormatAnnotationFormatterFactoryimplementsAnnotationFormatterFactory<AmountFormat>{publicSet<Class<?>>getFieldTypes(){Set<Class<?>>fieldTypes=newHashSet<Class<?>>(1,1);fieldTypes.add(Long.class);returnfieldTypes;}publicParser<?>getParser(AmountFormatannotation,Class<?>fieldType){returnnewAmountFormatter();}publicPrinter<?>getPrinter(AmountFormatannotation,Class<?>fieldType){returnnewAmountFormatter();}}In the above example listing, AmountFormatAnnotationFormatterFactory implementsAnnotationFormatterFactory<AmountFormat> interface, which means that theAmountFormatAnnotationFormatterFactorycreatesformattersforfieldsannotatedwith@AmountFormatannotation.

ThegetFieldTypesmethodreturnsthefieldtypesthatmaybeannotatedwith@AmountFormatannotation.ThegetFieldTypesmethodintheaboveexamplelistingreturnsasingletype,Longtype,whichmeansthatonlyaLongtypefieldthatisannotatedwith@AmountFormatannotationisconsideredforformattingby

Page 471: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

the formatters created by the AmountFormatAnnotationFormatterFactory. The getParser and getPrintermethodsreturnformattersforfieldsthatareannotatedwith@AmountFormatannotation.YoushouldnotethattheFormatterinterfaceisasub-interfaceofParserandPrinterinterfaces.

ConfiguringAnnotationFormatterFactoryimplementationAsincaseofFormattersconfiguration,anAnnotationFormatterFactoryimplementationisregisteredwithFormattingConversionServiceviaformatterspropertyofFormattingConversionServiceFactoryBean:

Examplelisting13-23–AmountFormatAnnotationFormatterFactoryconfigurationProject–ch13-converter-formatter-bankappSourcelocation–src/main/webapp/WEB-INF/spring<beans.....>.....<mvc:annotation-drivenconversion-service="myConversionService"/>.....<beanid="myConversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><propertyname="formatters"><set><beanclass="sample.spring.chapter13.formatter.AmountFormatAnnotationFormatterFactory"/></set></property></bean></beans>Now thatwehave seenhow touseAnnotationFormatterFactory to enable formatting of fields that areannotatedwith a specific annotation, let’s look at how it is used in ch13-converter-formatter-bankappproject.

The following figure shows theweb page of ch13-converter-formatter-bankapp project that shows thelistsoffixeddeposits:

Page 472: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure13-4 -The ‘Deposit amount’ column showsUSDorEUROdepending upon the language codeobtainedfromtheuser’scurrentlocale

TheabovefigureshowsthatUSDisappendedtothefixeddepositamountifthelanguagechosenbytheuserisEnglish.IfyouswitchthelanguagetoGerman,theUSDwillbereplacedbyEURO.Inexamplelisting13-19,wesawthat theAmountFormattercontained the logic toshowUSDorEUROdependinguponthelanguagecodeobtainedfromtheuser’scurrentlocale.

ToensurethattheformattersconfiguredwiththeFormattingConversionServiceareinvokedduringpagerenderingandformsubmission,Spring’staglibrarytags(like,<eval>and<input>)havebeenusedintheJSPpagesofch13-converter-formatter-bankappproject.

Let’snowlookathowSpringWebMVCsimplifiesuploadingfiles.

Page 473: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

13-6FileuploadsupportinSpringWebMVCYou can handle multipart requests in your Spring Web MVC applications by configuring aMultipartResolver.Springprovides the followingout-of-the-box implementationsofMultipartResolverinterfacethatyoucanuseinyourwebapplications:

§CommonsMultipartResolver–basedonApacheCommonsFileUploadlibrary

§StandardServletMultipartResolver–basedonServlet3.0PartAPI

Whenamultipartrequestisreceived,DispatcherServletusestheconfiguredMultipartResolver towraptheHttpServletRequest intoaMultipartHttpServletRequest instance. InSpringWebMVC, an uploadedfile is represented by the MultipartFile object. The controller responsible for handling file uploadsaccesses the uploaded file using methods defined by the MultipartHttpServletRequest or by directlyaccessingtheMultipartFileobject.

Let’sfirstlookatasamplewebapplicationthatusesCommonsMultipartResolverforuploadingfiles.

IMPORT chapter 13/ch13-commons-file-upload (This project shows how to useCommonsMultipartResolver to upload files. As CommonsMultipartResolver uses Apache CommonsFileUploadlibrary,theprojectisdependentoncommons-fileuploadJARfile.)

UploadingfilesusingCommonsMultipartResolverThefollowingexamplelistingshowsthefileuploadformthatisdisplayedbych13-commons-file-uploadproject:

Examplelisting13-24–uploadForm.jsp–showstheuploadformProject–ch13-commons-file-uploadSourcelocation–src/main/webapp/WEB-INF/jsp

.....<formmethod="post"action="/ch13-commons-file-upload/uploadFile"enctype="multipart/form-data"><tablestyle="padding-left:200px;"><tr><tdcolspan="2"><c:outvalue="${uploadMessage}"/></td></tr><tr><td><b>Selectthefiletobeuploaded:&nbsp;</b></td><td><inputtype="file"name="myFileField"/></td></tr><tr><tdcolspan="2"align="center"><inputtype="button"value="Uploadfile"onclick="document.forms[0].submit();"/></td></tr></table></form>.....

Page 474: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Theaboveexample listingshows that theenctypeattributeof<form>element is set tomultipart/form-data, which means that the form submission results in sending multipart request to the server. TheuploadMessage request attribute shows the success or failuremessage after the user selects a file andclicksthe‘Uploadfile’button.

The following example listing shows the configuration of CommonsMultipartResolver that resolvesmultipartrequests:

Examplelisting13-25–fileupload-config.xml–CommonsMultipartResolverconfigurationProject–ch13-commons-file-uploadSourcelocation–src/main/webapp/WEB-INF/spring

<beanid="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><propertyname="maxUploadSize"value="100000"/><propertyname="resolveLazily"value="true"/></bean>It is important to note that the MultipartResolver implementation must be configured with id asmultipartResolver in thewebapplicationcontextXMLfile.ThemaxUploadSizeproperty specifies themaximumsize (inbytes)of the file thatcanbeuploaded. Ifyouattempt touploada filewhosesize isgreaterthan100KB,theCommonsMultipartResolvershownintheaboveexamplelistingwillthrowanexception. If an exception is thrown by the CommonsMultipartResolver instance, the controllerresponsible for handling the file upload doesn’t get the opportunity to handle the exception. For thisreason,theresolveLazilypropertyissettotrue.IftheresolveLazilypropertyissettotrue,themultipartrequestisresolvedonlywhentheuploadedfileisaccessedbythecontroller.Thisgivestheopportunitytothecontrollertohandleexceptionsthatoccurduringmultipartrequestresolution.

ThefollowingexamplelistingshowstheFileUploadControllerthathandlesfileuploads:

Examplelisting13-26–FileUploadControllerProject–ch13-commons-file-uploadSourcelocation–src/main/java/sample/spring/chapter13/web

packagesample.spring.chapter13.web;importorg.springframework.web.multipart.MultipartFile;.....publicclassFileUploadController{.....@RequestMapping(value="/uploadFile",method=RequestMethod.POST)publicModelAndViewhandleFileUpload(@RequestParam("myFileField")MultipartFilefile)throwsIOException{ModelMapmodelData=newModelMap();if(!file.isEmpty()){//--savetheuploadedfileonthefilesystemStringsuccessMessage="Filesuccessfullyuploaded";

Page 475: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

modelData.put("uploadMessage",successMessage);returnnewModelAndView("uploadForm",modelData);}.....}@ExceptionHandler(value=Exception.class)publicModelAndViewhandleException(){.....}}FileUploadController’s handleFileUpload method accepts an argument of type MultipartFile whichidentifies the uploaded file. Notice that the @RequestParam annotation specifies name of the <inputtype=”file”.....>fieldintheuploadForm.jsppage(referexamplelisting13-24).Ifthefileissuccessfullyuploaded, 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 uploadprocess.Forinstance,ifthefilesizeisgreaterthan100KB,anerrormessageisshowntotheuser.

Now that we have seen how to use CommonsMultipartResolver to upload files, let’s look at how touploadfilesusingStandardServletMultipartResolver.

IMPORT chapter 13/ch13-servlet3-file-upload (This project shows how to useStandardServletMultipartResolvertouploadfiles.)

UploadingfilesusingStandardServletMultipartResolverThesupportforhandlingmultipartrequestisprovidedout-of-the-boxinServlet3.Ifyouwanttousethemultipart support provided by Servlet 3, enable multipart request handling by specifying <multipart-config>elementintheDispatcherServletconfiguration,andconfigureStandardServletMultipartResolverin the web application context XML file. Unlike, CommonsMultipartResolver,StandardMultipartResolverdoesn’tdefineanyproperties.

ThefollowingexamplelistingshowstheDispatcherServletconfigurationinweb.xmlfile:

Examplelisting13-27–web.xmlProject–ch13-servlet3-file-uploadSourcelocation–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,thefileuploadservletcanhandlemultipartrequests.The

Page 476: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

<max-file-size>elementspecifiesthemaximumfilesizethatcanbeuploaded.Noticethatthemaximumfilesizeisnowspecifiedaspartof<multipart-config>element.

Page 477: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

13-7SummaryInthischapter,welookedatsomeoftheimportantfeaturesofSpringWebMVCframeworkthatsimplifydevelopingwebapplications.Inthenextchapter,we’lllookathowtosecureSpringapplicationsusingSpringSecurityframework.

Page 478: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Chapter14–SecuringapplicationsusingSpringSecurity

Page 479: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

14-1IntroductionSecurityisanimportantaspectofanyapplication.SpringSecurityisbuiltontopofSpringFramework,andprovidesacomprehensiveframeworkforsecuringSpring-basedapplications.Inthischapter,we’lllookathowtouseSpringSecurityframeworkto:

§authenticateusers

§implementwebrequestsecurity,

§implementmethod-levelsecurity

§securedomainobjectsusingACL(AccessControlList)basedsecurity

Let’sbeginby lookingat theMyBankwebapplication’ssecurity requirements thatwe’lladdressusingSpringSecurity.

Page 480: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

14-2SecurityrequirementsoftheMyBankwebapplicationTheusersoftheMyBankwebapplicationarecustomersandadministratorsthatmanagefixeddepositsinthesystem.Acustomercanopenandeditfixeddepositsbutcan’tclosethem.Anadministratorcan’tcreateoreditfixeddepositsbutcanclosefixeddepositsofcustomers.

As only authenticated users can access the MyBank web application, a login form is displayed tounauthenticatedusers:

Figure14-1-Loginformthatisdisplayedtounauthenticatedusers

Theabovefigureshowstheloginformthat isdisplayedtounauthenticatedusers.If theuserselects the‘Remember me on this computer’ checkbox, the MyBank web application remembers the credentialsenteredbytheuserandusesitforautomaticauthenticationoftheuserinfuturevisits.

When acustomer logs in,detailsof the fixed deposits associatedwith the customer are displayed, asshownhere:

Figure14-2-Fixeddepositsofthecustomeraredisplayedafterauthentication

TheabovefigureshowsaLogouthyperlinkthatthecustomercanclicktologoutfromtheMyBankwebapplication.AcustomercaneditdetailsofafixeddepositbyclickingtheEdithyperlinkcorrespondingtothatfixeddeposit.AcustomercanviewtheformforopeninganewfixeddepositbyclickingtheCreatenew FixedDeposit button. Notice that the username of the authenticated user is displayed below theLogouthyperlink.

Whenanadministratorlogsin,detailsofallthefixeddepositsinthesystemaredisplayedbytheMyBankwebapplication,asshownhere:

Page 481: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure14-3-Fixeddepositsofallthecustomeraredisplayedtoanadministrator

Intheabovefigure,anadministratorcanchoosetocloseafixeddepositbyclickingtheClosehyperlinkcorresponding to that fixed deposit. As in case of customers, theCreate new FixedDeposit button isvisible toanadministratoralso,butanattempt tosavedetailsof thenewfixeddepositwill result inasecurityexceptionthrownbytheapplication.

Let’s now look at how to address the security requirements ofMyBankweb application using SpringSecurity.

IMPORT chapter 14/ch14-bankapp-simple-security (This project represents the MyBank webapplicationthatusesSpringSecurityframeworkforaddressingsecurityrequirementsdescribedinsection14-2.)

Page 482: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

14-3SecuringMyBankwebapplicationusingSpringSecuritySpring Security framework consists of multiple modules that address various security aspects ofapplications.ThefollowingtabledescribessomeoftheimportantmodulesofSpringSecurity:

Module Description

spring-security-core DefinesthecoreclassesandinterfacesofSpringSecurityframework.ThismoduleisrequiredbyanyapplicationthatusesSpringSecurity.

spring-security-web Providessupportforsecuringwebapplications

spring-security-configLike Spring’s tx and mvc schemas, Spring Security defines a security schema thatsimplifiesconfiguringSpringSecurity features.The spring-security-configmodule isresponsibleforparsingtheelementsofthesecuritynamespace.

spring-security-taglibs DefinestagsthatyoucanusetoaccesssecurityinformationandtosecurethecontentdisplayedbyJSPpages

spring-security-acl EnablesuseofACLs(AccessControlList) tosecure instancesofdomainobjects inapplications

In this section,we’ll look at usage of spring-security-core, spring-security-web, spring-security-configandspring-security-taglibsmodules tosecure theMyBankwebapplication.Later in thischapter,we’lllookathowtousespring-security-aclmoduletosecuredomainobjectinstances.

Let’sbeginbylookingathowwebrequestsecurityisconfigured.

WebrequestsecurityconfigurationYoucanaddwebrequestsecuritytoanapplicationby:

§configuringSpring’sDelegatingFilterProxyfilterintheweb.xmlfile,and

§enablingwebrequestsecurityprovidedbytheSpringSecurityframework

Let’sfirstlookathowtoconfigureDelegatingFilterProxyfilter.

DelegatingFilterProxyfilterconfiguration

Spring Framework’s web module (represented by spring-web-4.0.0.RELEASE.jar file) defines theDelegatingFilterProxyclassthatimplementsServletAPI’sFilterinterface.ThefollowingexamplelistingshowstheconfigurationofDelegatingFilterProxyfilterintheweb.xmlfile:

Examplelisting14-1–web.xml-DelegatingFilterProxyfilterconfigurationProject–ch14-bankapp-simple-securitySourcelocation-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>

Page 483: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

The<filter-mapping>element specifies that theDelegatingFilterProxy filter ismapped to all incomingwebrequests.Thefilternamespecifiedbythe<filter-name>elementcarriesaspecialsignificanceinthecontext ofDelegatingFilterProxy filter.DelegatingFilterProxy filter delegates request processing to theSpringbeanwhosenamematchesthevalueof<filter-name>element.Intheaboveexamplelisting,webrequests received by the DelegatingFilterProxy filter are delegated to the Spring bean namedspringSecurityFilterChain in the root application context. We’ll soon see that thespringSecurityFilterChainbeaniscreatedbytheSpringSecurityframework.

Now,thatwehaveconfiguredtheDelegatingFilterProxyfilter,let’slookathowtoconfigurewebrequestsecurity.

Configuringwebrequestsecurity

The following example listing shows the application context file that uses <http> element of securityschematoconfigurewebrequestsecurity:

Examplelisting14-2–applicationContext-security.xml–websecurityconfigurationProject–ch14-bankapp-simple-securitySourcelocation-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/securityhttp://www.springframework.org/schema/security/spring-security-3.2.xsd"><httpuse-expressions="true"><intercept-urlpattern="/**"access="hasAnyRole('ROLE_CUSTOMER','ROLE_ADMIN')"/><form-login/><logout/><remember-me/><headers><cache-control/><xss-protection/></headers></http>.....</beans:beans>Theaboveexamplelistingshowsthatthespring-security-3.2.xsdschemaisreferencedbytheapplicationcontext XML file. The spring-security-3.2.xsd schema is contained in theorg.springframework.security.configpackageofspring-security-config-3.2.0.RELEASE.jarfile.

The<http>elementcontains thewebrequest securityconfiguration for theapplication.SpringSecurityframework parses the <http> element and registers a bean named springSecurityFilterChain with the

Page 484: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Springcontainer.The springSecurityFilterChain bean is responsible for handlingweb request security.TheDelegatingFilterProxy filter thatwe configured earlier (refer example listing 14-1) delegateswebrequesthandlingtothespringSecurityFilterChainbean.ThespringSecurityFilterChainbeanrepresentsaninstanceofFilterChainProxybean(referSpringSecuritydocsformoreinformation)thatcontainsachainofServletfiltersthatareaddedtothechainbythesub-elementsof<http>element.

The <intercept-url> element’s access attribute specifies a Spring EL expression that evaluates to aboolean value. If theSpringEL expression returns true, theURLsmatched by the pattern attribute areaccessibletotheuser.IftheSpringELexpressionreturnsfalse,accessisdeniedtotheURLsmatchedbythepatternattribute.SpringSecurityframeworkprovidesacoupleofbuilt-inexpressions,likehasRole,hasAnyRole,isAnonymous,andsoon.

Inexamplelisting14-2,thehasAnyRole('ROLE_CUSTOMER','ROLE_ADMIN')expressionreturnstrueif theauthenticateduserhasROLE_CUSTOMERorROLE_ADMIN role. InMyBankwebapplication,theROLE_CUSTOMER role is assigned to a customer and theROLE_ADMIN role is assigned to anadministrator.As thepattern /*matches allURLs, the <intercept-url> element in example listing 14-2specifiesthatonlyauserwithroleROLE_CUSTOMERorROLE_ADMINcanaccesstheMyBankwebapplication.YoushouldnotethattheuseofSpringELexpressionintheaccessattributeisallowedonlyifyousetthevalueofuse-expressionsattributeof<http>elementtotrue.

The<form-login>elementconfiguresaloginpagethatisusedtoauthenticateusers.Youcanusevariousattributesof<form-login>element, like login-page,default-target-url,andsoon, tocustomize the loginpage.Thelogin-pageattributespecifies theURLthat isused torender the loginpage. If the login-pageattributeisnotspecified,aloginpageisautomaticallyrenderedatthe/spring_security_loginURL.

The<logout>elementconfiguresthelogoutprocessingfeatureofSpringSecurityframework.Youcanusevariousattributesof<logout>element, like logout-url,delete-cookies, invalidate-session,andsoon, toconfigurethelogoutfunctionality.Forinstance,youcanusethedelete-cookiesattributetospecifycomma-separatednamesofcookiesthatshouldbedeletedwhentheuserlogsoutoftheapplication.Thelogout-urlattributeallowsyoutoconfiguretheURLthatperformsthelogoutprocessing.Ifyoudon’tspecifythelogout-urlattribute,thelogout-urlattributevalueissetto/j_spring_security_logoutbydefault.

The<remember-me>elementconfiguresthe‘remember-me’authenticationinwhichthewebapplicationremembers the identity of the authenticated user between sessions. When a user is successfullyauthenticated,SpringSecurityframeworkgeneratesauniquetokenthatcaneitherbestoredinapersistentstore or sent to the user in a cookie. In example listing 14-2, <remember-me> element configures acookie-basedremember-meauthenticationservice.Whentheuserrevisitsthewebapplication,thetokenisretrievedfromthecookieandisautomaticallyauthenticated.

The<headers>elementspecifiesthesecurityheadersthatareaddedtotheHTTPresponsebytheSpringSecurity framework. For instance, in example listing 14-2, the <cache-control> element adds Cache-Control,PragmaandExpiresresponseheaders,andthe<xss-protection>elementaddsX-XSS-Protectionheader.

WhenanunauthenticateduseraccessestheMyBankwebapplication,SpringSecuritydisplaystheloginpage (refer figure 14-1) configured by the <form-login> element to the user. Let’s now look at howauthenticationisperformedwhentheuserentershiscredentialsandclickstheLoginbutton.

Page 485: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

AuthenticationconfigurationWhenauserentershiscredentialsandsubmitstheloginpage,SpringSecurity’sAuthenticationManagerisresponsibleforprocessingtheauthenticationrequest.AnAuthenticationManager isconfiguredwithoneormoreAuthenticationProvidersagainstwhichtheAuthenticationManagerattemptstoauthenticateusers.For instance, if you want to authenticate users against an LDAP server, you can configure anLdapAuthenticationProvider (an implementation of AuthenticationProvider) that authenticates usersagainstanLDAPserver.

The security schema simplifies configuration of AuthenticationManager and AuthenticationProviderobjects,asshowninthefollowingexamplelisting:

Examplelisting14-3–applicationContext-security.xmlProject–ch14-bankapp-simple-securitySourcelocation-src/main/resources/META-INF/spring

<authentication-manager><authentication-provider><user-service><username="admin"password="admin"authorities="ROLE_ADMIN"/><username="cust1"password="cust1"authorities="ROLE_CUSTOMER"/><username="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 ofAuthenticationProvider)thatusesSpring’sUserDetailsServiceasaDAOtoloaduserdetails.

DaoAuthenticationProvider uses the configured UserDetailsService to load user details from the userrepository based on the supplied username. DaoAuthenticationProvider performs authentication bycomparing the login credentials supplied by the user with the user details loaded by the configuredUserDetailsService.YoushouldnotethataUserDetailsServicemayloaduserdetailsfromadatasource,aflatfileoranyotheruserrepository.

The <user-service> sub-element of <authentication-provider> configures an in-memoryUserDetailsServicethatloadsusersdefinedbythe<user>elements.Inexamplelisting14-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 theusernameassigned to theuser, thepassword attribute specifies the password assigned to the user, andauthoritiesattributespecifiestherole(s)assignedtotheuser.

Now, if you deploy the ch14-bankapp-simple-security project and access it by going to thehttp://localhost:8080/ch14-bankapp-simple-securityURL, the loginpage (refer figure14-1) of thewebapplication is displayed. If you authenticate by enteringusername as cust1 andpassword as cust1, thewebapplicationwilldisplayfixeddepositsassociatedwithcust1(referfigure14-2)user.Similarly, ifyouloginwithusernameascust2andpasswordascust2,thewebapplicationwilldisplayfixeddeposits

Page 486: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

associated with cust2 user. If you login with username as admin and password as admin, the webapplicationwilldisplayfixeddepositsofbothcust1andcust2users.

Let’snowlookathowtouseSpringSecurity’sJSPtaglibrarytoaccesssecurityinformationandtoapplysecurityconstraintsonthecontentdisplayedbyJSPpages.

SecuringJSPcontentusingSpringSecurity’sJSPtablibraryOneoftherequirementsofMyBankwebapplicationisthattheoptiontoeditafixeddeposit(referfigure14-2)isavailableonlytouserswithroleROLE_CUSTOMER.And,theoptiontocloseafixeddeposit(refer figure14-3) isavailableonly touserwith roleROLE_ADMIN.Asweneed to secureEdit andClose hyperlinks based on the authenticated user’s role, the MyBank web application uses SpringSecurity’sJSPtaglibrarytosecureJSPcontent.

Thefollowingexample listingshowsusageofSpringSecurity’sJSPtag library toaccessauthenticateduser’susername,andtosecureJSPcontentbasedontheroleoftheloggedinuser:

Examplelisting14-4–fixedDepositList.jspProject–ch14-bankapp-simple-securitySourcelocation-src/main/webapp/WEB-INF/jsp

<%@tagliburi="http://www.springframework.org/security/tags"prefix="security"%>.....<body>.....<tdstyle="font-family:'arial';font-size:12px;font-weight:bold"align="right"><ahref="${pageContext.request.contextPath}/j_spring_security_logout">Logout</a><p>Username:<security:authenticationproperty="principal.username"/></p></td>.....<tdclass="td"><security:authorizeaccess="hasRole('ROLE_CUSTOMER')"><ahref="${pageContext.request.contextPath}/fixedDeposit?.....">Edit</a></security:authorize><security:authorizeaccess="hasRole('ROLE_ADMIN')"><ahref="${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.Asmentioned earlier, if you don’tspecify 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 theMyBankwebapplication.

Page 487: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

TheaboveexamplelistingalsoshowsthattheJSPpageincludesSpringSecurity’sJSPtaglibraryusingthetaglibdirective.SpringSecurity’sAuthenticationobjectcontains informationabout theauthenticateduser.For instance, it contains informationaboutauthenticateduser’s role(s)andusername that theuserusedforauthentication.The<authentication>elementprintsthespecifiedpropertyoftheAuthenticationobject. In the above example, the principal.username property refers to the username property of theauthenticateduser.

The<authorize>elementsecurestheenclosedJSPcontentbasedontheresultofevaluationofthesecurityexpression specified by the access attribute. If the security expression evaluates to true, the enclosedcontent is rendered, otherwise the enclosed content is not rendered. In the above example listing, thehasRole(‘ROLE_CUSTOMER’)expressionreturnstrueiftheauthenticateduserhasROLE_CUSTOMERrole, and the hasRole(‘ROLE_ADMIN’) expression returns true if the authenticated user hasROLE_ADMIN role. In the aboveexample listing, thehasRole expressionhasbeenused such that theEditoptionisdisplayedonlytoauserwithROLE_CUSTOMERroleandtheCloseoptionisdisplayedonlytoauserwithROLE_ADMINrole.

Let’snowlookathowtoincorporatemethod-levelsecurityusingSpringSecurity.

SecuringmethodsOne of the requirements ofMyBank application is that a userwithROLE_ADMIN role can view the‘Create newFixedDeposit’ button (refer figure 14-3) but an attempt to save details of the new fixeddeposit will result in a security exception. This is an example in which we want to secure theFixedDepositService’ssaveFixedDepositmethodsuchthatonlyauserwithROLE_CUSTOMERrolecaninvokeit.

WealsowanttosecureothermethodsoftheFixedDepositServicesothatitisnotinvokedbyunauthorizedusers.Forinstance,cust1userloggedinwithROLE_CUSTOMERcaninvoketheFixedDepositService’scloseFixedDeposit method to close an existing fixed deposit by entering the following URL in thebrowser:

http://localhost:8080/ch14-bankapp-simple-security/fixedDeposit?fdAction=close&fixedDepositId=<fixed-fixed-id>The<fixed-deposit-id>intheaboveURListhefixeddepositidthatyouwanttoremove,ashighlightedinthefollowingfigure:

Page 488: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure14-4–FixeddepositIDofafixeddepositisdisplayedintheIDcolumn

Toaddmethod-levelsecuritytoyourapplication,youneedtodothefollowing:

§configuremethod-levelsecurityforyourapplicationbyusing<global-method-security>elementofsecurityschema

§add@Securedannotationstothemethodsthatyouwanttosecureagainstunauthorizedaccess

Let’sfirstlookatthe<global-method-security>element.

Configuringmethod-levelsecurityusing<global-method-security>element

Thefollowingexamplelistingshowsusageof<global-method-security>element:

Examplelisting14-5–applicationContext-security.xmlProject–ch14-bankapp-simple-securitySourcelocation-src/main/resources/META-INF/spring

<beans:beansxmlns="http://www.springframework.org/schema/security".....><global-method-securitysecured-annotations="enabled"/></beans:beans>

The<global-method-security> element configuresmethod-level security.The<global-method-security>elementisapplicableonlytotheapplicationcontextinwhichitisdefined.Forinstance,ifthe<global-method-security>elementisdefinedintherootwebapplicationcontextXMLfile, thenit isapplicableonly 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 theapplicationContext.xml(thatdefinesservicesandDAOs)filesconstitutetherootwebapplicationcontextXMLfiles(referweb.xmlfileofch14-bankapp-simple-securityproject); therefore, the<global-method-security>elementappliesonlytothebeansdefinedintheseapplicationcontextXMLfiles.

The <global-method-security> element’s secured-annotations attribute specifies whether the use ofSpring’s@Secured annotation should be enabled or disabled for the beans registeredwith the Spring

Page 489: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

container.Asthevalueissettoenabled,youcanuseSpring’s@Securedannotationtospecifythebeanmethodsthataresecured.

NOTEIfyouwanttosecurecontrollermethods,thendefinethe<global-method-security>elementinthewebapplicationcontextXMLfileinsteadoftherootwebapplicationcontextXMLfile.

Let’snowlookathowtosecuremethodsusingSpring’s@Securedannotation.

Specifyingsecurityconstraintsonbeanmethodsusing@Securedannotation

The following example listing shows usage of Spring’s @Secured annotation to define securityconstraintsonmethods:

Examplelisting14-6–FixedDepositServiceinterfaceProject–ch14-bankapp-simple-securitySourcelocation-src/main/java/sample/spring/chapter14/service

packagesample.spring.chapter14.service;importorg.springframework.security.access.annotation.Secured;.....publicinterfaceFixedDepositService{.....@Secured("ROLE_CUSTOMER")voidsaveFixedDeposit(FixedDepositDetailsfixedDepositDetails);.....@Secured("ROLE_ADMIN")voidcloseFixedDeposit(intfixedDepositId);@Secured("ROLE_CUSTOMER")voideditFixedDeposit(FixedDepositDetailsfixedDepositDetails);}TheaboveexamplelistingshowstheFixedDepositServiceinterfacethatdefinesmethodsthatoperateonfixed deposits. @Secured("ROLE_CUSTOMER") annotation on the saveFixedDeposit andeditFixedDeposit methods specifies that these methods can only be invoked by a user whose role isROLE_CUSTOMER. @Secured("ROLE_ADMIN") annotation on the closeFixedDeposit methodspecifiesthatthemethodcanonlybeinvokedbyauserwhoseroleisROLE_ADMIN.

NOTEBydefault,method-levelsecurityisbasedonSpringAOP.IfyouwanttouseAspectJinsteadofSpring AOP, set mode attribute of <global-method-security> element to aspectj. Also, add spring-security-aspectsmodule to your project, and specify@Secured annotations on the class instead of theinterface.

Insteadofusing@Securedannotation,youcanuseSpring’s@PreAuthorizeannotationtoapplysecurityconstraints on methods. Unlike @Secured annotation, @PreAuthorize annotation accepts securityexpressions,likehasRole,hasAnyRole,andsoon.Toenableuseof@PreAuthorizeannotation,setpre-post-annotationsattributeof<global-method-security>elementtoenabled.Thefollowingexamplelistingshowsusageof@PreAuthorizeannotation:

Page 490: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting14-6–@PreAuthorizeannotationimportorg.springframework.security.access.prepost.PreAuthorize;.....publicinterfaceSomeService{.....@PreAuthorize("hasRole('ROLE_XYZ')")voiddoSomething(.....);.....}In the above example listing, @PreAuthorize annotation specifies that the doSomething method isaccessibleonlytouserswithroleROLE_XYZ.

SpringSecurityalsosupportssecurityannotations,like@RolesAllowed,@DenyAll,@PermitAll,andsoon, defined by JSR-250 – Common Annotations. To enable use of JSR-250 security annotations, setjsr250-annotations attribute of <global-method-security> to enabled. The following example listingshowsusageof@RolesAllowedannotation:

Examplelisting14-7–@RolesAllowedannotationimportjavax.annotation.security.RolesAllowed;.....publicinterfaceSomeService{.....@RolesAllowed("ROLE_XYZ")voiddoSomething(.....);.....}In the above example listing, @RolesAllowed annotation specifies that the doSomething method isaccessibleonlytouserswithroleROLE_XYZ.

NOTEWesawearlierinthisbookthatJSR250annotations,like@PreDestroy,@PostConstruct,andsoon,arepartofJavaSE6orlater.AssecurityrelatedannotationsofJSR250arenotpartofJavaSE,youneed to add jsr250-api JAR file to your project to use @RolesAllowed, @PermitAll, and so on,annotations.

Inthissection,welookedathowtouseSpringSecuritytoauthenticateusers,securewebrequestsandimplementmethod-levelsecurity.Let’snowlookatSpringSecurity’sACLmoduleforsecuringdomainobjectinstances.

IMPORTchapter14/ch14-bankapp-db-security(ThisprojectrepresentstheMyBankwebapplicationthatusesSpringSecurity’sACLmoduleforsecuringFixedDepositDetailsinstances.)

Page 491: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

14-4MyBankweb application - securing FixedDepositDetails instancesusingSpringSecurity’sACLmoduleThech14-bankapp-db-securityprojectrepresentsavariantofMyBankwebapplicationthatusesSpringSecurity’sACLmoduletosecureFixedDepositDetailsinstances.

Let’slookathowtodeployandusech14-bankapp-db-securityproject.

Deployingandusingch14-bankapp-db-securityprojectThe ch14-bankapp-db-security project usesMySQL database to store application users, fixed depositdetailsandACLinformation.Beforedeployingthech14-bankapp-db-securityproject,createadatabasenamed securitydb in MySQL and execute the bankapp.sql script located in scripts folder of ch14-bankapp-db-securityproject.

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.TableswhosenamesbeginwithACL_storeACLrelatedinformation(moreonthesetableslaterinthischapter).FIXED_DEPOSIT_DETAILStablecontainsfixeddepositdetails.USERSandAUTHORITIEStablescontainuserandroleinformation,respectively.Thebankapp.sqlscriptalsoinsertssetupdataintoUSERS,AUTHORITIES,ACL_CLASSandACL_SIDtables.

Now, that you have setup the database for ch14-bankapp-db-security project, deploy the project onembeddedTomcat7serverbyexecutingthetomcat7:rungoalfromtheproject’sdirectory(referappendixAformoreinformationonhowtodeploywebprojectsonembeddedTomcat7server).Oncetheprojectissuccessfullydeployed,gotohttp://localhost:8080/ch14-bankapp-db-securityURL.Youshouldseetheloginpage,asshownbelow:

Figure14-5–LoginpageofMyBankwebapplication

By default, the following three users are configured for the MyBank web application: cust1(ROLE_CUSTOMERrole),cust2(ROLE_CUSTOMERrole), andadmin(ROLE_ADMIN role).Whenyouloginwithusernamecust1andpasswordascust1,you’llseethefixeddepositsassociatedwithcust1customer,asshowninthefollowingfigure:

Page 492: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Figure14-6–Listoffixeddepositsassociatedwithcustomercust1

Asnofixeddepositsarecurrentlyassociatedwithcust1, theabovefigureshowsanemptylistoffixeddeposits.Clickingthe‘CreatenewFixedDeposit’buttonopenstheformforcreatinganewfixeddeposit.Ifyoucreateanewfixeddeposit,it’llappearinthelistoffixeddeposits,asshownhere:

Figure14-7–Acustomercaneditfixeddepositsormakethemaccessibletotheadminuser.

Intheabovefigure,the‘Edit’optionallowsthecustomertoeditfixeddepositdetails,andthe‘Provideaccesstoadmin’optionmakes thefixeddepositaccessible to theadminuser.Theadminusercanonlyviewfixeddepositsthataremadeaccessiblebycustomers.Clickthe‘Provideaccesstoadmin’hyperlinktomakethefixeddepositaccessibletotheadminuser.

Now,logoutfromtheMyBankwebapplication,andloginusingadminusernameandadminaspassword.Theadminusercanviewallthefixeddepositsthatweremadeaccessiblebycustomers,asshownhere:

Figure14-8–Theadminusercancloseafixeddepositbyselectingthe‘Close’option

The above figure shows that the admin user can choose the ‘Close’ option to close the fixed deposit.ClosingafixeddepositdeletesthefixeddepositfromtheFIXED_DEPOSIT_DETAILStable.

Page 493: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

To summarize, you can login using cust1/cust1, cust2/cust2 and admin/admin credentials to see thefollowingfeaturesoftheMyBankwebapplication:

§onlycust1(ROLE_CUSTOMERrole)andcust2(ROLE_CUSTOMERrole)userscancreatefixeddeposits

§ cust1andcust2 canonly edit fixeddeposits that theyown.For instance, cust1 can’t edit a fixeddepositcreatedbycust2.

§ cust1andcust2canonlymake thefixeddeposits that theyownaccessible to theadminuser.Forinstance,cust1can’tmakeafixeddepositcreatedbycust2accessibletotheadminuser.

§adminuser(ROLE_ADMINrole)canonlyviewfixeddepositsthataremadeaccessiblebycust1andcust2users

§onlytheadminusercanclosefixeddeposits

Before delving into the implementation details ofMyBankweb application, let’s look at the standarddatabasetablesrequiredbySpringSecuritytostoreACLanduserinformation.

DatabasetablestostoreACLanduserinformationSpringSecurity’sACLmoduleprovidesdomainobjectinstancesecurity.MyBankwebapplicationusesSpring Security’s ACL module to secure instances of FixedDepositDetails. Spring Security tables(ACL_CLASS,ACL_ENTRY,ACL_OBJECT_IDENTITYandACL_SID)containpermissionsthatapplytofixeddepositsstoredintheFIXED_DEPOSIT_DETAILStable.WhenaFixedDepositDetails instanceis accessed, Spring Security’s ACL module verifies that the authenticated user has the necessarypermissionstooperateontheFixedDepositDetailsinstance.

Let’slookateachoftheSpringSecuritytablesthatareusedtostoreACLinformation.

ACL_CLASStable

ACL_CLASS table contains the fully-qualified name of domain classes whose instances we want tosecureinourapplication.IncaseofMyBankwebapplication,theACL_CLASStablecontainsthefully-qualifiednameoftheFixedDepositDetailsclass,asshownhere:

Figure14-9ACL_CLASStableTablecolumndescription

id–containstheprimarykey

class–fully-qualifiednameofthedomainclasswhoseinstanceswewanttosecure

ACL_SIDtable

ACL_SIDtable(SIDmeans‘securityidentity’)containstheprincipals(thatis,usernames)orauthorities

Page 494: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

(thatis,roles)inthesystem.IncaseofMyBankwebapplication,ACL_SIDtablecontainsadmin,cust1andcust2usernames,asshownhere:

Tablecolumndescription

id–containstheprimarykey

principal–specifieswhetherthesidcolumnstoresroleorusername.Thevaluetruespecifiesthatthesidcolumnstoresusername.Thevaluefalsespecifiesthatthesidcolumnstoresrole.

sid–containsusernameorrole

ACL_OBJECT_IDENTITYtable

ACL_OBJECT_IDENTITYtablecontainsidentitiesofdomainobjectsthatwewanttosecure.IncaseofMyBank web application, the ACL_OBJECT_IDENTITY table contains identities of fixed depositsstoredinFIXED_DEPOSIT_DETAILStable,asshownhere:

Figure14-11ACL_OBJECT_IDENTITYtable

In the above figure, the object_id_identity column contains identities of fixed deposits stored in theFIXED_DEPOSIT_DETAILStable.

Tablecolumndescription

id–containstheprimarykey

object_id_class–referstothedomainclassdefinedintheACL_CLASStable

object_id_identity–referstothedomainobjectinstanceintheFIXED_DEPOSIT_DETAILStable

parent_object – if a parent object exists for the domain object referenced by the object_id_identitycolumn,thiscolumnreferstotheidentityoftheparentobject

owner_sid–referstotheuserorrolethatownsthedomainobjectinstance

entries_inheriting–flagthatindicateswhethertheobjectinheritsACLentriesfromanyparentACLentryornot

Page 495: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

ACL_ENTRYtable

ACL_ENTRY table contains permissions (read,write, create, and soon) assigned to users ondomainobjects. In caseofMyBankwebapplication, theACL_ENTRYtablecontains permissions assigned tousersonfixeddepositsstoredinFIXED_DEPOSIT_DETAILStable,asshownhere:

Figure14-12ACL_ENTRYtable

Intheabovefigure,theacl_object_identity,maskandsidcolumnsdeterminethepermissionsassignedtoauser(orrole)onadomainobjectinstance.YoushouldnotethatanentryintheACL_ENTRYtableiscommonlyreferredtoasACE(AccessControlEntry).

Tablecolumndescription

id–containstheprimarykey

acl_object_identity – refers to the id column of the ACL_OBJECT_IDENTITY table, which in turnidentifiesthedomainobjectinstance

ace_order–specifiestheorderingoftheaccesscontrolentries

sid–referstotheidcolumnofACL_SIDtable,whichinturnidentifiestheuser(orrole)

mask–specifiesthepermissions(read,write,create,andsoon)assignedtotheuser(orrole).1meansread,2meanswrite,8meansdeleteand16meansadministrationpermission.

granting – flag that indicates whether the entry in the mask column identifies as granting access ordenyingaccess.Forinstance,ifthevalueinthemaskcolumnis1andgrantingcolumnistrue, itmeansthatthecorrespondingSIDhasreadaccess.But,ifthevalueinthemaskcolumnis1andgrantingcolumnisfalse,itmeansthatthecorrespondingSIDdoesn’thavereadaccess.

audit_success–flagthatindicateswhethertoauditsuccessfulpermissionsornot.Laterinthischapter,we’llseethatSpringSecurity’sConsoleAuditLoggercanbeusedtologsuccessfulpermissions.

audit_failure-flagthatindicateswhethertoauditfailedpermissionsornot.Laterinthischapter,we’llseethatSpringSecurity’sConsoleAuditLoggercanbeusedtologfailedpermissions.

Asexplainedsofar,thediagram14-13depictsrelationshipbetweenACLtables.Thearrowsinthefigurerepresentforeignkeyreferencesfromatable.Forinstance,theACL_OBJECT_IDENTITYtablecontains

Page 496: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

foreignkeysthatrefertoACL_CLASS,ACL_SIDandFIXED_DEPOSIT_DETAILStables.

Figure14-13 ACL tables and their relationships. The arrows represent foreign key references from atable.

Now,thatwehaveseentheACLtablesrequiredtostoreACLinformation,let’snowlookattheSpringSecuritytablesthatstoreusersandtheirrolesinformation.

USERStable

USERStablestorescredentialsofusers,asshownhere:

Figure14-14USERStableTablecolumndescription

username–usernameoftheuser

password–passwordoftheuser

enabled–flagthatindicateswhethertheuserisenabledordisabled

AUTHORITIEStable

AUTHORITIEStablecontainstheroleassignedtoeachuserdefinedintheUSERStable

Page 497: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Tablecolumndescription

username–usernameoftheuser

authority–roleassignedtotheuser

Figure14-15AUTHORITIEStable

Let’snowlookathowtheusersareauthenticatedinMyBankwebapplication.

UserauthenticationMyBank web application explicitly configures the UserDetailsService to load user details from theUSERSandAUTHORITIESdatabasetables,asshowninthefollowingexamplelisting:

Examplelisting14-8–applicationContext-security.xmlProject–ch14-bankapp-db-securitySourcelocation-src/main/resources/META-INF/spring

<authentication-manager><authentication-provideruser-service-ref="userDetailsService"/></authentication-manager><beans:beanid="userDetailsService"class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"><beans:propertyname="dataSource"ref="dataSource"/></beans:bean>Intheaboveexamplelisting,theuser-service-refattributeof<authentication-provider>elementreferstoan implementation of UserDetailsService that is responsible for loading user (and their authorities)details basedon the suppliedusername. JdbcDaoImpl is an implementationofUserDetailsService thatloadsuser(andtheirauthorities)detailsfromthedatasource(specifiedbythedataSourceproperty)usingJDBCqueries.RefertotheapplicationContext.xmlfileofch14-bankapp-db-securityprojecttoviewthedataSourcebeandefinition.Bydefault,JdbcDaoImplloadsuserdetailsfromtheUSERS(referfigure14-14)tableandauthoritiesinformationfromtheAUTHORITIES(referfigure14-15)table.Ifyoualreadyhavecustomdatabasetablesthatcontainuserandauthoritiesdetails,thensettheusersByUsernameQueryandauthoritiesByUsernameQuerypropertiesofJdbcDaoImpltoretrieveuserdetailsandtheirauthoritiesfromthesecustomtables.

TheusersByUsernameQuerypropertyspecifiestheSQLquerytoretrieveuserdetailsbasedonthegivenusername. If user details are stored in a table named MY_USERS that contains USERNAME andPASSWORD columns, you can set the following SQL query as the value of usersByUsernameQuerypropertytoretrieveuserdetails:

Page 498: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

selectUSERNAME,PASSWORD,‘true’asENABLEDfromMY_USERSwhereUSERNAME=?You should note that the columns returned by the SQL querymust beUSERNAME, PASSWORD andENABLED.Ifaparticularcolumn(like,ENABLED)doesn’texist inyourdatabase table, thenreturnadefaultvalue(like,‘true’)forthatcolumn.

TheauthoritiesByUsernameQueryproperty specifies theSQLquery to retrieveauthoritiesbasedon thegivenusername.IfauthoritydetailsarestoredinatablenamedMY_AUTHORITIESthatcontainsUSERandROLEcolumns,youcan set the followingSQLqueryas thevalueof authoritiesByUsernameQuerypropertytoretrieveauthorities:

selectUSERASUSERNAME,ROLEASAUTHORITYfromMY_AUTHORITIESwhereUSER=?YoushouldnotethatthecolumnsreturnedbytheSQLquerymustbeUSERNAMEandAUTHORITY.

Ifyourapplicationstoresencodedpasswordsinthedatabase,youcanusethe<password-encoder>sub-element of <authentication-provider> element to specify the password encoder (an implementation ofSpring’sPasswordEncoder interface) tobeused toconvert thesubmittedpasswords into theirencodedform. BCryptPasswordEncoder is a concrete implementation of PasswordEncoder that uses BCrypthashing algorithm (http://en.wikipedia.org/wiki/Bcrypt). The DaoAuthenticationProvider uses theconfigured password encoder to encode the submitted password and compare it with the passwordloadedbytheUserDetailsService.

Let’snowlookatthewebrequestsecurityconfigurationintheMyBankwebapplication.

WebrequestsecurityThe following example listing shows how web request security is configured for the MyBank webapplication:

Examplelisting14-9–applicationContext-security.xml–websecurityconfigurationProject–ch14-bankapp-db-securitySourcelocation-src/main/resources/META-INF/spring

<httpuse-expressions="true"><access-denied-handlererror-page="/access-denied"/><intercept-urlpattern="/fixedDeposit/*"access="hasAnyRole('ROLE_CUSTOMER','ROLE_ADMIN')"/><form-loginlogin-page="/login"authentication-failure-handler-ref="authFailureHandler"/><logout/>....</http><beans:beanid="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), you’ll notice that we have added someadditionalconfigurationinformation.

The <access-denied-handler> element’s error-page attribute specifies the error page (refer to

Page 499: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

scr/main/webapp/WEB-INF/jsp/access-denied.jsppage) towhichanauthenticateduser is redirected incase the user attempts to access an unauthorized web page. The <form-login> element’s login-pageattribute specifies the URL that renders the login page. The value /login URL is mapped toLoginController (refer to LoginController class of ch14-bankapp-db-security project) that renders theloginpage(refer toscr/main/webapp/WEB-INF/jsp/login.jsppage).The authentication-failure-handler-ref attribute refers to anAuthenticationFailureHandler bean that handles authentication failures.As theabove example listing shows, MyAuthFailureHandler (an implementation ofAuthenticationFailureHandler) is responsible for handling authentication failures in MyBank webapplication.ThefollowingexamplelistingshowstheimplementationofMyAuthFailureHandlerclass:

Examplelisting14-10–MyAuthFailureHandlerclassProject–ch14-bankapp-db-securitySourcelocation-src/main/java/sample/spring/chatper14/security

packagesample.spring.chapter14.security;.....importorg.springframework.security.core.AuthenticationException;importorg.springframework.security.web.authentication.AuthenticationFailureHandler;publicclassMyAuthFailureHandlerimplementsAuthenticationFailureHandler{@OverridepublicvoidonAuthenticationFailure(HttpServletRequestrequest,HttpServletResponseresponse,AuthenticationExceptionexception)throwsIOException,ServletException{request.setAttribute("exceptionMsg",exception.getMessage());response.sendRedirect(request.getContextPath()+"/login?exceptionMsg="+exception.getMessage());}}AuthenticationFailureHandler interface defines an onAuthenticationFailure method which is invokedwhen authentication fails. The onAuthenticationFailure method accepts an instance ofAuthenticationException that represents an authentication failure. In the above example listing, theonAuthenticationFailuremethodredirectstheusertotheloginpageandpassestheexceptionmessageasaquerystringparameter.Ifyouenterwrongcredentials(orentercredentialsofauserwhoisdisabledinthesystem)ontheloginpageofMyBankwebapplication,you’llnoticethattheMyAuthFailureHandler’sonAuthenticationFailuremethod is invoked.For instance, ifyouenterwrongcredentials,you’ll see themessage‘Badcredentials’.

Let’snowlookatACL-specificconfigurationinMyBankwebapplication.

JdbcMutableAclServiceconfigurationAs ACL permissions are stored in database tables, the MyBank web application uses Spring’sJdbcMutableAclService to perform CRUD (CreateReadUpdateDelete) operations on ACLs in thetables.ThefollowingexamplelistingshowstheconfigurationofJdbcMutableAclService:

Page 500: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Examplelisting14-11–applicationContext-security.xml–JdbcMutableAclServiceconfigurationProject–ch14-bankapp-db-securitySourcelocation-src/main/resources/META-INF/spring

<beans:beanid="aclService"class="org.springframework.security.acls.jdbc.JdbcMutableAclService"><beans:constructor-argref="dataSource"/><beans:constructor-argref="lookupStrategy"/><beans:constructor-argref="aclCache"/></beans:bean>The above example listing shows references to dataSource, lookupStrategy and aclCache beans arepassed to the JdbcMutableAclService’s constructor.Let’s now look at howdependencies (dataSource,lookupStrategyandaclCache)ofJdbcMutableAclServiceareconfigured.

The dataSource bean identifies the javax.sql.DataSource that holds the ACL tables (refer to thedataSourcebeandefinitionintheapplicationContext.xmlfileformoredetails).

The lookupStrategy bean represents an implementation of Spring’s LookupStrategy interface that isresponsible for looking upACL information. The following example listing shows the lookupStrategybeandefinition:

Examplelisting14-12–applicationContext-security.xml–LookupStrategyconfigurationProject–ch14-bankapp-db-securitySourcelocation-src/main/resources/META-INF/spring

<beans:beanid="lookupStrategy"class="org.springframework.security.acls.jdbc.BasicLookupStrategy"><beans:constructor-argref="dataSource"/><beans:constructor-argref="aclCache"/><beans:constructor-arg><beans:beanclass="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl"><beans:constructor-arg><beans:beanclass="org.springframework.security.core.authority.SimpleGrantedAuthority"><beans:constructor-argvalue="ROLE_ADMIN"/></beans:bean></beans:constructor-arg></beans:bean></beans:constructor-arg><beans:constructor-arg><beans:beanclass="org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy"><beans:constructor-arg><beans:beanclass="org.springframework.security.acls.domain.ConsoleAuditLogger"/></beans:constructor-arg>

Page 501: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

</beans:bean></beans:constructor-arg></beans:bean>In the above example listing, Spring’s BasicLookupStrategy (an implementation ofLookupStrategy 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 isstored in custom database tables, then you can customize the JDBC queries by setting selectClause,lookupPrimaryKeysWhereClause, lookupObjectIdentitiesWhereClause andorderByClause properties ofBasicLookupStrategy. For more details on these properties, please refer to the API documentation ofSpringSecurity.

BasicLookupStrategy’s constructor accepts arguments of typeDataSource (represents the database thatcontains the ACL tables), AclCache (represents the ACL caching layer),AclAuthorizationStrategy (represents the strategy todetermine if aSIDhas thepermissions toperformadministrative actions on the ACL entries of a domain object instance), andPermissionGrantingStrategy (strategy to grant or deny access to secured objects depending on thepermissionsassignedtoSIDs).

In the above example listing, the AclAuthorizationStrategyImpl class implementsAclAuthorizationStrategy. The AclAuthorizationStrategyImpl’s constructor accepts an instance ofGrantedAuthoritythatspecifiestherolethatcanperformadministrativeactions(like,changingownershipofanACLentry)ontheACLentries(representedbyanobjectoftypeMutableAcl)ofadomainobjectinstance. In the above example listing, ROLE_ADMIN role is passed to theAclAuthorizationStrategyImpl, which means that a user with ROLE_ADMIN role can performadministrativeactionsonACLentries.Laterinthischapter,we’llseethattheAclAuthorizationStrategysecurestheMutableAclinstancefromunauthorizedmodification.

In the above example listing, the DefaultPermissionGrantingStrategy implementsPermissionGrantingStrategy.TheDefaultPermissionGrantingStrategy’sconstructoracceptsaninstanceofAuditLogger that logs success and/or failure in granting permissions for an ACL entry in theACL_ENTRY table. In the above example listing, the ConsoleAuditLogger (an implementation ofAuditLogger thatwriteson theconsole) logssuccessfulpermissions ifaudit_successcolumn’svalue issettotrue(thatis,1),andlogsfailedpermissionsifaudit_failurecolumn’svalueissettotrue(thatis,1).Forinstance,thefollowingmessageshowsoutputfromtheConsoleAuditLoggeronsuccessfulpermissiontoanACLentry:GRANTEDduetoACE: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 inexample listing 14-12) that represents a cache for ACLs. The following example listing shows theaclCachebeandefinitionthatisusedbyBasicLookupStrategytocacheACLs:

Examplelisting14-13–applicationContext-security.xml–CacheconfigurationProject–ch14-bankapp-db-securitySourcelocation-src/main/resources/META-INF/spring

<beans:bean id="aclCache"

Page 502: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

class="org.springframework.security.acls.domain.EhCacheBasedAclCache"><beans:constructor-arg><beans:beanclass="org.springframework.cache.ehcache.EhCacheFactoryBean"><beans:propertyname="cacheManager"><beans:beanclass="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/></beans:property><beans:propertyname="cacheName"value="aclCache"/></beans:bean></beans:constructor-arg></beans:bean>EhCacheBasedAclCache is an implementation ofAclCache that usesEhCache (http://ehcache.org/) forcaching ACLs. EhCacheFactoryBean is Spring FactoryBean that creates an instance ofnet.sf.ehcache.EhCache. The cacheManager property of EhCacheFactoryBean specifies thenet.sf.ehcache.CacheManager instance that is responsibleformanagingthecache. In theaboveexamplelisting, EhCacheManagerFactoryBean is a Spring FactoryBean that creates an instance ofnet.sf.ehcache.CacheManager.TheEhCacheFactoryBean’scacheNamepropertyreferstothecacheregiontobecreatedinEhCacheforstoringACLs.

Now,thatwehaveconfiguredJdbcMutableAclServicetoperformCRUDoperationsonACLs,let’slookat the method-level security configuration that uses ACLs loaded by JdbcMutableAclService forauthorizationpurposes.

Method-levelsecurityconfigurationThefollowingexamplelistingshowsmethod-levelsecurityconfigurationintheMyBankwebapplication:

Examplelisting14-14–applicationContext-security.xml–Method-levelsecurityconfigurationProject–ch14-bankapp-db-securitySourcelocation-src/main/resources/META-INF/spring

<global-method-securitypre-post-annotations="enabled"><expression-handlerref="expressionHandler"/></global-method-security>The <global-method-security> element’s pre-post-annotations attribute value is set to enabled, whichenables use of @PreAuthorize (explained earlier in this chapter), @PostAuthorize, @PostFilter [email protected],the<expression-handler>elementreferstotheexpressionHandlerbeanthatconfiguresaSecurityExpressionHandlerinstance.

ASecurityExpressionHandlerisusedbySpringSecuritytoevaluatesecurityexpressions, likehasRole,hasAnyRole,hasPermission,andsoon.ThefollowingexamplelistingshowstheexpressionHandlerbeandefinition that configures a DefaultMethodSecurityExpressionHandler (a SecurityExpressionHandlerimplementation)instance:

Examplelisting14-15–applicationContext-security.xml–SecurityExpressionHandlerconfigurationProject–ch14-bankapp-db-securitySourcelocation-src/main/resources/META-INF/spring

<beans:beanid="expressionHandler"class="org.springframework.security.access.expression.method.

Page 503: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

DefaultMethodSecurityExpressionHandler"><beans:propertyname="permissionEvaluator"ref="permissionEvaluator"/><beans:propertyname="permissionCacheOptimizer"><beans:beanclass="org.springframework.security.acls.AclPermissionCacheOptimizer"><beans:constructor-argref="aclService"/></beans:bean></beans:property></beans:bean><beans:beanid="permissionEvaluator"class="org.springframework.security.acls.AclPermissionEvaluator"><beans:constructor-argref="aclService"/></beans:bean>In the above example listing, the permissionEvaluator property refers to an instance ofAclPermissionEvaluator instance that uses ACLs to evaluate security expressions. ThepermissionCacheOptimzer property refers to an instance of AclPermissionCacheOptimizer that loadsACLsinbatchestooptimizeperformance.

Let’snowlookathowdomainobjectinstancesecurityisachievedintheMyBankwebapplication.

DomainobjectinstancesecurityWe saw earlier that the @PreAuthorize annotation specifies role-based security constraints on themethods. If a@PreAuthorize annotated method accepts a domain object instance as an argument, the@PreAuthorizeannotationcanspecifytheACLpermissionsthattheauthenticatedusermusthaveonthedomainobject instance to invoke themethod.The followingexample listing shows the@PreAuthorizeannotationthatspecifiesACLpermissions:

Example listing 14-16 – FixedDepositService interface – @PreAuthorize annotation with ACLpermissionsProject–ch14-bankapp-db-securitySourcelocation-src/main/java/sample/spring/chatper14/service

packagesample.spring.chapter14.service;importorg.springframework.security.access.prepost.PreAuthorize;importsample.spring.chapter14.domain.FixedDepositDetails;.....publicinterfaceFixedDepositService{.....@PreAuthorize("hasPermission(#fixedDepositDetails,write)")voideditFixedDeposit(FixedDepositDetailsfixedDepositDetails);}Intheaboveexamplelisting,theFixedDepositService’seditFixedDepositmethodacceptsaninstanceofFixedDepositDetails. In the hasPermission expression, #fixedDepositDetails represents an expressionvariable that refers to the FixedDepositDetails instance passed to the editFixedDeposit method. The

Page 504: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

hasPermission expression evaluates to true if the authenticated user has write permission on theFixedDepositDetails instance passed to the editFixedDeposit method. At runtime, the hasPermissionexpression isevaluatedby theconfiguredAclPermissionEvaluator (refer example listing14-15). If thehasPermissionevaluatestotrue,theeditFixedDepositmethodisinvoked.

If a method accepts a domain object identifier (instead of the actual domain object instance) as anargument,youcanstillspecifyACLpermissionsthatapplytothedomainobjectinstancereferredbytheidentifier. The following example listing shows the provideAccessToAdmin method that acceptsfixedDepositId(whichuniquelyidentifiesaFixedDepositDetailsinstance)asargument:

Examplelisting14-17–FixedDepositServiceinterface–@PreAuthorizeannotationusageProject–ch14-bankapp-db-securitySourcelocation-src/main/java/sample/spring/chatper14/service

packagesample.spring.chapter14.service;importorg.springframework.security.access.prepost.PreAuthorize;.....publicinterfaceFixedDepositService{.....@PreAuthorize("hasPermission(#fixedDepositId,'sample.spring.chapter14.domain.FixedDepositDetails',write)")voidprovideAccessToAdmin(intfixedDepositId);}Intheaboveexamplelisting,#fixedDepositIdexpressionvariablereferstothefixedDepositIdargumentpassedtotheprovideAccessToAdminmethod.As thefixedDepositIdargument identifiesan instanceofFixedDepositDetailsobject,thefully-qualifiednameoftheFixedDepositDetailsclassisspecifiedasthesecond argument of hasPermission expression. The hasPermission(#fixedDepositId,‘sample.spring.chapter14.domain.FixedDepositDetails’,write)evaluatestotrueif theauthenticateduserhas write permission on the FixedDepositDetails instance identified by the fixedDepositId argumentpassedtotheprovideAccessToAdminmethod.

Itisalsopossibletocombinemultiplesecurityexpressionstoformamorecomplexsecurityexpression,asshowninthefollowingexamplelisting:

Examplelisting14-18–FixedDepositServiceinterface–@PreAuthorizeannotationusageProject–ch14-bankapp-db-securitySourcelocation-src/main/java/sample/spring/chatper14/service

packagesample.spring.chapter14.service;importorg.springframework.security.access.prepost.PreAuthorize;.....publicinterfaceFixedDepositService{.....@PreAuthorize("hasPermission(#fixedDepositId,'sample.spring.chapter14.domain.FixedDepositDetails',read)or"

Page 505: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

+"hasPermission(#fixedDepositId,'sample.spring.chapter14.domain.FixedDepositDetails',admin)")FixedDepositDetailsgetFixedDeposit(intfixedDepositId);.....}Intheaboveexamplelisting,thetwohasPermissionexpressionshavebeencombinedusingoroperatortoformamoresophisticatedsecurityexpression.ThegetFixedDepositmethodwillbeinvokedonlyif theauthenticateduserhas reador admin permission on the FixedDepositDetails instance identified by thefixedDepositIdargument.

If a method returns a list of domain object instances, you can filter the results by using@PostFilterannotation.Thefollowingexamplelistingshowsusageof@PostFilterannotation:

Examplelisting14-19–FixedDepositServiceinterface–@PostFilterannotationusageProject–ch14-bankapp-db-securitySourcelocation-src/main/java/sample/spring/chatper14/service

packagesample.spring.chapter14.service;importorg.springframework.security.access.prepost.PostFilter;.....publicinterfaceFixedDepositService{.....@PreAuthorize("hasRole('ROLE_ADMIN')")@PostFilter("hasPermission(filterObject,read)orhasPermission(filterObject,admin)")List<FixedDepositDetails>getAllFixedDeposits();.....}Like@PreAuthorize annotation,@PostFilter specifies a security expression. If amethod is annotatedwith@PostFilter annotation, Spring Security iterates over the collection returned by the method andremoves the elements forwhich the specified security expression returns false. In the above examplelisting, Spring Security iterates over the collection of FixedDepositDetails instances returned by thegetAllFixedDepositsmethodandremovestheinstancesforwhichtheauthenticateduserdoesn’thavereadoradminpermission.The term filterObject in the hasPermission expression of@PostFilter annotationreferstothecurrentobjectinthecollection.NoticethatthegetAllFixedDepositsmethodisalsoannotatedwith@PreAuthorizeannotation,whichindicatesthatthegetAllFixedDepositsmethodisonlyinvokediftheauthenticateduserhasROLE_ADMINrole.

Wesawearlierthatacustomer(ROLE_CUSTOMERrole)makesafixeddepositavailabletotheadminuser(ROLE_ADMINrole)byclickingthe‘Provideaccesstoadmin’hyperlink(referfigure14-7).Whenthecustomerclicksthe‘Provideaccesstoadmin’,applicationgrantsread,adminanddeletepermissionsonthefixeddeposittotheadminuser.We’llseelaterinthischapterhowthisisdoneprogrammatically.The FixedDepositService’s getAllFixedDeposits method is invokedwhen a user with ROLE_ADMINrolevisitsthewebpagethatshowslistsoffixeddeposits(referfigure14-8).Astheadminusershouldonlybeabletoseefixeddepositsforwhichcustomershavegrantedpermissions,thegetAllFixedDepositsmethod is annotated with @PostFilter annotation to remove fixed deposits on which the admin user

Page 506: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

doesn’thavereadoradminpermission.

Let’snowlookathowtoprogrammaticallymanageACLentries.

ManagingACLentriesprogrammaticallyYoucanmanageACLentriesprogrammaticallybyusingtheJdbcMutableAclServicethatwasconfiguredintheapplicationcontextXMLfile(referexamplelisting14-11).

When a customer creates a new fixed deposit, read andwrite permissions on the newly created fixeddeposit are granted to the customer.When a customer clicks the ‘Provide access to admin’ hyperlinkcorrespondingtoafixeddeposit,theMyBankwebapplicationgrantsread,adminanddeletepermissionsonthefixeddeposittotheadminuser.

ThefollowingexamplelistingshowstheFixedDepositServiceImpl’sprovideAccessToAdminmethodthatisinvokedwhenthe‘Provideaccesstoadmin’hyperlinkisclicked:

Examplelisting14-20–FixedDepositServiceImplclass–addingACLpermissionsProject–ch14-bankapp-db-securitySourcelocation-src/main/java/sample/spring/chatper14/service

packagesample.spring.chapter14.service;importorg.springframework.security.acls.domain.*;importorg.springframework.security.acls.model.*;.....@ServicepublicclassFixedDepositServiceImplimplementsFixedDepositService{.....@AutowiredprivateMutableAclServicemutableAclService;@OverridepublicvoidprovideAccessToAdmin(intfixedDepositId){addPermission(fixedDepositId,newPrincipalSid("admin"),BasePermission.READ);addPermission(fixedDepositId,newPrincipalSid("admin"),BasePermission.ADMINISTRATION);addPermission(fixedDepositId,newPrincipalSid("admin"),BasePermission.DELETE);}privatevoidaddPermission(longfixedDepositId,Sidrecipient,Permissionpermission){.....}}Intheaboveexamplelisting,theprovideAccessToAdminmethodusestheaddPermissionmethodtograntread, admin and delete permissions to the admin user. The following arguments are passed to theaddPermissionmethod:

§ fixedDepositId–uniquely identifies theFixedDepositDetails instanceonwhomwewant tograntpermissions

§ PrincipalSid object - represents the SID (that is, the user or role) whom we want to grant

Page 507: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

permissions.ThePrincipalSidclassimplementsSpringSecurity’sSidinterface.

§ permission to grant – The BasePermission class defines constants, like READ,ADMINISTRATION,DELETE,andsoon,representingstandardpermissionsthatwecangranttoPrincipalSid.TheBasePermissionclassimplementsSpringSecurity’sPermissioninterface.

ThefollowingexamplelistingshowstheimplementationofaddPermissionmethod:

Examplelisting14-21–FixedDepositServiceImplclass–addingACLpermissionsProject–ch14-bankapp-db-securitySourcelocation-src/main/java/sample/spring/chatper14/service

packagesample.spring.chapter14.service;importorg.springframework.security.acls.domain.*;importorg.springframework.security.acls.model.*;.....@ServicepublicclassFixedDepositServiceImplimplementsFixedDepositService{.....@AutowiredprivateMutableAclServicemutableAclService;.....privatevoidaddPermission(longfixedDepositId,Sidrecipient,Permissionpermission){MutableAclacl;ObjectIdentityoid=newObjectIdentityImpl(FixedDepositDetails.class,fixedDepositId);try{acl=(MutableAcl)mutableAclService.readAclById(oid);}catch(NotFoundExceptionnfe){acl=mutableAclService.createAcl(oid);}acl.insertAce(acl.getEntries().size(),permission,recipient,true);mutableAclService.updateAcl(acl);}.....}As JdbcMutableAclService class implements MutableAclService interface, JdbcMutableAclServiceinstanceisautowiredintotheFixedDepositServiceImplclass.

Tograntpermissions,theaddPermissionmethodfollowsthesesteps:

1) declaresanobjectof typeMutableAcl.AMutableAclobject representsACLentriesofadomainobjectinstance.MutableAcldefinesmethodsthatyoucanusetomodifyACLentries.

2) creates an instance of ObjectIdentityImpl by passing domain object type (which isFixedDepositDetails.class)andidentity(whichisfixedDepositId)asargumentstotheconstructor

Page 508: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

3) retrieves the ACL entries for the domain object instance by calling MutableAclService’sreadAclById method. If no ACL entries are found, the readAclById method throwsNotFoundException.

o IfNotFoundException is thrown,MutableAclService’screateAclmethod is used to create anempty instance of MutableAcl that doesn’t contain any ACL entries. This is equivalent tocreatinganentryintheACL_OBJECT_IDENTITYtable(referfigure14-11).

4) addsACLentries to theMutableAcl instanceusing insertAcemethod.TheACL entries added toMutableAclareeventuallypersistedintotheACL_ENTRYtable(referfigure14-12).Theargumentspassed to the insertAce method are - the index location where the ACL entry is to be added(corresponds to theACE_ORDERcolumn), thepermission tobe added (corresponds to theMASKcolumn), theSIDforwhomthepermission is tobeadded(corresponds to theSIDcolumn),and theflag indicating that the ACL entry is for granting or denying permission (corresponds to theGRANTINGcolumn).

5)persistschangesmadetotheMutableAclinstanceusingMutableAclService’supdateAclmethod.

The following example listing shows FixedDepositServiceImpl’s closeFixedDeposit method that isinvokedwhentheadminuserclicksthe‘Close’hyperlinktocloseafixeddeposit(referfigure14-8):

Examplelisting14-22–FixedDepositServiceImplclass–removingACLsProject–ch14-bankapp-db-securitySourcelocation-src/main/java/sample/spring/chatper14/service

packagesample.spring.chapter14.service;importorg.springframework.security.acls.domain.ObjectIdentityImpl;importorg.springframework.security.acls.model.MutableAclService;importorg.springframework.security.acls.model.ObjectIdentity;.....@ServicepublicclassFixedDepositServiceImplimplementsFixedDepositService{.....@AutowiredprivateMutableAclServicemutableAclService;.....@OverridepublicvoidcloseFixedDeposit(intfixedDepositId){fixedDepositDao.closeFixedDeposit(fixedDepositId);ObjectIdentityoid=newObjectIdentityImpl(FixedDepositDetails.class,fixedDepositId);mutableAclService.deleteAcl(oid,false);}.....}Intheaboveexamplelisting,MutableAclService’sdeleteAclmethodisusedtodeleteACLentriesofthefixed deposit identified by the ObjectIdentity instance. For instance, if the fixedDepositId is 101,

Page 509: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

deleteAclmethoddeletesallACLentriesoffixeddeposit101fromACL_ENTRY(refer figure14-12)andACL_OBJECT_IDENTITY(referfigure14-11)tables.

Let’snowlookathowMutableAclinstanceissecuredfromunauthorizedmodifications.

MutableAclandsecuritySpringSecurity’sMutableAcl interfacedefinesmethods formodifyingACLentries of a domainobjectinstance.WesawthattheMyBankwebapplicationusesMutableAcl’sinsertAcemethodtoaddanACLentry for a domain object instance (refer example listing 14-21). TheAclAuthorizationStrategyImplinstancethatwesuppliedtotheBasicLookupStrategy(referexamplelisting14-12) is used behind the scenes to ensure that the authenticated user has appropriate permissions tomodifyACLentries.

AnauthenticatedusercanmodifyACLentriesofadomainobjectinstanceifatleastoneofthefollowingconditionsistrue:

§iftheauthenticateduserownsthedomainobjectinstance,theusercanmodifytheACLentriesofthatdomainobjectinstance

§ if the authenticated user holds the authority that was passed to AclAuthorizationStrategyImpl’sconstructor. In example listing 14-12, the ROLE_ADMIN role was passed toAclAuthorizationStrategyImpl’s constructor; therefore, auserwithROLE_ADMIN role canmakechangestoACLentriesofanydomainobjectinstance.

§ if the authenticated user has BasePermission’s ADMINISTRATION permission on the domainobjectinstance.

Page 510: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

14-5SummaryIn thischapter,we lookedathow touseSpringSecurity framework to secureSpringapplications.Welooked at how to incorporateweb request security,method-level security, and domain object instancesecurity.

Page 511: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

Appendix A – Importing and deploying sample projects inEclipseIDE(orIntelliJIDEA)Inthisappendix,we’lllookathowtosetupthedevelopmentenvironment,importasampleprojectintoEclipseIDE(orIntelliJIDEA),andrunitasastandaloneapplication(ifthesampleprojectrepresentsastandalone Java application) or deploy it onTomcat 7 server (if the sample project represents awebapplication).

Page 512: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

A-1SettingupthedevelopmentenvironmentBeforesettingupthedevelopmentenvironment,youneedtodothefollowing:

·DownloadandinstallEclipseIDE(orIntelliJIDEA)–YoucandownloadtheEclipseIDEforJavaEEDevelopersfromhttp://www.eclipse.org/downloads.ToinstallEclipseIDE,allyouneedtodoistounzipthedownloadedZIPfileintoadirectory.

· Download and install Tomcat 7 server – You can download the Tomcat 7 server fromhttp://tomcat.apache.org/download-70.cgi.ItisrecommendedthatyoudownloadtheTomcat7bundledasZIPfile,andunzipthebundleintoyourlocalfilesystem.

· Download and install Maven 3 build tool – You can download Maven 3 fromhttp://maven.apache.org/download.cgi. To install Maven, all you need to do is to unzip thedownloaded ZIP file into a directory. Maven is used for converting the sample web projects thataccompanythisbookintoEclipseIDEorIntelliJIDEAprojects.

Let’slookathowtoimportasampleprojectintoEclipseIDE.

Page 513: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

A-2ImportingasampleprojectintoEclipseIDE(orIntelliJIDEA)It isrecommendedthatyoudownloadthesampleprojects thataccompanythisbookfromthefollowingGooglecodeproject:

https://code.google.com/p/getting-started-with-spring-framework-2edition/

Therestofthissectionassumesthatyouhavecreatedaspring-samplesdirectoryinyourlocalfilesystemthatcontainsallthesampleprojectsthataccompanythisbook.

Tosuccessfullyimportasampleproject,youneedtodothefollowing:

§ConverttheprojectintoanEclipseIDEorIntelliJIDEAproject§ Configure an M2_REPO classpath variable in the Eclipse IDE (or IntelliJ IDEA). M2_REPO

variable points to the localmaven repository that contains the JAR files on which the projectdepends.

Let’snowlookattheabovementionedstepsindetail.

ImportingasampleprojectEach sample project contains a pom.xml file that contains configuration of Eclipse, IntelliJ IDEA andTomcatmavenplugins.ThesepluginsareusedbymavenforconvertingasampleprojectintoEclipseIDEorIntelliJ IDEAproject,andfordeploying theprojectonanembeddedTomcat7 instance.Youshouldnote that the TomcatMaven plugin (http://tomcat.apache.org/maven-plugin.html) is configured only forsample projects that representweb applications. The pom.xml file also specifies the JAR files (likespring-core,spring-beans,andsoon)onwhichtheprojectdepends.

TocreateEclipseIDEorIntelliJIDEAspecificconfigurationfilesforthesampleproject,followthesesteps:

§ Open the command prompt and set JAVA_HOME environment variable to point to Java SDKinstallationdirectory:

C:\>setJAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0_25

§Gotothedirectorycontainingthesampleproject:

C:\>cdspring-samplesC:\spring-samples>cdch01-bankapp-xmlC:\spring-samples\ch01-bankapp-xml>

§AddpathofthebindirectoryofyourmaveninstallationtothePATHenvironmentvariable:

C:\spring-samples\ch01-bankapp-xml>setpath=%path%;C:\apache-maven-3.0.4\bin§IfyouwanttoimportthesampleprojectintoEclipseIDE,executetheeclipse:eclipsegoalofMaven

EclipsePlugin(http://maven.apache.org/plugins/maven-eclipse-plugin/):

C:\spring-samples\ch01-bankapp-xml>mvneclipse:eclipse

Executing the eclipse:eclipse goal downloads dependencies of the sample project and creates

Page 514: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

configurationfiles(like.classpathand.project)forEclipseIDE.

OR

§ Ifyouwant to import thesampleproject intoIntelliJ IDEA,execute the idea:ideagoalofMavenIDEAPlugin(http://maven.apache.org/plugins/maven-idea-plugin/):

C:\spring-web-mvc-samples\ch01-xml-config>mvnidea:idea

Executing the idea:idea goal downloads dependencies of the sample project and createsconfigurationfiles(like.ipr,.imland.iws)forIntelliJIDEA.

NOTEApom.xmlfileisalsoprovidedattherootofthesourcecodedistribution,whichbuildsalltheprojects.Youcangotospring-samplesdirectoryandexecutethemvneclipse:eclipse(ormvnidea:idea)commandtoconvertalltheprojectsintoEclipseIDE(orIntelliJIDEA)projects.

Now,importthesampleprojectintoEclipseIDEbyfollowingthesesteps:

§GotoFileàImportoption.§SelecttheGeneralàExistingProjectsintoWorkspaceoptionfromthedialogbox,andclickNext.§Selectthesampleproject(ex.ch01-bankapp-xml)directoryfromthefilesystem,andclickFinish.

ConfiguringtheM2_REPOclasspathvariableintheEclipseIDEWhenyouexecutetheeclipse:eclipseoridea:ideagoal,dependenciesoftheprojectaredownloadedintothe<home-directory>/.m2/repositorydirectory.Here,<home-directory>isthehomedirectoryoftheuser.OnWindows,thisreferstoC:\DocumentsandSettings\myusername\.m2\repositorydirectory.Bydefault,.classpathfilecreatedbyexecutionofeclipse:eclipsegoalreferstotheJARdependenciesoftheprojectusingM2_REPOclasspathvariable.For thisreason,youneedtoconfigureanewM2_REPOclasspathvariableinEclipseIDEthatrefersto<home-directory>/.m2/repositorydirectory.

ToconfigureanewM2_REPOvariable,followthesesteps:

§GotoWindowsàPreferencesoption.ThiswillshowthePreferencesdialogbox.§SelecttheJavaàBuildPathàClasspathVariablesoptioninthedialogboxtoviewtheconfigured

classpathvariables.§Now,clickNewbuttontoconfigureanewM2_REPOclasspathvariable.Itisimportanttonotethat

yousettheM2_REPOclasspathvariableto<home-directory>/.m2/repositorydirectory.We have now successfully imported the sample project into the Eclipse IDE and set the M2_REPOclasspath variable. If the project represents a standalone application, you can run the application byfollowingthesesteps:

§InEclipseIDE’sProjectExplorertab,right-clickontheJavaclassthatcontainsthemainmethodoftheapplication.You’llnowseethelistofactionsthatcanbeperformedontheselectedJavaclass.

§SelectRunAsàJavaApplicationoption.ThiswillexecutethemainmethodoftheJavaclass.Let’snowlookathowEclipseIDEisconfiguredtoworkwithTomcat7server.

Page 515: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

A-3ConfiguringEclipseIDEwithTomcat7serverYouneedtoopenEclipseIDE’sServersviewtoconfigureEclipseIDEwithTomat7server.ToopentheServers view, select Window à Show View à Servers option from the Eclipse IDE’s menu bar. ToconfigureaserverwithEclipseIDE,firstgototheServersview,right-clickintheServersviews,andselectNewàServeroption.You’llnowseeaNewServerwizardwhichallowsyoutoconfigureaserverwithEclipseIDEinastep-by-stepfashion.Thefirststepis‘DefineaNewServer’,whereinyouneedtochoose the type and version of the server with which you want to configure your Eclipse IDE. Thefollowingfigureshowsthe‘DefineaNewServer’step:

FigureA-1SelecttheTomcatserverversionthatyouwanttousewithEclipseIDE

SelectApacheàTomcatv7.0Serveras theserver,andset‘Tomcatv7.0’as theservername.ClicktheNextbuttontogoto thenextstepofconfiguringTomcat7serverwithEclipseIDE.Thenextstepis tospecifyinstallationdirectoryofTomcat7server,asshowninfigureA-2.

Page 516: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

FigureA-2SpecifyTomcatserverinstallationdirectoryandsettheJavaSDKtobeusedbytheserver.

To set the Tomcat installation directory, click the Browse button (refer figure A-2) and select thedirectoryinwhichyouunzippedtheTomcatZIPfile.Also,clicktheInstalledJREsbuttonandconfigurethe Java SDK to be used by Eclipse IDE for running the Tomcat server. Click the Finish button tocomplete configuration of Tomcat 7 server with Eclipse IDE. You’ll now be able to see the newlyconfiguredTomcat7serverintheServersview,asshowninthefollowingfigure:

FigureA-3TheServersviewshowsthenewlyconfiguredTomcat7server

Now,thatwehaveconfiguredTomcat7server,let’slookathowtodeployasamplewebprojecttotheconfiguredTomcat7server.

Page 517: Getting started with Spring Framework Ashish Sarin, J Sharma€¦ · 1-3 Spring IoC container 1-4 Benefits of using Spring Framework Consistent approach to managing local and global

A-4DeployingawebprojectonTomcat7serverTodeployawebproject(ex.ch10-helloworld)onTomcat7server,followthesesteps:

§Right-clickonthesamplewebprojectinEclipseIDE’sProjectExplorertab.You’llnowseethelistofactionsthatcanbeperformedontheselectedwebproject.

§ If youwant to simplydeploy thewebproject, selectRunAsàRunonServer option. ThiswilldeploythewebprojectontheTomcat7serverthatweconfiguredinsectionA-3.OR

§Ifyouwanttodeployanddebugthewebproject,thenselectDebugAsàDebugonServeroption.ThiswilldeploythewebprojectontheTomcat7thatweconfiguredinsectionA-3,andallowyoutodebugthewebprojectbysettingbreakpointsintheEclipseIDE.

IfTomcat7serverisconfiguredcorrectlywithEclipseIDE,you’llnoticethatTomcat7serverisstartedand the web project is deployed on it. If you now open a web browser and go tohttp://localhost:8080/<sample-project-folder-name>,you’llseethehomepageofthewebproject.Here,<sample-project-folder-name>referstothenameofthefolderofthesampleproject.

RunningtheTomcat7serverinembeddedmodeAsimplerwaytodeployandrunasamplewebprojectistouseanembeddedTomcat7server.Inallthesamplewebprojects,MavenTomcatplugin(http://tomcat.apache.org/maven-plugin-2.0/)isconfiguredinthepom.xmlfile.Ifyouexecutetomcat7:rungoalofMavenTomcatpluginbygoing tosampleproject’sdirectory, the plugin takes care of downloading and starting Tomcat 7 in embedded mode andautomaticallydeployingthesamplewebprojectontheembeddedTomcat7instance.Tostoptheserver,allyouneedtodoistopressCtrl-C.