比较分析 Spring AOP 和 AspectJ 之间的差别

面向方面的编程(AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化。AOP提供方面来将跨越对象关注点模块化。虽然现在可以获得许多AOP框架,但在这里我们要区分的只有两个流行的框架:Spring AOP和AspectJ。这里将会帮助你基于一些关键信息,为你的项目选择正确的技术。

Spring AOP不同于大多数其他AOP框架。Spring AOP的目的并不是为了提供最完整的AOP实现(虽然Spring AOP具有相当的能力);而是为了要帮助解决企业应用中的常见问题,提供一个AOP实现与Spring IOC之间的紧密集成。由于Spring AOP是容易实现的,如果你计划在Spring Beans之上将横切关注点模块化,Spring的这一目标将是要点之一。但同样的目标也可能成为一个限制,如果你用的是普通的Java对象而不是Spring beans,并基于此将横切关注点模块化的话。另一方面,AspectJ可用于基于普通Java对象的模块化,但在实施之前需要良好的关于这个主题的知识。

super0555

翻译于 3年前

3人顶

 翻译得不错哦!

在决定使用哪种框架实现你的项目之前,有几个要点可以帮助你做出合适的选择(同样适用于其他框架)。

Spring AOP致力于提供一种能够与Spring IoC紧密集成的面向方面框架的实现,以便于解决在开发企业级项目时面临的常见问题。明确你在应用横切关注点(cross-cutting concern)时(例如事物管理、日志或性能评估),需要处理的是Spring beans还是POJO。如果正在开发新的应用,则选择Spring AOP就没有什么阻力。但是如果你正在维护一个现有的应用(该应用并没有使用Spring框架),AspectJ就将是一个自然的选择了。为了详细说明这一点,假如你正在使用Spring AOP,当你想将日志功能作为一个通知(advice)加入到你的应用中,用于追踪程序流程,那么该通知(Advice)就只能应用在Spring beans的连接点(Joinpoint)之上。

bearkidult

翻译于 3年前

4人顶

 翻译得不错哦!

例子:在appbeans.xml中配置如下的切入点(pointcut),那么当调用myServices bean的service方法时就将应用日志通知(advice)。

<!—Configuration snippet in appbeans.xml -->

  <bean id="myServices" class="com.ashutosh.MyServicesImpl " />

  <aop:config>

    <aop:aspect id="loggingAspect" ref="logging">

       <aop:around method="log" pointcut="execution(public * *(..))"/>

   </aop:aspect>

 </aop:config --> 

// Java file calling service method

ApplicationContext beans =newClassPathXmlApplicationContext("appbeans.xml");

MyServices myServices = (MyServices) beans.getBean("myServices");

myServices.service(); // Logging advice applied here

看一下日志通知将要被应用处的注释,在这里应用程序将记录被调用方法的详细信息。但是,当你在service()方法中调用同一个类中的其他方法时,如果你没有使用代理对象,那么日志通知就不会被应用到这个方法调用上。

例如:

// MyServices service method

public void service() {

  performOperation();// Logging advice not going to apply here

}

如果你想要在通过this对象调用的方法上应用通知,那么你必须使用currentProxy对象,并调用其上的相应方法。

// MyServices service method

public void service() {

  // Logging advice going to apply here

  ((MyServices) AopContext.currentProxy()).performOperation();

}

于此相似,如果你想要在某对象的方法上应用通知,那么你必须使用与该对象相应的Spring bean。

public void service() {

  MyObject obj = new MyObject();

  Obj.performOperation();// Logging advice not going to apply here

}

如果你想要应用该通知,那么上述代码必须修改为如下形式。

public void service() {

  MyObject obj = new MyObject();

 Obj.performOperation();// Logging advice not going to apply here

 ApplicationContext beans =newClassPathXmlApplicationContext("appbeans.xml");

 MyObject obj =(MyObject) beans.getBean("myObject");

 obj.performOperation()// Logging advice applied here

}

于此不同,使用“AspectJ”你可以在任何Java对象上应用通知,而不需要在任何文件中创建或配置任何bean。

bearkidult

翻译于 3年前

3人顶

 翻译得不错哦!

另一个需要考虑的因素是,你是希望在编译期间进行织入(weaving),还是编译后(post-compile)或是运行时(run-time)。Spring只支持运行时织入。如果你有多个团队分别开发多个使用Spring编写的模块(导致生成多个jar文件,例如每个模块一个jar文件),并且其中一个团队想要在整个项目中的所有Spring bean(例如,包括已经被其他团队打包了的jar文件)上应用日志通知(在这里日志只是用于加入横切关注点的举例),那么通过配置该团队自己的Spring配置文件就可以轻松做到这一点。之所以可以这样做,就是因为Spring使用的是运行时织入。

<!—Configuration -->

<bean id="myServices" class="com.ashutosh.MyServicesImpl " />

 <aop:config>

  <aop:aspect id="loggingAspect" ref="logging">

      <aop:around method="log" pointcut="execution(public * *(..))"/>

  </aop:aspect>

</aop:config -->

如果你使用AspectJ想要做到同样的事情,你也许就需要使用acj(AspectJ编译器)重新编译所有的代码并且进行重新打包。否则,你也可以选择使用AspectJ编译后(post-compile)或载入时(load-time)织入。

bearkidult

翻译于 3年前

3人顶

 翻译得不错哦!

因为Spring基于代理模式(使用CGLIB),它有一个使用限制,即无法在使用final修饰的bean上应用横切关注点。因为代理需要对Java类进行继承,一旦使用了关键字final,这将是无法做到的。

例如,在Spring bean MyServicesImpl上使用关键字final,并配置一个“execution(public * *(..))”这样的切入点,将导致运行时异常(exception),因为Spring不能为MyServicesImpl生成代理。

// Configuration file

<bean id="myServices" class="com.ashutosh.MyServicesImpl" />

//Java file

public final classMyServicesImpl {

  ---

}

在这种情况下,你也许会考虑使用AspectJ,其支持编译期织入且不需要生成代理。

于此相似,在static和final方法上应用横切关注点也是无法做到的。因为Spring基于代理模式。如果你在这些方法上配置通知,将导致运行时异常,因为static和final方法是不能被覆盖的。在这种情况下,你也会考虑使用AspectJ,因为其支持编译期织入且不需要生成代理。

bearkidult

翻译于 3年前

2人顶

 翻译得不错哦!

你一定希望使用一种易于实现的方式。因为Spring AOP支持注解,在使用@Aspect注解创建和配置方面时将更加方便。而使用AspectJ,你就需要通过.aj文件来创建方面,并且需要使用ajc(Aspect编译器)来编译代码。所以如果你确定之前提到的限制不会成为你的项目的障碍时,使用Spring AOP。

使用AspectJ的一个间接局限是,因为AspectJ通知可以应用于POJO之上,它有可能将通知应用于一个已配置的通知之上。对于一个你没有注意到这方面问题的大范围应用的通知,这有可能导致一个无限循环。

bearkidult

翻译于 3年前

2人顶

 翻译得不错哦!

例如,创建一个包含如下切入点的方面。

public aspectLogging {

  Object around() : execution(public * * (..))

  Sysytem.out.println(thisJoinPoint.getSignature());

  return proceed();

}

在这种情况下,当proceed即将被调用时,日志通知会被再次应用,这样就导致了嵌套循环。

所以,如果你希望在Spring bean上采取比较简单的方式应用横切关注点时,并且这些bean没有被标以final修饰符,同时相似的方法也没有标以static或final修饰符时,就使用Spring AOP吧。相比之下,如果你需要在所提到的限制之上应用横切关注点,或者要在POJO上应用关注点,那么就使用AspectJ。你也可能选择同时使用两种方法,因为Spring支持这样。

参考链接:http://docs.spring.io/spring/docs/3.0.x/reference/aop.html

时间: 2024-12-25 23:13:14

比较分析 Spring AOP 和 AspectJ 之间的差别的相关文章

Spring AOP With AspectJ

一.AOP和拦截器 某些情况下,AOP和拦截器包括Filter能够实现同样的功能,一般都是请求即controller层的操作,这三个执行顺序为Filter>Interceptor>AOP,当然这里面的区别我会重新写一篇文章讲解,这里面提一下就是想告诉大家,不一定要使用AOP,个人感觉用Filter和Interceptor实现的更方便简单一点. 二.AOP 准备 在spring框架下,你还需要添加aspectjrt,aspectjweaver和cglib 的相关jar包,maven项目的pom.

自我分析-Spring AOP

Spring AOP直白的来说就是使用了JDK的动态代理和CGLIB对Bean的代理,从而实现方法增强的效果. 注意: 1.分析框架代码时,要常使用类继承.调用关系等快捷键,可以更高效的学习,快捷键可以设置成你习惯的按键: 2.本文重在怎么自我分析框架代码,所以对其中解析需自己实际跟踪代码实践方可: 3.spring源代码版本 spring-framework-3.2.1.RELEASE. 预览 org.springframework.beans.factory.support.Abstract

Spring AOP和AspectJ支持

学了Spring之后发现我都不知道java为何物-- 在这一章中有好几节,讲的切面编程 第一节:在项目中启用Spring的AspectJ注解支持 第二节:用AspectJ注解声明aspect 第三节:访问连接点信息 第四节:指定aspect的优先级 第五节:重用切入点定义 第六节:编写AspectJ切入点表达式 第七节:在Bean中引入行为 第八节:为Bean引入状态 第九节:用基于XML的配置声明aspect 如果JVM版本低于1.4时后者不想依赖于AspectJ,就不应该使用AspectJ来

Spring AOP框架 AspectJ

1 AspectJ简介 v  AspectJ是一个基于Java语言的AOP框架 v  Spring2.0以后新增了对AspectJ切点表达式支持 v  @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面 v  新版本Spring框架,建议使用AspectJ方式来开发AOP v  主要用途:自定义开发 2 切入点表达式[掌握] execution() 用于描述方法 [掌握] 语法:execution(修饰符  返回值  包.类.方法名(参数) t

spring AOP 编程--AspectJ注解方式 (4)

1. AOP 简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充. AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点. 在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里. AOP 的好处:

spring aop ---基于AspectJ

因为自己在引用jar包上吃过很多亏,也浪费过很多时间,所以每次都会把使用到的jar包都标明,谢谢理解! 引用jar包: 1.运行类: @Service public class Fit { public String say(){ System.out.println("册数使用的数据!!!!"); // throw new RuntimeException("失败!!!"); return "你好啊!!!"; } } 2.切面类:该类需@Com

关于 Spring AOP (AspectJ) 你该知晓的一切

[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/54629058 出自[zejian的博客] 关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容

关于 Spring AOP (AspectJ) 该知晓的一切

关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容,尽力呈现出简单易懂的文字含义,如文中有错误请留言,谢谢. OOP的新生机 OOP新生机前夕 神一样的AspectJ-AOP的领跑者 AspectJ的织入方式及其原理概要 基于Aspect Spring AOP

Spring AOP + AspectJ Annotation Example---reference

In this tutorial, we show you how to integrate AspectJ annotation with Spring AOP framework. In simple, Spring AOP + AspectJ allow you to intercept method easily. Common AspectJ annotations : @Before – Run before the method execution @After – Run aft