Подтвердить что ты не робот

Spring AOP - зачем мне нужен ascjweaver?

Я написал очень простой аспект с Spring AOP. Это работает, но у меня есть некоторые проблемы с пониманием того, что действительно происходит. Я не понимаю, почему я должен добавить aspectjweaver.jar? Документация Spring -AOP четко заявляет, что мне не нужен компонентный компилятор или ткач, если я просто использую Spring -AOP:

Время выполнения AOP по-прежнему является чистым Spring AOP, и нет никакой зависимости от компилятора или ткача AspectJ.

Моя конфигурация выглядит следующим образом:

<aop:aspectj-autoproxy />

@Aspect
@Service
public class RemoteInvocationAspect {

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

Я также пробовал XML-конфигурацию, но ничего не менял. Может быть, я мог бы просто отпустить его, но я действительно хотел бы понять, почему используется аспект-ткач? Если я не добавляю зависимость в maven, я получаю java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

4b9b3361

Ответ 1

Spring Реализация AOP, я думаю, повторно использует некоторые классы из азартного ткача. Он по-прежнему использует динамические прокси - не выполняет модификацию байтового кода.

Следующий комментарий из форума spring может прояснить.

Spring в этом случае не использует ткацкий станок AspectJ. Это просто повторное использование некоторых классов из aspectjweaver.jar.

-Ramnivas

Ответ 2

Недавно у меня был аналогичный вопрос Почему spring выдает аспектную ошибку, если она не зависит от aspectj?

Чтобы использовать spring AoP без зависимости от AspectJ, это должно быть сделано в xml. Аннотации являются частью AspectJ.

Кроме того, действительно классный язык выражений поддерживается только AspectJ. Таким образом, вам нужно определить четкие сокращения точек. См. Раздел 6.3.2. Объявление pointcut: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html раздел

У меня все еще есть проблемы с поиском подробной документации по этой технике.

Ответ 3

Вы используете AscutJ стиль pointcut-expression @Aspect и @Before являются частью AspectJ. Проверьте эту ссылку.

Что касается AspectJ-weaver, то он фактически является ткачом байт-кода, который переносит аспекты в классы во время загрузки.

Ответ 4

Вы можете просмотреть веб-сайт spring и найти ответ на странице docs.spring.io

Поддержка @AspectJ может быть включена с конфигурацией стиля XML или Java. В любом случае вам также необходимо убедиться, что библиотека AspectJs aspectjweaver.jar находится на пути к классу вашего приложения (версия 1.6.8 или новее). Эта библиотека доступна в каталоге "lib" дистрибутива AspectJ или через репозиторий Maven Central.

Ответ 5

При использовании языка выражения pointcut AspectJ нужны атрибуты aspectjtools или aspectjweaver.

См. следующие классы:

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!");
    }
}

И посмотрите App.java версия - 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();
    }
}

Результатом запуска этого примера будет:

Bar!
Foo!
Baz!

Мне нужно только org.springframework: spring -context.jar в моем пути к классам. Теперь вместо NameMatchMethodPointcutAdvisor можно использовать 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();
    }
}

Опять же, если у меня есть только spring -context.jar в моем пути к классам, я получу:

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

Когда вы исследуете класс AspectJExpressionPointcutAdvisor, вы увидите, что он расширяет AbstractGenericPointcutAdvisor и который делегирует работу экземпляру AspectJExpressionPointcut. И вы можете видеть, что AspectJExpressionPointcut имеет следующие операторы импорта:

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;

Вам понадобится зависимость aspectjtools в вашем пути к классам во время выполнения, чтобы AspectJExpressionPointcut мог загружать классы, которые ему нужны.