12

如果我使用的是基于 AspectJ 的 Spring AOP,那么我是否必须将我的方面配置为使用加载时间编织?或者当使用基于 AspectJ 的方法时,Spring AOP 是否也支持运行时/编译时编织?

4

2 回答 2

18

我认为我们应该小心不要混淆 Spring AOP 和 AspectJ。

  • 就像 singh101 所说,Spring AOP 是基于代理的,更确切地说是基于 Java SE 动态代理(用于接口)或 CGLIB 代理(用于类)。它使用 AspectJ 语法的子集,是一种“AOP lite”方法,基本上仅限于方法执行切入点,缺少许多 AspectJ 切入点类型,如方法调用、类成员 set/get、构造函数调用/执行等。从技术上讲,它与 AspectJ 有很大不同,并且由于代理方法(调用间接)而总是会产生运行时开销。此外,它仅限于从 bean 类外部调用 Spring Bean 方法,即如果 bean 调用它自己的方法之一(因为它不通过相应的代理),它也不起作用,并且它也不适用于非-Spring Bean 类(普通 POJO)。
  • 另一方面,AspectJ 是一个成熟的 AOP 框架,它不依赖于代理或 Spring 框架。不过,它可以很容易地包含在 Spring 应用程序中。它通过自己的编译器(Java 编译器的超集)直接生成字节码或检测现有字节码来工作。AspectJ 可以在编译时(无运行时开销)或类加载(加载时编织,LTW)期间使用。虽然 LTW 在应用程序启动期间有一点开销(但同样适用于 Spring AOP),但由于调用间接,两种 AspectJ 编织方法都没有运行时开销,因为不涉及代理。
  • 关于 AOP 的 Spring 手册章节很好地解释了当 Spring AOP 不够强大或太慢时如何将完整的 AspectJ 集成到 Spring中。
于 2014-10-13T08:54:47.540 回答
9

Spring AOP 是基于代理的。除非另外配置,否则 Spring AOP 会执行运行时编织。

编织:将方面与其他应用程序类型或对象链接以创建建议对象。这可以在编译时(例如,使用 AspectJ 编译器)、加载时或运行时完成。Spring AOP 与其他纯 Java AOP 框架一样,在运行时执行编织。

来源:http ://docs.spring.io/spring/docs/4.0.1.RELEASE/spring-framework-reference/htmlsingle/#aop-introduction-defn


但是,您可以设置 Spring 来进行加载时编织。查看有关如何执行此操作的 Spring 文档:http: //docs.spring.io/spring/docs/3.2.0.RELEASE/spring-framework-reference/htmlsingle/#aop-aj-ltw

除其他外,您将@EnableLoadTimeWeaving在 Java Config 类中使用。设置相当简单,您的@Aspect课程不会改变。

开发人员只需修改一个或多个构成应用程序上下文的文件以启用加载时编织,而不是依赖通常负责部署配置(例如启动脚本)的管理员

于 2014-10-12T15:31:27.567 回答