0

嗨,

看了很多关于Spring AOP vs AspectJ,还是有些疑惑:

1.)当使用带有@Aspect注释的类并使用“aop:aspectj-autoproxy”标签的Spring AOP时,可以说我们只使用了aspectj的注释,或者它也被用于编织?

2)据说AspectJ具有更好的性能,因为编织是在编译时,这意味着目标类文件在物理上发生了变化,在其中插入了方面?是不是有点咄咄逼人?

3)它说Spring使用代理进行AOP,所以,我理解当你从Spring获得一个bean时,Spring会在内存中构建一个已经插入方面的代理,对吧?那么为什么说当你的代理bean中的一个方法调用代理中的其他方法时,最后一个方法不会有方面呢?

谢谢

4

2 回答 2

1

1) usingaspectj-autoproxy表示@Aspect注释已被识别,但仍在创建 Spring 代理,请参阅文档中的此引用:

不要被元素名称误导:使用它会导致创建 Spring AOP 代理。@AspectJ 样式的方面声明在这里只是被使用,但不涉及 AspectJ 运行时。

2) AspectJ 支持加载时编织、字节码编织和编译时编织。性能应该没有差异,只是编织方面的不同时间点(编译,可用的第三方 jar,类加载时间),有关更多详细信息,请参阅此答案

实际上,一旦设置为在这些时刻编织方面,它实际上会更加透明,使用运行时代理时,当 bean 使用 this.someMethod 调用自身时会出现问题,方面不会被应用,因为代理被绕过(@Transactional/ @Secured 不起作用,等等)。

3)从文档中查看这张图片:

在此处输入图像描述

使用运行时代理(非 AspectJ),Spring 使 bean 类保持不变。它的作用是创建一个代理,该代理要么实现与 bean 相同的接口(JDK 代理),要么如果 bean 没有实现接口,那么它会动态地创建一个带有 CGLIB(bean 的子类)的代理类。

但在这两种情况下,都会创建一个代理,将调用委托给实际的 bean 实例。因此,当 bean 调用 t his.methodB()frommethodA时,会绕过代理,因为调用是直接在 bean 上而不是在代理上进行的。

于 2014-02-11T21:22:32.880 回答
0
  1. Spring AOP 可以用AspectJ-sytle 配置,即解析注释以构建配置,但不使用AspectJ 编译器进行编织。只有 AspectJ 注释和切入点定义的子集可以与 Spring AOP 一起使用。

  2. 也许吧,但我不知道有任何班级抱怨过。但是,某些类在被其他字节码工具修改时可能不允许重新编织。

  3. 内部调用没有被代理,因为它们调用this.method()(使用this= 目标 bean 开始代理)而不是 on,proxy.method()因此代理没有机会拦截调用。但是,Spring AOP 代理通常会注意到目标方法何时返回this并返回自身,因此调用 likebuilder.withColor(Color.RED).withHat(Hat.Cowboy)将起作用。请注意,在 Spring AOP 中始终涉及两个类:代理和目标。

于 2014-02-11T21:19:38.620 回答