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
Ответы
Ответ 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 мог загружать классы, которые ему нужны.