2010-11-29 38 views
2

Je développe un aspect qui vérifie les arguments de chaîne des méthodes setter de mon paquet d'entité pour les chaînes vides et les remplace par des valeurs null. Mais malheureusement, mon aspect ne fonctionne pas bien :(Je suppose qu'il est à cause de ma définition de pointcut, mais je ne suis pas sûrDéfinition de point de coupure AOP pour l'éditeur de chaînes

Mon aspect ressemble à:..

import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.annotation.Aspect; 

@Aspect 
public class EmptyStringToNullSetter { 
    private static final Logger LOGGER = LoggerFactory 
      .getLogger(EmptyStringToNullSetter.class); 

    public void check(final JoinPoint jp) { 
     LOGGER.debug(jp.getSignature().toLongString()); 
    } 
} 

Ma config de printemps ressemble :

<bean id="emptyStringToNullSetter" class="de.foo.util.aop.parameter.EmptyStringToNullSetter" /> 
<aop:config> 
    <aop:pointcut id="entityStringSetter" expression="execution(* de.foo.entity.*.set*(..)) and args(java.lang.String)" /> 
    <aop:aspect id="checkEmptyStringsAspect" ref="emptyStringToNullSetter"> 
     <aop:before method="check" pointcut-ref="entityStringSetter" /> 
    </aop:aspect> 
</aop:config> 

ma classe de test ressemble:

import de.foo.entity.Period; 

@ContextConfiguration(locations = { "/spring/test-util-context.xml" }) 
public class EmptyStringToNullSetterTest extends 
    AbstractJUnit4SpringContextTests { 
    @Test 
    public void testCheck() { 
     Period period = new Period(); 
     period.setName(""); 
     Assert.assertNull(period.getName()); 
    } 
} 

Lorsque j'exécute mon test l'aspect ne signifie en tercept mon setter. Est-ce que quelqu'un a une idée de pourquoi?!

Cheers,

Kevin

Répondre

4

Puisque vous utilisez AOP, les conseils basés proxy s'appliqueront uniquement aux haricots printemps et l'objet « période » n'est pas un haricot. Vous devez soit avoir "période" comme un haricot ou utiliser l'AOP basée sur le tissage d'AspectJ. Dans les deux cas, vous devrez également utiliser un conseil autour au lieu d'avant.

+0

oui merci, vous avez raison avec procuration base aop, mais je pensais que le printemps fait cela aussi avec des haricots non printemps. De toute façon je vais passer au tissage d'aspectj. Mais pourquoi devrais-je utiliser un conseil autour au lieu d'avant? – eglobetrotter

+1

Un conseil avant ajoutera une logique supplémentaire avant le point de jointure conseillé, mais continuera avec le même contexte (c'est-à-dire l'argument original de la méthode conseillée). Avec un conseil autour, vous pouvez appeler proceed() avec un contexte altéré (dans votre cas, null au lieu d'une chaîne vide). – ramnivas

0

Cette conception est très délicate et sujette aux erreurs avec l'AOP Spring JDK.

J'ai mentionnais ce point ici: http://doanduyhai.wordpress.com/2011/08/08/spring-aop-advices-on-setters-not-trigged/

Fondamentalement, un aspect définir avec Spring AOP est mis en oeuvre lors de l'exécution comme emballage objet proxy autour de l'objectif initial.

Dans le cycle de vie du bean, Spring crée des proxys uniquement après l'initialisation complète du bean, par ex. après toutes les propriétés d'injection par setter.

Ainsi, la première fois que votre setter est appelé, il ne sera pas intercepté par le conseil car le proxy n'existe pas encore.

Cependant, tous les appels ultérieurs au passeur seront interceptés.

En outre, faites attention aux problèmes d'auto-invocation, par ex. appeler le setter() dans une autre méthode cible.

+0

Salut doanduyhai, cela fonctionne pour moi bien avec l'instrumentation aspectj à la compilation. – eglobetrotter