web-dev-qa-db-fra.com

Spring AOP - Pourquoi ai-je besoin d'aspectjweaver?

j'ai écrit un aspect très simple avec Spring AOP. Cela fonctionne, mais j'ai du mal à comprendre ce qui se passe réellement. Je ne comprends pas pourquoi je dois ajouter le fichier aspectjweaver.jar? La documentation de Spring-AOP indique clairement que je n’ai pas besoin du compilateur ni du tisserand d’aspectj tant que j’utilise Spring-AOP:

Le runtime AOP est toujours un Spring AOP pur, et il n'y a aucune dépendance vis-à-vis du compilateur AspectJ ou du tisserand.

Ma configuration ressemble à ceci:

<aop:aspectj-autoproxy />

@Aspect
@Service
public class RemoteInvocationAspect {

    @Before("execution(* at.test.mypackage.*.*(..))")
    public void test() {
        System.out.println("test");
    }
    ...

J'ai aussi essayé la configuration XML, mais rien n'a changé. Peut-être que je pourrais simplement laisser tomber, mais j'aimerais vraiment comprendre pourquoi aspectj-weaver est utilisé? Si je n'ajoute pas la dépendance dans Maven, je reçois Java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

33
Mario B

Je pense que la mise en œuvre de Spring AOP consiste à réutiliser certaines classes de l'aspectj-weaver. Il utilise toujours des procurations dynamiques - ne modifie pas le code d'octet.

Le commentaire commentaire suivant du forum de printemps pourrait clarifier.

Spring n'utilise pas le tisserand AspectJ dans ce cas. C'est simplement en réutilisant certaines des classes de aspectjweaver.jar.

-Ramnivas

29
gkamal

J'ai récemment eu une question similaire Pourquoi Spring renvoie-t-il une erreur aspectj si elle ne dépend pas de aspectj?

Pour utiliser Spring AoP sans dépendance AspectJ, vous devez le faire en xml. Les annotations font partie de AspectJ.

En outre, le langage d’expression vraiment cool n’est pris en charge que par AspectJ. Vous devez donc définir des coupes de points explicites. Voir la section 6.3.2. Déclarer un point de coupe: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html section 

J'ai encore du mal à trouver une documentation élaborée sur cette technique.

4
beta-brad

Vous utilisez le style AspectJ expression_du-point @Aspect et @Before font partie de AspectJ. Vérifiez ce lien

En ce qui concerne le AspectJ-weaver, il s’agit en fait d’un tisserand de type bytecode qui tresse des aspects en classes au moment du chargement.

4
Santosh

Vous pouvez parcourir le site Web du printemps et trouver la réponse à la page de docs.spring.io

Le support @AspectJ peut être activé avec une configuration de style XML ou Java. Dans les deux cas, vous devrez également vous assurer que la bibliothèque Aspectjweaver.jar de AspectJ se trouve sur le chemin de classe de votre application (version 1.6.8 ou ultérieure). Cette bibliothèque est disponible dans le répertoire 'lib' d'une distribution AspectJ ou via le référentiel Maven Central.

0
Richard Xue

Vous avez besoin des dépendances aspectjtools ou aspectjweaver lorsque vous utilisez le langage d’expression AspectJ.

S'il vous plaît voir les classes suivantes:

Foo.Java

public interface Foo {
    void foo();
    void baz();
}

FooImpl.Java

public class FooImpl implements Foo {
    @Override
    public void foo() {
        System.out.println("Foo!");
    }

    @Override
    public void baz() {
        System.out.println("Baz!");
    }
}

MethodBeforeAdviceBarImpl.Java

import org.springframework.aop.MethodBeforeAdvice;
import Java.lang.reflect.Method;

public class MethodBeforeAdviceBarImpl implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Bar!");
    }
}

Et s'il vous plaît voir App.Java version - 1

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;

public class App {

    public static void main(String[] args) {
        final MethodBeforeAdvice advice = new MethodBeforeAdviceBarImpl();

        final NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor = new NameMatchMethodPointcutAdvisor();
        nameMatchMethodPointcutAdvisor.setMappedName("foo");
        nameMatchMethodPointcutAdvisor.setAdvice(advice);

        final ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvisor(nameMatchMethodPointcutAdvisor);

        final Foo foo = new FooImpl();
        proxyFactory.setTarget(foo);

        final Foo fooProxy = (Foo) proxyFactory.getProxy();
        fooProxy.foo();
        fooProxy.baz();
    }
}

Le résultat de l’exécution de cet exemple sera:

Bar!
Foo!
Baz!

J'ai seulement besoin de org.springframework: spring-context.jar dans mon classpath. Maintenant, au lieu d'un NameMatchMethodPointcutAdvisor, utilisons AspectJExpressionPointcutAdvisor:

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.aop.framework.ProxyFactory;

public class App {

    public static void main(String[] args) {
        final MethodBeforeAdvice advice = new MethodBeforeAdviceBarImpl();

        final AspectJExpressionPointcutAdvisor aspectJExpressionPointcutAdvisor = new AspectJExpressionPointcutAdvisor();
        aspectJExpressionPointcutAdvisor.setAdvice(advice);
        aspectJExpressionPointcutAdvisor.setExpression("execution(void biz.tugay.spashe.Foo.foo())");

        final ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvisor(aspectJExpressionPointcutAdvisor);

        final Foo foo = new FooImpl();
        proxyFactory.setTarget(foo);

        final Foo fooProxy = (Foo) proxyFactory.getProxy();
        fooProxy.foo();
        fooProxy.baz();
    }
}

Encore une fois, si je n'ai que le fichier spring-context.jar dans mon classpath, j'obtiendrai:

An exception occured while executing the Java class. null: InvocationTargetException: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

Lorsque vous étudiez la classe AspectJExpressionPointcutAdvisor, vous constaterez qu'elle étend AbstractGenericPointcutAdvisor et qui délègue le travail à une instance de AspectJExpressionPointcut. Et vous pouvez voir que AspectJExpressionPointcut a les instructions d'importation suivantes:

import org.aspectj.weaver.patterns.NamePattern;
import org.aspectj.weaver.reflect.ReflectionWorld.ReflectionWorldException;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
import org.aspectj.weaver.tools.ContextBasedMatcher;
import org.aspectj.weaver.tools.FuzzyBoolean;
import org.aspectj.weaver.tools.JoinPointMatch;
import org.aspectj.weaver.tools.MatchingContext;
import org.aspectj.weaver.tools.PointcutDesignatorHandler;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParameter;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;
import org.aspectj.weaver.tools.ShadowMatch;

Vous aurez besoin de la dépendance aspectjtools dans votre chemin de classe au moment de l'exécution pour permettre à AspectJExpressionPointcut de charger les classes dont il a besoin.

0
Koray Tugay