Search Blog

Search duranek.blogspot.com

Tuesday, January 10, 2012

AOP 2

AOP in Spring

Advice: Method Names
Pointcut: Advice path lere shortcut
JoinPoint: Aspect de called method un ismini verir. Aspect metoduna parametre 
olarak yazilir.

<aop:aspectj-autoproxy /> bunu spring.xml e yazmak lazim.

Spring de member variable update icin advice yazilmaz.
sadece method icin yaziliyor. member variable icin sadece aspectj kullanmak lazim

@Before("execution(public void String getName())")
Bu anotation sadece bu metodlarda calisir.

joinPoint.getTarget() dersen cagiran object i gosterir
joinPoint.toString() dersen cagiran metodu yazar.
joinPoint.getTarget() ile , objeyi cekip islem yapabilirsin

@Before("args(String)")
argument i String olan metodlardan once calistir.

@Before("args(name)")
public void xxAdvice(String name) {

}
Burada name olarak value yu kullanabiliriz. Bunun da String olmasi lazim.

@Before annotation'i, biz explicit olarak metodu cagirdigimiz zaman
calisir. Spring initialize olurken bu metodu cagirdigi zaman calismaz.
( Spring initialize olurken, default value leri set ediyordu ya )

@After
Bu annotation i metoddan sonra calismasi icin yapabilirsin.

@AfterReturning
Bu annotation ile advice sadece return olunca yani exception olmazsa
cagirilir.

@AfterThrowing
Sadece throw olduktan sonra cagirilir.

Aspect class larinin annotation'i @Aspect

@AfterReturning(pointcut="args(name)",returning="returnString")
public void xxadvice(String name,String returnString){

}
return String i almak icin bu annotation i kullanabiliriz.

Advice metodlarina parametre olarak Object verirsek, cast ederek
istedigimiz objeye cevirebiliriz.

@AfterThrowing(pointcut="args(name)",throwing="ex")
public void xxxAdvice(String name, RuntimeException ex)
Bu sekilde ise exception i alabiliriz.

Ayni parametre olarak Object verdiğimiz gibi, throwing olarak Exception
class ini veririsek cast ederek istedigimizi alabiliriz. 

@Around annotation i ile hem before hem after'da calistirabilirsin
advice'i.

@Around("test()")
public void xxAdvice(ProceedingJoinPoint proceedingJoinPoint) {
//before da cagirilacak yer
proceedingJoinPoint.proceed();  //metodun gercekten cagirilmasi
//after da cagirilacak yer.
}
Fakat around yaptigimiz zaman ProceedingJoinPoint kullanmak lazim. Ve bu sart !
Ikisini tek yerde yapabiliriz.

Neden hep @Around hep kullanmiyoruz, hep en kolay olani kullanmak lazim.
Always the least powerful

Eger eger advice olan metod obje donuyorsa, @Around metod da obje donmeli

Tipik conventionlar
pakeler asagidaki gibi:
com.xx  : main
com.xx.aspect : aspectler icin . Class isimleri XXXAspect
com.xx.model : bean ler icin
com.xx.service : servisler icin ( servislerden bean leri cagirma ) . XXXService
Conventionlarimiz olursa gerek class ismi, gerek servis ismi, aspect lerde
pointcut expression yazarken cok kolay olur. Cunku pointcut expression lar
da regular expression gibi. 

expression lari && ile baglayabilirsin
@Before("a" && "b")

Yeni bir annotation yaratirsin. xxxAnnotation
@Around("@annotation(com.xx.xxxAnnotation)")
dersin. Sonra advice istedigin metodun ustune gelip @xxxAnnotation dersin.
Sadece o annotation in bulundugu metodlari cagirir.

Annotation yerine, spring xml in icine de aspect leri tanimlayabiliriz.
<aop:config>
    <aop:aspect id="xx" ref="beanIsmi">
        <aop:pointcut id="allGetters" expression="execution("* get())"/>
        <aop:around method="xxx" pointcut-ref="allGetters"/>
    </aop:aspect> // bu aslinda class'a @Aspect tanimlamak ile ayni
</aop:config>

Aspect Class inin da bean xml icinde tanimlanmis olmasi lazim bunu tabi unutmamak lazim.
annotated ve xml solution icin de. 

Annotation genelde functionality acisindan, XML configuration acisindan tercih edilir.
Mesela transaction tanimlama functionality dir, debug mod ya da degil flag i mesela
xml configuration dir.

No comments: