Avatar billede dn666 Nybegynder
01. november 2007 - 11:30 Der er 12 kommentarer og
1 løsning

Spring 2.07 AOP + AspectJ

Hej,

Jeg har en simpel bønne, med en metode der hedder således:
public Date getDueDate();

men har det problem at i mit dao lag må denne værdi ikke være null.
så jeg skal sætte en default værdi hvis den nu engang er det.
da det ikke er en imutable så kunne jeg godt tænke mig at prøve med AOP, og da det ligger i Spring alligevel så vil jeg prøve at lege med det.

Jeg har så lavet en lille aspect klasse og konfigureret spring til autoproxy,


@Aspect
public class Aspects {
    @Pointcut("execution(* *.getDueDate())")
    public void dateHandler() {}


    @AfterReturning(pointcut = "dateHandler()")
    public void handleNullDate() {
        System.out.println("handleNullDate");
    }
}


Det virker fint, "handleNullDate" bliver printet, men nu skal jeg manipulere min data, hvis den er null..

SÅ spørgsmålet er:
Hvordan får jeg fat i den værdi getDueDate() returnrer, og hvordan  kan jeg manipulere den og returnrer min default værdi hvis den er null ??

/David
Avatar billede arne_v Ekspert
02. november 2007 - 01:51 #1
Følgende er testet med AspectJ standalone, men det virker sikkert også via Spring.
Avatar billede arne_v Ekspert
02. november 2007 - 01:51 #2
Test program:

public class AopTest {
    private String getString() {
        if(Math.random() < 0.5) {
            return "OK";
        } else {
            return null;
        }
    }
    public static void main(String[] args) {
        AopTest tst = new AopTest();
        for(int i = 0; i < 10; i++) {
          String s = tst.getString();
          System.out.println(s);
        }
    }
}
Avatar billede arne_v Ekspert
02. november 2007 - 01:51 #3
AfterReturning som fisker værdi:

import java.lang.reflect.*;

import org.aspectj.lang.annotation.*;

@Aspect
public class NullCatcher {
    @Pointcut("execution(* *.getString())")
    public void getStringHandler() {}
    @AfterReturning(pointcut = "getStringHandler()", returning = "o")
    public void checkIfNull(String o) {
        if(o == null) {
            System.out.println("Ooops we got a null");
        }
    }
}
Avatar billede arne_v Ekspert
02. november 2007 - 01:52 #4
Around som ændrer værdi:

import java.lang.reflect.*;

import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;

@Aspect
public class NullHandler {
    @Pointcut("execution(* *.getString())")
    public void getStringHandler() {}
    @Around(value = "getStringHandler()")
    public String replaceNull(ProceedingJoinPoint pjp) {
        String res = (String)pjp.proceed();
        if(res == null) {
            res = "Sorry - we got null";
        }
        return res;
    }
}
Avatar billede arne_v Ekspert
02. november 2007 - 01:52 #5
AspectJ er faktisk et stort område, så jeg skal ikke påstå at de to stykker kode
er optimale.

Men de virker.
Avatar billede thomaswinterberg Nybegynder
02. november 2007 - 02:57 #6
Hvis du vil læse lidt om AOP har jeg skrevet følgende. Det er dog ikke helt nyt. Har desværre ikke haft tid til at opdatere dokumentet. Måske kan det hjælpe.

http://www.cs.aau.dk/~thomasw/aspectJ/AspectJ.pdf
Avatar billede dn666 Nybegynder
02. november 2007 - 10:48 #7
Ah.. @AfterReturning kan ikke modificere data.. det er superb..
1000 tak..

Lige en lille ting mere:
Jeg er ikke helt fan af at, når jeg kigger på min kode ikke fårstår at den laver mærkelige ting.. Så jeg kunne godt tænke mig at jeg kunne annotere hvilke metoder mine pointcuts skal kigge på, og ikke bare et pattern der ligger beskerevet et helt andet sted, er det ikke muligt at lave en form for indikatorer på metoderne eller lign ?
Avatar billede arne_v Ekspert
02. november 2007 - 14:01 #8
Fremfor at referere til et Pointcut i @AfterReturning og @Around kan du angive
pattern direkte der.
Avatar billede dn666 Nybegynder
02. november 2007 - 14:08 #9
Ja. det har jeg tænkt på men..
Har nu findet det perfekte pattern..

Jeg laver min egen annotation,
og skriver pattern: "execution(@MyAnnotation public * *.*(..))"

Arne kan du ikke lige lave et svar.. da løsningen er at bruge Around :)


PS.
Sejt doc Thomas.
Avatar billede dn666 Nybegynder
02. november 2007 - 14:09 #10
Avatar billede arne_v Ekspert
02. november 2007 - 14:22 #11
svar
Avatar billede dn666 Nybegynder
07. november 2007 - 12:53 #12
Lige en lille een mere..

Når jeg så kan execute når de rigtige metoder bliver kaldt, hvordan kan jeg så definere at det kun er når det er min dao der kalder..
og ikke når alle andre kalder ?
Avatar billede arne_v Ekspert
08. november 2007 - 01:36 #13
Ved standalone AspectJ ville jeg kun oversætte DAO med aspect'et.

Du må kunne angive i Spring at det kun skal gøres for en klasse.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester