+ Répondre à la discussion Actualité déjà publiée
  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    novembre 2005
    Messages
    159
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : novembre 2005
    Messages : 159
    Points : 462
    Points
    462

    Par défaut Spring Garden, Tutoriel d'introduction au framework Spring

    Bonsoir,

    En attendant la sortie de Spring 3 en version finale, je vous propose un tutoriel d'introduction aux modules IoC et AOP du framework.

    J'ai essayé d'utiliser un exemple ludique qui, je l'espère, aidera les nouveaux venus à découvrir l'écosystème Spring et amusera les autres.

    En résumé, on codera un jardin de printemps (pour essayer de nous souvenir du soleil), avec des parcelles, des plantes et un jardinier qui en prend soin. Mais tout n'est pas rose (ou vert), une mauvaise herbe rode dans le jardin et elle est affamée...

    Lire le tutoriel

    Je vous vous remercie d'avance pour tout commentaire.

    Bon jardinage!

  2. #2
    Membre à l'essai
    Inscrit en
    mai 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : mai 2006
    Messages : 14
    Points : 11
    Points
    11

    Par défaut

    Bonjour,

    je trouve l'exemple très intéressant et bien construit pour expliquer les différentes notions.

    Cependant, dans l'esprit du jardin, je ne pense pas qu'il n'y ait qu'une seule mauvaise herbe pour tout le jardin, qui capte l'eau et l'engrais. On peut imaginer qu'une mauvaise herbe remplace une plante malade, ou alors qu'il y a une mauvaise herbe par parcelle.

    Ce que j'essaye de faire, c'est modifier l'aspect pour representer ces comportements. Mais je me heurte a mon manque de connaissance de Spring AOP.

    Si j'arrive a les decrire, je les posterai ici, mais je veux bien un peu d'aide

  3. #3
    Membre confirmé

    Profil pro
    Inscrit en
    novembre 2005
    Messages
    159
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : novembre 2005
    Messages : 159
    Points : 462
    Points
    462

    Par défaut

    Bonjour,

    je trouve l'exemple très intéressant et bien construit pour expliquer les différentes notions.

    Cependant, dans l'esprit du jardin, je ne pense pas qu'il n'y ait qu'une seule mauvaise herbe pour tout le jardin, qui capte l'eau et l'engrais. On peut imaginer qu'une mauvaise herbe remplace une plante malade, ou alors qu'il y a une mauvaise herbe par parcelle.

    Ce que j'essaye de faire, c'est modifier l'aspect pour representer ces comportements. Mais je me heurte a mon manque de connaissance de Spring AOP.

    Si j'arrive a les decrire, je les posterai ici, mais je veux bien un peu d'aide
    Bonsoir,
    Effectivement il pourrait y avoir plusieurs mauvaises herbes, mais dans ce cas l'exemple d'aspect serait moins intéressant car il ne serait plus utilisé pour implémenter une seule responsabilité transversale à l'application. Cependant si tu veux avoir plusieurs mauvaises herbes il te faudrait donc définir plusieurs points de coupe différents (changer notamment: bean(*Malade) par un id plus précis). Dans ce cas il serait sans doute plus intéressant d'utiliser un fichier de configuration xml plutôt que des annotations car tu utiliserais un même aspect (avec une mauvaise herbe différente) pour plusieurs point de coupe différents.
    Si tu veux une mauvaise herbe par parcelle, je crois que tu aurais besoin que les plantes connaissent la parcelle à laquelle elles appartiennent (pas très propre) et, ainsi, quand l'aspect est exécuté, en fonction de la parcelle de la plante, tu redirige l'exécution sur une certaine mauvaise herbe.

    En tout cas si tu trouves mieux, n'hésites pas à le poster.

  4. #4
    Membre à l'essai
    Inscrit en
    mai 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : mai 2006
    Messages : 14
    Points : 11
    Points
    11

    Par défaut

    Je ne pense pas que rajouter plusieurs pointcuts soit la solution.

    Mon idee etait plus d'utiliser la possibilite d'instancier un meme aspect plusieurs fois. Dans l'application actuelle, l'aspect n'est instancie qu'une seule fois. Ca ne rompt pas l'idee d'un aspect, car tu decris toujours un comportement transversal : "tous les fruits et legumes malades se font remplacer par des mauvaises herbes".

    Il existe les mots cles "perthis" et "pertarget" (cf doc spring sur aop instantiation, mais aussi doc AspectJ sur instantiation). Leurs utilite est justement de pouvoir decrire ce comportement.

    Mais pour le moment je suis toujours coince par spring, et je n'ai toujours pas reussi a le coder correctement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    /**
     * Cette classe implémente tout le mal de la mauvaise herbe ;-).
     */
    //@Component
    @Aspect("pertarget(nourriPlanteMalade())")
    public class MauvaiseHerbeAspect {
     
    	public MauvaiseHerbeAspect(){
    		System.out.println ("Aspect created");
    	}
    	/**
             * Mauvaise herbe qui vole les nutriments.
             */
    	@Resource
    	IPlante mauvaiseHerbe;
     
    	@Pointcut("execution(* nourri*(..)) && bean(*Malade)")
    	public void nourriPlanteMalade() {}
     
     
    	/**
             * Advice associé Ã* l'éxécution d'une méthode avec le prefixe "nourri" d'un
             * bean avec le suffixe "Malade".
             * 
             * @param joinPoint
             *            référence au point de jonction de l'aspect.
             * @throws IllegalAccessException
             * @throws InvocationTargetException
             */
    	@Around("nourriPlanteMalade()")
    	public void mauvaiseHerbeAdvice(final ProceedingJoinPoint joinPoint)
    			throws IllegalAccessException, InvocationTargetException {
     
    		// On sait que l'objet destin de l'appel est une Plante
    		IPlante plante = (IPlante) joinPoint.getTarget();
     
    		// On sait que le JoinPoint est une méthode
    		Method method = ((MethodSignature) joinPoint.getSignature())
    				.getMethod();
     
    		System.out.println("    * mauvaise herbe (" + mauvaiseHerbe.hashCode() + ")sent la methode "
    				+ method.getName() + " sur " + plante.getNomPlante());
     
    		// Ce qu'allais recevoir la plante est reçu par la mauvaise herbe
    		method.invoke(mauvaiseHerbe, joinPoint.getArgs());
    	}
    }
    Cet aspect n'est jamais instancie, et donc aucune mauvaise herbe ne vole d'eau et d'engrais aux plantes.

    Comment faire pour arriver au comportement voulu donc?

  5. #5
    Membre confirmé

    Profil pro
    Inscrit en
    novembre 2005
    Messages
    159
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : novembre 2005
    Messages : 159
    Points : 462
    Points
    462

    Par défaut

    Interressant...
    Mais pour 'perthis' tu n'es pas sensé mettre le nom complet de la classe puis de la méthode?, du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    perthis(com.xyz.myapp.SystemArchitecture.businessService())

  6. #6
    Membre à l'essai
    Inscrit en
    mai 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : mai 2006
    Messages : 14
    Points : 11
    Points
    11

    Par défaut

    De ce que j'ai vu et compris, je dirais non, car n'importe quel pointcut fait l'affaire.

    Avec l'aspect qui est maintenant défini comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    @Aspect("perthis(execution(* nourri*(..)) && bean(*Malade))")
    @Component
    @Scope("prototype")
    public class MauvaiseHerbeAspect {
     
    	public MauvaiseHerbeAspect(){
    		System.out.println ("Aspect created - " + this.hashCode());
    	}
    	/**
             * Mauvaise herbe qui vole les nutriments.
             */
    	@Resource
    	IPlante mauvaiseHerbe;
     
    	@Pointcut("execution(* nourri*(..))")
    	public void nourriPlante() {}
     
    	@Pointcut("bean(*Malade)")
    	public void planteMalade() {}
     
    	@Pointcut("nourriPlante() && planteMalade()")
    	public void nourriPlanteMalade() {}
     
    	/**
             * Advice associé Ã* l'éxécution d'une méthode avec le prefixe "nourri" d'un
             * bean avec le suffixe "Malade".
             * 
             * @param joinPoint
             *            référence au point de jonction de l'aspect.
             * @throws IllegalAccessException
             * @throws InvocationTargetException
             */
    	@Around("nourriPlanteMalade()")
    	public void mauvaiseHerbeAdvice(final ProceedingJoinPoint joinPoint)
    			throws IllegalAccessException, InvocationTargetException {
     
    		// On sait que l'objet destin de l'appel est une Plante
    		IPlante plante = (IPlante) joinPoint.getTarget();
     
    		// On sait que le JoinPoint est une méthode
    		Method method = ((MethodSignature) joinPoint.getSignature())
    				.getMethod();
     
    		System.out.println("    * mauvaise herbe (" + mauvaiseHerbe.hashCode() + " from aspect " + this.hashCode() + ") sent la methode "
    				+ method.getName() + " sur " + plante.getNomPlante());
     
    		// Ce qu'allais recevoir la plante est reçu par la mauvaise herbe
    		method.invoke(mauvaiseHerbe, joinPoint.getArgs());
    	}
    }
    j'ai un comportement bizarre. Plusieurs aspects sont crées, mais ils ne volent que l'engrais. Et aussi, la mauvaise herbe qui est utilisée est toujours la meme, là où j'aimerais avoir une mauvaise herbe créée pour chaque aspect :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     Mauve herbe creee
     
    JARDIN DE DEPART
    Le Jardin de Monsieur Dupond contient:
    Potager:
        - Patate avec 0ml d'eau et 0g d'engrais
        - PatateMalade avec 0ml d'eau et 0g d'engrais
        - Choux avec 0ml d'eau et 0g d'engrais
        - Tomate avec 0ml d'eau et 0g d'engrais
        - Choux avec 0ml d'eau et 0g d'engrais
    Verger:
        - Poire avec 0ml d'eau et 0g d'engrais
        - Pomme avec 0ml d'eau et 0g d'engrais
        - PoireMalade avec 0ml d'eau et 0g d'engrais
     
    ON ARROSE LE JARDIN
    Monsieur Dupond arrose le Jardin
    Potager:
        - arrose la plante Patate avec 91ml d'eau
         --> Patate a maintenant 91ml d'eau
    Aspect created - 12839401
        - arrose la plante PatateMalade avec 91ml d'eau
         --> PatateMalade a maintenant 91ml d'eau
        - arrose la plante Choux avec 91ml d'eau
         --> Choux a maintenant 91ml d'eau
        - arrose la plante Tomate avec 91ml d'eau
         --> Tomate a maintenant 91ml d'eau
        - arrose la plante Choux avec 91ml d'eau
         --> Choux a maintenant 91ml d'eau
    Verger:
        - arrose la plante Poire avec 91ml d'eau
         --> Poire a maintenant 91ml d'eau
        - arrose la plante Pomme avec 91ml d'eau
         --> Pomme a maintenant 91ml d'eau
    Aspect created - 19509473
        - arrose la plante PoireMalade avec 91ml d'eau
         --> PoireMalade a maintenant 91ml d'eau
     
    ON MET DE L'ENGRAIS DANS LE JARDIN
    Monsieur Dupond met de l'engrais
    Potager:
        - met 28g d'engrais a la plante Patate
         --> Patate a maintenant 28g d'engrais
        * mauvaise herbe (25252664 from aspect 12839401)sent la methode nourriEngrais sur PatateMalade
        ** La mauvaise herbe vole l'engrais !! **
        - met 28g d'engrais a la plante MauvaiseHerbe
         --> MauvaiseHerbe a maintenant 28g d'engrais
        - met 28g d'engrais a la plante Choux
         --> Choux a maintenant 28g d'engrais
        - met 28g d'engrais a la plante Tomate
         --> Tomate a maintenant 28g d'engrais
        - met 28g d'engrais a la plante Choux
         --> Choux a maintenant 28g d'engrais
    Verger:
        - met 28g d'engrais a la plante Poire
         --> Poire a maintenant 28g d'engrais
        - met 28g d'engrais a la plante Pomme
         --> Pomme a maintenant 28g d'engrais
        * mauvaise herbe (25252664 from aspect 19509473)sent la methode nourriEngrais sur PoireMalade
        ** La mauvaise herbe vole l'engrais !! **
        - met 28g d'engrais a la plante MauvaiseHerbe
         --> MauvaiseHerbe a maintenant 56g d'engrais
     
    JARDIN A LA FIN
    Le Jardin de Monsieur Dupond contient:
    Potager:
        - Patate avec 91ml d'eau et 28g d'engrais
        - PatateMalade avec 91ml d'eau et 0g d'engrais
        - Choux avec 91ml d'eau et 28g d'engrais
        - Tomate avec 91ml d'eau et 28g d'engrais
        - Choux avec 91ml d'eau et 28g d'engrais
    Verger:
        - Poire avec 91ml d'eau et 28g d'engrais
        - Pomme avec 91ml d'eau et 28g d'engrais
        - PoireMalade avec 91ml d'eau et 0g d'engrais

  7. #7
    Membre à l'essai
    Inscrit en
    août 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : août 2007
    Messages : 13
    Points : 15
    Points
    15

    Par défaut

    très bien . très bon tuto, et une très bonne introduction sur les AOP.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    mai 2006
    Messages
    160
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : mai 2006
    Messages : 160
    Points : 176
    Points
    176

    Par défaut

    Salut,

    merci pour ton très bon tuto.

    Pour correction, chez moi ça n'a pas compiler sans ajouter la dépendance à aop dans le pom.xml

    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>3.0.0.RELEASE</version>
    </dependency>

    Ca pourra aider car le message n'est pas très explicite et Google non plus...

    Le message :

    Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/aop]
    Offending resource: class path resource [applicationContext.xml]

    A ++

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    mars 2014
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : mars 2014
    Messages : 1
    Points : 1
    Points
    1

    Par défaut Qu'est ce qui dit à Jardin.jardiner de s'exécuter?

    Je ne comprends pas comment, quand on lance la commande
    mvn compile exec:java -Dexec.mainClass="org.yannart.springgarden.SpringGardenApplication"

    la méthode Jardin.jardiner() s'exécute.

    J'ai refait l'application pour m'entrainer à quand je lance la commande maven je n'obtiens que l'instantiation des beans mais l'exécution s'arrête là. La méthode jardiner() ne s'exécute pas. Quelqu'un sait pourquoi??

    Merci d'avance!
    E.

  10. #10
    Membre habitué
    Homme Profil pro
    Développeur Java
    Inscrit en
    octobre 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : octobre 2009
    Messages : 57
    Points : 129
    Points
    129

    Par défaut

    Clair, net et précis.
    Très bon tuto, ça m'a permis de revoir des bases et apprendre l'AOP. :cool:

    Merci.
    Pensez à mettre votre sujet et un petit au passage pour ceux qui vous ont aidé.

    Passionné d'Automobile - http://www.encyclauto.com

Discussions similaires

  1. [Framework] [Info] Framework Spring
    Par sleepy2002 dans le forum Spring
    Réponses: 4
    Dernier message: 21/09/2005, 00h06
  2. [Débutant][Framework] Spring vs Struts vs JSF
    Par Saloucious dans le forum JSF
    Réponses: 2
    Dernier message: 13/07/2005, 10h42
  3. [Data] Développement avec la framework spring et ibatis
    Par ujoodha dans le forum Spring
    Réponses: 1
    Dernier message: 07/03/2005, 14h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo