You are on page 1of 13

8/17/2013

1
SpringAOP
PradeepLN
pradeep@clearsemantics.com
Motivations
Manybusinessmethodsinmanybeansneed
somecommonlogic
Security
Auditing
Profiling
Repeatingthislogicinallmethodsis
cumbersome
Evenifwritteninahelperclass,itpollutesthe
businessmethodsbyhavingcallstohelperclass
methods
AOPConcepts
AspectOrientedProgramming (AOP)complements
ObjectOrientedProgramming(OOP)byproviding
anotherwayofthinkingaboutprogramstructure.
ThekeyunitofmodularityinOOPistheclass,whereas
in AOP the unit of modularity is the aspect inAOPtheunitofmodularityistheaspect.
Aspectsenablethemodularizationofconcernssuchas
transactionmanagementthatcutacrossmultipletypes
andobjects.(Suchconcernsareoftentermed
crosscutting concernsinAOPliterature.)
8/17/2013
2
AOPConcepts
AOPisusedintheSpringFrameworkto...
...providedeclarativeenterpriseservices,
especiallyasareplacementforEJBdeclarative
services The most important such service is services.Themostimportantsuchserviceis
declarativetransactionmanagement.
...allowuserstoimplementcustomaspects,
complementingtheiruseofOOPwithAOP.
AOPConcepts
Aspect:amodularizationofaconcernthatcuts
acrossmultipleclasses.Transactionmanagement
isagoodexampleofacrosscuttingconcernin
JavaEEapplications.
InSpringAOP,aspectsareimplementedusingregular In Spring AOP, aspects are implemented using regular
classes(theschemabasedapproach)orregular
classesannotatedwiththe@Aspectannotation(the
@AspectJstyle).
Joinpoint:apointduringtheexecutionofa
program,suchastheexecutionofamethodor
thehandlingofanexception.InSpringAOP,ajoin
pointalways representsamethodexecution.
AOPConcepts
Advice:actiontakenbyanaspectataparticularjoin
point.Differenttypesofadviceinclude"around,"
"before"and"after"advice.
ManyAOPframeworks,includingSpring,modelanadvice
asaninterceptor,maintainingachainofinterceptors
around the join point around thejoinpoint.
Pointcut:apredicatethatmatchesjoinpoints.Adviceis
associatedwithapointcut expressionandrunsatany
joinpointmatchedbythepointcut (forexample,the
executionofamethodwithacertainname).
Theconceptofjoinpointsasmatchedbypointcut
expressionsiscentraltoAOP,andSpringusestheAspectJ
pointcut expressionlanguagebydefault.
8/17/2013
3
AOPConcepts
Targetobject:objectbeingadvisedbyoneor
moreaspects.Alsoreferredtoastheadvised
object.SinceSpringAOPisimplementedusing
runtimeproxies,thisobjectwillalwaysbea
proxied object proxied object.
AOPproxy:anobjectcreatedbytheAOP
frameworkinordertoimplementtheaspect
contracts(advisemethodexecutionsandsoon).
IntheSpringFramework,anAOPproxywillbea
JDKdynamicproxyoraCGLIBproxy.
AOPConcepts
Weaving:linkingaspectswithother
applicationtypesorobjectstocreatean
advisedobject.Thiscanbedoneatcompile
time (using the AspectJ compiler for time(usingtheAspectJcompiler,for
example),loadtime,oratruntime.Spring
AOP,likeotherpureJavaAOPframeworks,
performsweavingatruntime.
SpringAOPcapabilities
SpringAOPisimplementedinpureJava.
Thereisnoneedforaspecialcompilationprocess.
SpringAOPdoesnotneedtocontroltheclass
loaderhierarchy,andisthussuitableforuseina y,
JavaEEwebcontainerorapplicationserver.
SpringAOPcurrentlysupportsonlymethod
executionjoinpoints(advisingtheexecution
ofmethodsonSpringbeans).Field
interceptionisnotimplemented.
8/17/2013
4
DefiningPointcuts syntax
SpringAOPusersarelikelytousethe
executionpointcut designatorthemostoften.
Theformatofanexecutionexpressionis:
execut i on( modi f i er s pat t er n? r et t ype execut i on( modi f i er s- pat t er n? r et - t ype-
pat t er n decl ar i ng- t ype- pat t er n? name-
pat t er n( par am- pat t er n) t hr ows- pat t er n?)
Allpartsexceptthereturningtypepattern(rettype
patterninthesnippetabove),namepattern,and
parameterspatternareoptional.
DefiningPointcuts syntax
Thereturningtypepatterndetermineswhatthereturntypeofthe
methodmustbeinorderforajoinpointtobematched.
Mostfrequentlyyouwilluse*asthereturningtypepattern,which
matchesanyreturntype.
Afullyqualifiedtypenamewillmatchonlywhenthemethod
returnsthegiventype.
Th h h h d Thenamepatternmatchesthemethodname.
Youcanusethe*wildcardasallorpartofanamepattern.
Theparameterspatternisslightlymorecomplex:
()matchesamethodthattakesnoparameters,whereas(..)matches
anynumberofparameters(zeroormore).
Thepattern(*)matchesamethodtakingoneparameterofanytype,
(*,String)matchesamethodtakingtwoparameters,thefirstcanbeof
anytype,thesecondmustbeaString.
DefiningPointcuts examples
theexecutionofanypublicmethod:
execut i on( publ i c * *( . . ) )
theexecutionofanymethodwithanamebeginning
with"set":
execut i on( * set *( . . ) )
theexecutionofanymethoddefinedbythe
AccountService interface:
execut i on( *
com. xyz. ser vi ce. Account Ser vi ce. *( . . ) )
theexecutionofanymethoddefinedintheservice
package:
execut i on( * com. xyz. ser vi ce. *. *( . . ) )
8/17/2013
5
DefiningPointcuts examples
theexecutionofanymethoddefinedintheservicepackage
orasubpackage:
execut i on( * com. xyz. ser vi ce. . *. *( . . ) )
anyjoinpoint(methodexecutiononlyinSpringAOP)within
theservicepackage:
i t hi ( i *) wi t hi n( com. xyz. ser vi ce. *)
anyjoinpoint(methodexecutiononlyinSpringAOP)within
theservicepackageorasubpackage:
wi t hi n( com. xyz. ser vi ce. . *)
anyjoinpoint(methodexecutiononlyinSpringAOP)
wheretheproxyimplementstheAccountService interface:
t hi s( com. xyz. ser vi ce. Account Ser vi ce)
Typesofadvice:
Beforeadvice:Advicethatexecutesbeforeajoinpoint,
butwhichdoesnothavetheabilitytoprevent
executionflowproceedingtothejoinpoint(unlessit
throwsanexception).
Afterreturningadvice:Advicetobeexecutedaftera
j i i t l t ll f l if joinpointcompletesnormally:forexample,ifa
methodreturnswithoutthrowinganexception.
Afterthrowingadvice:Advicetobeexecutedifa
methodexitsbythrowinganexception.
After(finally)advice:Advicetobeexecutedregardless
ofthemeansbywhichajoinpointexits(normalor
exceptionalreturn).
Typesofadvice:
Aroundadvice:
Advicethatsurroundsajoinpointsuchasa
methodinvocation.
Thisisthemostpowerfulkindofadvice.Around
advicecanperformcustombehaviorbeforeand
afterthemethodinvocation.
Itisalsoresponsibleforchoosingwhetherto
proceedtothejoinpointortoshortcutthe
advisedmethodexecutionbyreturningitsown
returnvalueorthrowinganexception.
8/17/2013
6
@AspectJsupport
@AspectJreferstoastyleofdeclaringaspectsas
regularJavaclassesannotatedwithJava5
annotations.
The@AspectJstylewasintroducedbythe
AspectJ project as part of the AspectJ 5 release AspectJprojectaspartoftheAspectJ5release.
Spring2.0interpretsthesameannotationsas
AspectJ5,usingalibrarysuppliedbyAspectJfor
pointcut parsingandmatching.
TheAOPruntimeisstillpureSpringAOPthough,and
thereisnodependencyontheAspectJcompileror
weaver.
Enabling@AspectJsupport
Touse@AspectJaspectsinaSpringconfiguration
youneedtoenableSpringsupportforconfiguring
SpringAOPbasedon@AspectJaspects,and
autoproxying beansbasedonwhetherornot
they are advised by those aspects theyareadvisedbythoseaspects.
Byautoproxying wemeanthatifSpring
determinesthatabeanisadvisedbyoneormore
aspects,itwillautomaticallygenerateaproxyfor
thatbeantointerceptmethodinvocationsand
ensurethatadviceisexecutedasneeded.
Enabling@AspectJsupport
The@AspectJsupportisenabledbyincluding
thefollowingelementinsideyourspring
configuration:
<aop:aspectj autoproxy/> <aop:aspectjautoproxy/>
Youneed3morejarfiles:
Aopalliance.jar
Aspectjrt.jar
Aspectjweaver.jar
8/17/2013
7
SimpleExample
@Aspect
publicclassMySimpleAtAspectJAspect {
@Before("execution(*relax(..))")
public void beforeRelaxingMethod() { publicvoidbeforeRelaxingMethod(){
System.out.println("relax()methodis
abouttobeexecuted!");
}
}
SimpleExample
The@Aspectannotationontheclassdeclaration
indicatesthatthisclassisan@AspectJstyleaspect.
Aclassneedstohavethisannotationtoqualifyasan
aspect.
The @Before annotation is used to turn the regular The@Beforeannotationisusedtoturntheregular
beforeRelaxingMethod()methodintoanadvice
declarationandholdsthepointcut declarationforthe
advice.
InAspectJ,anadvicecannotexistwithoutapointcut.
Theannotationtypealsodefinestheadvicetype;inthis
case,itsbeforeadvice.
SimpleExmple
publ i c cl ass SunnyDay {
publ i c voi d r el ax( ) {
/ / go t o t he beach
}}
}
Beforetherelax()methodisexecuted,amessage
willbeprintedontheconsole.Theprint
statementistheactualadvicethatisexecuted.
8/17/2013
8
Autodetecting aspectsthrough
componentscanning
Youmayregisteraspectclassesasregular
beansinyourSpringXMLconfiguration,or
autodetect themthrouch classpath scanning
justlikeanyotherSpringmanagedbean.
However,notethatthe@Aspect annotationis
not sufficientforautodetection inthe
classpath:
Forthatpurpose,youneedtoaddaseparate
@Component annotation
AfterReturningAdvice
Afterreturningadviceiscalledwhenajoinpointhasbeen
executedandhasexitedwithareturnvalueorwithouta
returnvalueifthereturntypeisvoid.
@Aspect
publ i c cl ass MessagePr i nt i ngAspect {
@Aft R t i (" ti (* @AfterReturning("execution(*
startMatch(..))")
publ i c voi d
pr i nt MessageWhenTenni sMat chHasBeenSt ar t edS
uccessf ul l y( ) {
Syst em. out . pr i nt l n( " Tenni s mat ch was st ar t ed
successf ul l y! " ) ;
}
AfterThrowingAdvice
Ifyouwanttodosomeworkwhenajoinpointthrowsan
exception,youcanuseafterthrowingadvice.
@Aspect
publ i c cl ass MessagePr i nt i ngAspect {
@AfterThrowing("execution(* startMatch(..))")
publ i c voi d publ i c voi d
pr i nt MessageWhenSomet hi ngGoesWr ong( ) {
Syst em. out . pr i nt l n( " Oops, coul dn' t st ar t t he
t enni s mat ch. " +
" Somet hi ng went wr ong! " ) ;
}
}
8/17/2013
9
After(Finally)Advice
After(finally)adviceisalwaysexecutedaftera
joinpointhasbeenexecuted,butitcantgethold
ofthereturnvalueoranyexceptionthatis
thrown.
Inotherwords,thisadvicetypecantdetermine
theoutcomeoftheexecutionofthejoinpoint.
Itstypicallyusedtocleanupresources,suchas
tocleanupobjectsthatmaystillbeattachedto
thecurrentthread.
After(Finally)Advice
@Aspect
publ i c cl ass MessagePr i nt i ngAspect {
@After("execution(* startMatch(..))")
publ i c voi d
pr i nt MessageToConcl udeTheTenni sMat chSt ar t At t e
mpt ( ) { p
Syst em. out . pr i nt l n( " A t enni s mat ch st ar t
at t empt has t aken pl ace. " +
" We haven' t been i nf or med about t he out come but
we si ncer el y " +
" hope ever yt hi ng wor ked out OK and wi sh you
ver y ni ce day! " ) ;
}
}
AroundAdvice
Aroundadviceisthemostcomplicatedtypeto
usebecauseithasntbeenspecificallydesigned
foranyparticulartasks.
Instead,itsbasedonaninterceptionmodelthat
allows you to take full control over the join point allowsyoutotakefullcontroloverthejoinpoint
execution.
thisadviceneedstoabletoproceedwiththe
ongoingmethodexecution.
Forthispurpose,everyaroundadvicemethodmust
haveaProceedingJoinPoint declaredasitsfirst
argument
8/17/2013
10
@Aspect
publ i c cl ass MessagePr i nt i ngAspect {
@Around("execution(* startMatch(..))")
publ i c Obj ect
pr i nt MessageToTel l HowNi ceTheLi f eOf AnAdvi ceI s(
ProceedingJoinPoint pjp) throws Throwable {
Syst em. out . pr i nt l n( "Gr eet i ngs, Mast er , how ar e you
t oday?" ) ;
t r y {
return pjp.proceed();
} f i nal l y {
Syst em. out . pr i nt l n( "Au r evoi r , Mast er , Have a ver y "
+
" ni ce day your sel f , si r ! " ) ; }}}
AroundAdvice
Threethingsarespecialaboutthissignature:
Thereturntypeisjava.lang.Object;
theotheradvicetypeshavereturntypevoid.
The first argument is of type Thefirstargumentisoftype
org.aspectj.lang.ProceedingJoinPoint.
Themethoddeclaresjava.lang.Throwable inits
throwsclause.
Sharingcommonpointcut definitions
@Aspect
publicclassSystemArchitecture {
@Pointcut("within(com.xyz.someapp.web..*)")
publicvoidinWebLayer(){}
@Pointcut("within(com.xyz.someapp.service..*)")
publicvoidinServiceLayer(){}
@Pointcut("within(com.xyz.someapp.dao..*)")
publicvoidinDataAccessLayer(){}
@Pointcut("execution(*com.xyz.someapp.service.*.*(..))")
publicvoidbusinessService(){}
@Pointcut("execution(*com.xyz.someapp.dao.*.*(..))")
publicvoiddataAccessOperation(){}
}
8/17/2013
11
UsingsharedPCDs
@Aspect
publ i c cl ass Bef or eExampl e {
@Bef or e( "com. xyz. myapp. Syst emAr ch
i t ect ur e dat aAccessOper at i on( ) ") i t ect ur e. dat aAccessOper at i on( ) ")
publ i c voi d doAccessCheck( ) {
/ / . . .
}
}
AccesstothecurrentJoinPoint
Anyadvicemethodmaydeclareasitsfirstparameter,a
parameteroftypeorg.aspectj.lang.JoinPoint (pleasenote
thataroundadviceisrequired todeclareafirstparameter
oftypeProceedingJoinPoint,whichisasubclassof
JoinPoint.
The JoinPoint interface provides a number of useful TheJoinPoint interfaceprovidesanumberofuseful
methodssuchas:
getArgs()(returnsthemethodarguments)
getThis()(returnstheproxyobject)
getTarget()(returnsthetargetobject)
getSignature()(returnsadescriptionofthemethodthatisbeing
advised)
andtoString()(printsausefuldescriptionofthemethodbeing
advised).
Passingparameterstoadvice
Tomakeargumentvaluesavailabletotheadvice
body,youcanusethebindingformofargs.
Ifaparameternameisusedinplaceofatype
nameinanargs expression,thenthevalueofthe
correspondingargumentwillbepassedasthe
parametervaluewhentheadviceisinvoked.
Supposeyouwanttoadvisetheexecutionofdao
operationsthattakeanAccountobjectasthefirst
parameter,andyouneedaccesstotheaccountin
theadvicebody.
8/17/2013
12
Passingparameterstoadvice
@Bef or e( " com. xyz. myapp. Syst emAr chi t ect ur e. da
t aAccessOper at i on( ) && ar gs( account , . . ) " )
publ i c voi d val i dat eAccount ( Account account )
{ / / . . . }
Theargs(account,..)partofthepointcut expression g ( , ) p p p
servestwopurposes:
firstly,itrestrictsmatchingtoonlythosemethod
executionswherethemethodtakesatleastone
parameter,andtheargumentpassedtothatparameteris
aninstanceofAccount;
secondly,itmakestheactualAccountobjectavailableto
theadviceviatheaccountparameter.
Proxying mechanisms
SpringAOPuseseitherJDKdynamicproxiesor
CGLIBtocreatetheproxyforagiventarget
object.(JDKdynamicproxiesarepreferred
wheneveryouhaveachoice).
If the target object to be proxied implements at Ifthetargetobjecttobeproxied implementsat
leastoneinterfacethenaJDKdynamicproxywill
beused.
Alloftheinterfacesimplementedbythetarget
typewillbeproxied.
Ifthetargetobjectdoesnotimplementany
interfacesthenaCGLIBproxywillbecreated.
UnderstandingAOPproxies
SpringAOPisproxybased.Itisvitally
importantthatyougraspthesemanticsof
whatthatlaststatementactuallymeans
beforeyouwriteyourownaspectsoruseany
oftheSpringAOPbasedaspectssuppliedwith
theSpringFramework.
Considerfirstthescenariowhereyouhavea
plainvanilla,unproxied,nothingspecial
aboutit,straightobjectreference
8/17/2013
13
UnderstandingAOPproxies
publ i c cl ass Si mpl ePoj o i mpl ement s Poj o {
publ i c voi d f oo( )
{
t hi s. bar ( ) ;
}
publ i c voi d bar ( ) { / / some l ogi c } publ i c voi d bar ( ) { / / some l ogi c. . . }
}
Withproxies
publicstaticvoidmain(String[]args){
ProxyFactory factory=newProxyFactory(newSimplePojo());
factory.addInterface(Pojo.class);
factory.addAdvice(newRetryAdvice());
Pojo pojo =(Pojo)factory.getProxy();
pojo foo(); pojo.foo();
}
Solution
Thebestapproach(thetermbestisusedloosely
here)istorefactor yourcodesuchthattheself
invocationdoesnothappen.
Evenifithappens,itshouldbeprivateutilitymethods
th t d t d i t ti thatdontneedinterception
OR(notgood)
publ i c voi d f oo( ) {
/ / t hi s wor ks, but . . . gah!
( ( Poj o) AopCont ext . cur r ent Pr oxy( ) ) . bar ( ) ;
}