引子
AOP的出现并不是要完全取代OOP,而仅是作为OOP的有益补充。
AOP的应用场合是受限的,它一般只适合于那些具有横切逻辑的应用场合:如性能监测、访问控制、事务管理和日志记录(虽然有很多文章用日志作为讲解AOP的实例,但很多人认为很难用AOP编写实用的程序日志)
AOP的由来
按照软件重构思想的理念,如果多个类中出现相同的代码,应该考虑定义一个共同的抽象类,
将这些相同的代码提取到抽象类中。比如Horse、Pig、Camel这些对象都有run()、eat()的方法,通过引入一个包含这两个方法抽象的Animal父类,Horse、Pig、Camel就可以通过继承Animal复用到run()和eat()的方法。
通过引入父类消除多个类中重复代码的方式在大多情况下是可行的。但世界并非永远这样简单,请看下面论坛管理业务类的代码
public class ForumService {
private TransactionManager transManager;
private PerformanceMonitor pmonitor;
private TopicDao topicDao;
private ForumDao forumDao;
public void removeTopic(int topicId) {
pmonitor.start();//①-1性能监控开始
transManager.beginTransaction();//②-1 事务处理开始
topicDao.removeTopic(topicId); //③-1 业务逻辑
transManager.commit();//②-1事务处理结束
pmonitor.end();//①-2 性能监控结束
}
public void createForum(Forum forum) {
pmonitor.start();//①-1性能监控开始
transManager.beginTransaction();//②-1 事务处理开始
forumDao.create(forum); //③-2 业务逻辑
transManager.commit();//②-1事务处理结束
pmonitor.end();//①-2 性能监控结束
}
…
}
①的代码是方法性能监视代码,它在方法调用前启动,在方法调用返回前结束,并在内部记录性能监视的结果信息。
而②的代码是事务开始和事务提交的代码。我们发现③处的业务代码淹没在重复化非业务性的代码之中,性能监视和事务管理这些非业务性代码葛藤缠树般包围着业务性代码。
假设我们将ForumService业务类看成一段圆木,将removeTopic()和createForum()方法分别看成圆木的一截,我们会发现性能监视和事务管理的代码就好像一个年轮,而业务代码是圆木的树心,这也正是横切代码概念的由来。
我们无法通过抽象父类的方式消除以上所示的重复性横切代码,因为这些横切逻辑依附在业务类方法的流程中,它们不能转移到其他地方去。
AOP独辟蹊径通过横向抽取机制为这类无法通过纵向继承体系进行抽象的重复性代码提供了解决方案。对于习惯了纵向抽取的开发者来说,可能不容易理解横向抽取方法的工作机制,因为Java语言本身不直接提供这种横向抽象的能力,我们暂把具体实现放在一旁,先通过图解的方式归纳出AOP的解决思路,
从图6-2中,我们可以看出AOP希望将这些分散在各个业务逻辑代码中的相同代码,通过横向切割的方式抽取到一个独立的模块中,还业务逻辑类一个清新的世界。
当然,我们知道将这些重复性的横切逻辑独立出来是很容易的,但如何将这些独立的逻辑融合到业务逻辑中完成和原来一样的业务操作,这才是事情的关键,也正是AOP要解决的主要问题。AOP术语
- 连接点(JoinPoint)
程序执行的某个特定位置:如类开始初始化前、类初始化后、类某个方法调用前、调用后、方法抛出异常后。
一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就称为“连接点”。Spring仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时以及方法调用前后这些程序执行点织入增强。
连接点由两个信息确定:第一是用方法表示的程序执行点;第二是用相对点表示的方位。如在Test.foo()方法执行前的连接点,执行点为Test.foo(),方位为该方法执行前的位置。Spring使用切点对执行点进行定位,而方位则在增强类型中定义。
- 切点(PointCut)
每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点。
但在这为数众多的连接点中,如何定位到某个感兴趣的连接点上呢?AOP通过“切点”定位特定接连点。通过数据库查询的概念来理解切点和连接点的关系再适合不过了:连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
在Spring中,切点通过org.springframework.aop.Pointcut接口进行描述,它使用类和方法作为连接点的查询条件,Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。其实确切地说,用切点定位应该是执行点而非连接点,因为连接点是方法执行前、执行后等包括方位信息的具体程序执行点,而切点只定位到某个方法上,所以如果希望定位到具体连接点上,还需要提供方位信息。
- 通知/增强(Advice)
通知,个人感觉翻译为增强更贴切。
增强是织入到目标类连接点上的一段程序代码。
在Spring中,增强除用于描述一段程序代码外,还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点方位信息和切点信息,我们就可以找到特定的连接点了!
正因为增强既包含了用于添加到目标连接点上的一段执行逻辑,又包含了用于定位连接点的方位信息,所以Spring所提供的增强接口都是带方位名的:BeforeAdvice、AfterRetuningAdvice、ThrowsAdvice等。BeforeAdvice表示方法调用前的位置,而AfterReturingAdvice表示访问返回后的位置。所以只有结合切点和增强两者一起上阵才能确定特定的连接点并实施增强逻辑。
- 切面(Aspect)
切面由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义,Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。
AOP的工作重心在于如何将增强应用于目标对象的连接点上,这里首先包括两个工作:第一,如何通过切点和增强定位到连接点上;第二,如何在增强中编写切面的代码。本章大部分的内容都围绕这两点展开。
- 目标对象
增强逻辑的织入目标类。如果没有AOP,目标业务类需要自己实现所有逻辑,就如中ForumService所示。在AOP的帮助下,ForumService只实现那些非横切逻辑的程序逻辑,而性能监视和事务管理等这些横切逻辑则可以使用AOP动态织入到特定的连接点上。
- 引介(Introduction)
引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,我们可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
- 代理
一个类被AOP织入增强后,就产出了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以我们可以采用调用原类相同的方式调用代理类。
- 织入
织入是将增强添加对目标类具体连接点上的过程,AOP像一台织布机,将目标类、增强或者引介通过AOP这台织布机天衣无缝地编织到一起。我们不能不说“织入”这个词太精辟了。根据不同的实现技术,AOP有三种织入的方式:
1)编译期织入,这要求使用特殊的Java编译器;
2)类装载期织入,这要求使用特殊的类装载器;
3)动态代理织入,在运行期为目标类添加增强生成子类的方式。
Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
分享到:
相关推荐
在深入理解 Spring AOP 的源码时,需要熟悉 Spring IoC 的工作原理,以及 AOP 相关的概念,如切点表达式、通知类型等。了解这些基础知识可以帮助我们更好地掌握 Spring AOP 的实现细节。在分析源码时,可以参考作者...
在深入探讨Spring AOP之前,我们先要理解AOP(面向切面编程)的基本概念。AOP是一种编程范式,它将关注点分离,使得我们可以将横切关注点(如日志、事务管理、安全检查等)与业务逻辑解耦。在Spring框架中,AOP主要...
现在,我们回到主题——"springaop依赖的jar包"。在Spring 2.5.6版本中,使用Spring AOP通常需要以下核心jar包: - `spring-aop.jar`:这是Spring AOP的核心库,包含了AOP相关的类和接口。 - `spring-beans.jar`:...
本文将深入探讨“Spring AOP——Schema”,这是Spring AOP的一种配置方式,通过XML schema定义切面和通知。 首先,我们需要理解AOP的基本概念。面向切面编程是一种编程范式,旨在提高软件的模块化程度,将关注点...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。本入门案例将帮助你理解并掌握Spring AOP的基本概念和使用方法。 在...
"spring-aop-jar"这个主题涉及到Spring框架中的核心组件之一——Spring AOP。这里我们将深入探讨Spring AOP、相关jar文件以及它们在实际开发中的作用。 首先,我们来看一下提供的文件: 1. aopalliance.jar:这是一...
在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,它允许开发者将关注点分离,将横切关注点(如日志、事务管理、权限检查等)与核心业务逻辑解耦。AOP的核心概念是切面、通知、连接点、切入点和织入。在...
"9Spring AOP 盗梦空间之四——Around"这个标题暗示我们将深入探讨Spring AOP中的一个关键概念——环绕通知(Around Advice)。环绕通知是Spring AOP中功能最全面的通知类型,它提供了对方法执行前、执行后以及异常...
首先,我们要了解AOP的核心概念——切面(Aspect)、通知(Advice)、连接点(Join Point)、切入点(Pointcut)和织入(Weaving)。切面是关注点的模块化,如日志或事务管理;通知是在特定连接点执行的行为;连接点...
在IT行业中,Spring框架是Java企业级应用开发的首选,而Spring AOP(面向切面编程)则是其核心特性之一,用于实现横切关注点的模块化,如日志、事务管理等。@AspectJ是Spring AOP的一种注解驱动方式,它极大地简化了...
通过阅读《Spring AOP盗梦空间之二——获得返回值AfterReturnning》这篇博文(链接:https://garrincha.iteye.com/blog/2111779),你可以获得更详细的实践指导和示例代码。同时,结合提供的压缩包文件"Spring_AOP_...
Spring框架是Java开发中不可或缺的一部分,它通过提供两种核心特性——控制反转(IoC)和面向切面编程(AOP)来简化应用的构建。理解并掌握这两种技术对于任何Java开发者来说都至关重要。 **控制反转(IoC)**,也...
Spring AOP(面向切面编程)是一个强大的工具,常用于实现业务逻辑中的横切关注点,如日志、事务管理以及我们的案例——数据权限控制。本篇将深入探讨如何结合Spring AOP和Oracle数据库来实现精细化的数据权限控制。...
Spring AOP,全称Aspect Oriented Programming(面向切面编程),是Spring框架的核心部分之一,它为Java开发者提供了强大的面向切面的编程能力。本文将围绕spring-aop.jar这个核心组件,详细探讨Spring AOP的原理、...
在这个名为"springAOP-dome"的实例中,我们将探讨如何利用Spring AOP实现一个简单的日志记录功能,以作为入门学习。 首先,了解AOP的基本概念是必要的。面向切面编程是一种编程范式,旨在解决程序中的横切关注点,...
Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的一个重要组成部分。它是对传统面向对象编程(OOP)的一种补充,旨在解决业务逻辑中的横切关注点,如日志记录、事务管理、权限控制等。...
首先,我们需要理解Spring AOP的基本概念。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或责任。切面通过切点(Pointcut)定义关注点在哪里应用,而通知(Advice)定义了在切点发生时执行的具体操作。...
在"SpringAOP测试Demo"中,我们通常会涉及以下几个核心概念和操作: 1. **切面(Aspect)**:切面是关注点的一个模块化,它包括了连接点、通知、目标对象、织入和引入。在Spring AOP中,切面通常由一个或多个注解的...
在Java开发领域,Spring框架是不可或缺的一部分,它提供了许多强大的功能,其中AOP(面向切面编程)是其重要特性之一。AOP允许开发者将关注点分离,使得业务逻辑代码与系统服务如日志、事务管理等可以独立处理,提高...