Spring AOP - why do i need aspectjweaver?
我用Spring AOP写了一个非常简单的Aspect。 它有效,但是我在理解实际情况时遇到了一些问题。 我不明白为什么我必须添加Aspectjweaver.jar? Spring-AOP文档明确指出,只要使用Spring-AOP,我就不需要AspectJ编译器或weaver:
The AOP runtime is still pure Spring AOP though, and there is no dependency on the AspectJ compiler or weaver.
我的配置如下所示:
1 2 3 4 5 6 7 8 9 | @Aspect @Service public class RemoteInvocationAspect { @Before("execution(* at.test.mypackage.*.*(..))") public void test() { System.out.println("test"); } ... |
我也尝试了XML配置,尽管没有做任何更改。 也许我可以放手,但是我真的很想了解为什么要使用AspectJ-Weaver? 如果我不在Maven中添加依赖项,则会得到
我认为Spring AOP实现正在重用AspectJ-Weaver中的某些类。它仍然使用动态代理-不进行字节码修改。
春季论坛的以下评论可能会澄清。
Spring isn't using the AspectJ weaver in this case. It is simply
reusing some of the classes from aspectjweaver.jar.-Ramnivas
您正在使用AspectJ样式的pointcut-expression
关于
我最近有一个类似的问题,如果不依赖Aspectj,Spring为什么会抛出AspectJ错误?
要使用没有AspectJ依赖关系的Spring AoP,必须在xml中完成。注释是AspectJ的一部分。
而且,AspectJ仅支持非常酷的表达语言。因此,您必须定义明确的切入点。请参阅第6.3.2节。声明切入点:
http://static.springsource.org/spring/docs/2.0.x/reference/aop.html部分
我仍然找不到有关此技术的详尽文档。
使用AspectJ切入点表达语言时,需要AspectJtools或AspectJweaver依赖项。
请参阅以下课程:
Foo.java
1 2 3 4 | public interface Foo { void foo(); void baz(); } |
FooImpl.java
1 2 3 4 5 6 7 8 9 10 11 |
MethodBeforeAdviceBarImpl.java
1 2 3 4 5 6 7 8 9 |
并且请参阅App.java版本-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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(); } } |
运行此示例的输出将是:
1 2 3 | Bar! Foo! Baz! |
我只需要在类路径中使用org.springframework:spring-context.jar。现在让我们使用AspectJExpressionPointcutAdvisor代替NameMatchMethodPointcutAdvisor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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,我将得到:
1 | 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具有以下导入语句:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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可以加载所需的类。
您可以浏览spring网站并在docs.spring.io页面上找到答案
The @AspectJ support can be enabled with XML or Java style configuration. In either case you will also need to ensure that AspectJ’s aspectjweaver.jar library is on the classpath of your application (version 1.6.8 or later). This library is available in the 'lib' directory of an AspectJ distribution or via the Maven Central repository.