一些疑问与Spring中的AOP配置有关

时间:2014-12-06 15:00:07

标签: java spring spring-mvc aop spring-aop

我正在攻读Spring Core认证,我怀疑Spring是如何处理AOP的。

阅读文档似乎理解存在以下两种方式来获取Java中的AOP:

  1. 使用 AspectJ ,使用字节代码修改进行方面编织,提供了一种完整的面向方面编程语言。 (所以在我看来, AspectJ 是一种可以与Java集成的不同语言,为其提供AOP功能。)

  2. Spring AOP :在Spring框架中使用动态代理进行方面编织而不是字节码修改。

  3. 所以我的怀疑主要是以下几点:

    1)阅读文档后发现以下方法将 AOP支持添加到我的Spring应用程序中:

    使用JAVA CONFIGURATION CLASS:

    @Configuration
    @EnableAspectJAutoProxy
    @ComponentScan(basePackages=“com.example”)
    public class AspectConfig {
        ...
    }
    

    使用XML配置:

    <beans>
        <aop:aspectj-autoproxy />
        <context:component-scan base-package=“com.example” />
    </beans>
    

    正如您在两种配置中所看到的,都提到 AspectJ

    @EnableAspectJAutoProxy
    

    <aop:aspectj-autoproxy />
    

    为什么呢?如果Spring使用 Spring AOP 而不是 AspectJ ,为什么在Spring中配置AOP时会引用 AspectJ

    2)在前面的示例中,显示了配置Spring的两种方式:通过 Java配置类 XML配置。我知道存在第三种配置Spring应用程序的方法:使用注释。那么是否存在使用注释配置AOP的方法?

2 个答案:

答案 0 :(得分:3)

我认为这些Spring AOP设置在其名称中引用了AspectJ确实更有刺激性而不是有用。我能理解你为什么感到困惑。 Spring AOP与AspectJ实际上是一个不同的概念。正如您所说:Spring AOP中的动态JDK或CGLIB代理与AspectJ中的编译或加载时间内的字节代码检测。其他差异是:

  • AspectJ编译时编织需要一个名为 Ajc 的特殊编译器。它基本上是由Eclipse weaver增强的Eclipse Java编译器 Ecj ,它执行检测。相比之下,Spring AOP在运行时创建动态代理。
  • 在AspectJ中有两种语法变体:native和annotation-based。前者更优雅,更富有表现力,是Java的超集,绝对需要 Ajc 进行编译。后者使用Java注释,可以使用 Javac 编译,需要在 Ajc (编译时)和编织中包含的方面weaver代理 aspectjweaver.jar (加载时间)到&#34;完成&#34;它们并使它们在运行时可用。两种变体都需要包含在 aspectjrt.jar 中的AspectJ运行时(非常小,在运行时用于编译时编织方面)和 aspectjweaver.jar (更大,使用对于加载时编织,包含运行时和编织器。)
  • AspectJ适用于任何Java类,它不需要甚至不了解Spring框架。 Spring AOP需要Spring框架作为基础,你只能用它来测试Spring Beans / Components,而不是Spring不可知的POJO。
  • AspectJ更有效,因为它避免了代理。但是Spring AOP无论如何都是Spring框架的可选部分,所以如果你使用Spring和方法执行就可以截获Spring Beans,那么使用它是完全合理的。
  • Spring AOP使用AspectJ切入点语法的一个子集。也许这是Spring AOP使用AspectJ引用的一个微妙原因,但我仍然认为不区分这两个概念是一个错误的决定。关于命名法,彼此更清楚。此外,常见的poinctut语言子集在一个名为 aopalliance.jar 的小JAR中定义,因为很久以前所谓的&#34; AOP联盟&#34;已定义该语法。然而,今天主流和迄今为止最强大的AOP语言是AspectJ,所以实际上AspectJ(由Eclipse维护)是该领域的领导者,IMO。
  • 当我说Spring AOP使用AspectJ语法的一个子集时,相反它意味着AspectJ提供了一个超集。还有更多的切入点类型,例如call()set()get()等等。您可以通过建议或间隔更多选项拦截连接点并将横切关注点应用于代码库类型定义。

我不明白你的问题#2。示例中的配置类确实使用注释,因此没有第三种方法。 ;-)但是在Spring中有一种旧的,非常过时的AOP方法称为拦截器。它是早期AOP方法的遗留物,现在已经过时,尽管它仍然可用。

Spring AOP和AspectJ都可以通过XML或Spring中的注释进行配置。 : - )

答案 1 :(得分:1)

不确定我是否完全理解你的问题,我想你会问:“如果我使用的是Spring AOP,为什么我会看到对AspectJ的引用?”

如果是这种情况,您应该知道Spring不与AspectJ进行竞争,而是利用 AspectJ进行AOP。

请参阅Spring文档:http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html