AOP概述
AOP是Aspect Oriented Programing的简称,即“面向切面编程”。
如何理解这个含义,下面举一个例子。
按照软件重构思想的理念,如果多个类中出现相同的代码,那么应该考虑定义一个父类,将这些相同的代码提取到父类中,如所有的动物类都应该有run()和eat()方法,通过引入一个抽象的Animal父类,这些动物类就可以通过继承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();
transManager.beginTransaction();
topicDao.removeTopic(topicId);//1
transManager.endTransaction();
pmonitor.end();
}
public void CreateForum(Forum forum) {
pmonitor.start();
transManager.beginTransaction();
forumDao.create(forum);//2
transManager.endTransaction();
pmonitor.end();
}
}
请看1和2处,这段代码是方法性能监视代码,它在方法调用钱启动,在方法调用返回前结束,并在内部记录性能监视的结果信息。而前后都有transManager.beginTransaction和transManager.endTransaction,表示的是事务开始和事务提交的代码。
性能监视和事务管理这些非业务性代码包围了业务性代码,这些代码无法通过抽象父类的方式消除,因为这些横切逻辑依附在业务类方法的流程中,它们不能转移到其他地方去。
AOP通过横向抽取机制为这类无法通过纵向继承体系进行抽象的重复性代码提供了结局方案,下面通过一张图来归纳AOP的解决思路。
从图可以看出,AOP将这些分散在各个业务逻辑代码中的相同代码横向切割的方式抽取到一个独立的模块中。那么如何将这些独立的代码还原成原来的功能就是AOP要解决的主要问题。
AOP术语
1.连接点(Joinpoint)
特定点是程序执行的某个特定位置,如类开始初始化前,类初始化后等。一个类或者一段程序代码拥有一些具有边界性质的特定点,这些代码特定点就称为“连接点”。Spring仅能支持方法的连接点,即仅能在方法调用前,调用后,抛出异常,及方法调用前后这些程序执行点织入增强。
连接点由两个信息确定:一个是用方法表示的程序执行点,二是用相对位置表示的方法。比如在Test.test()方法执行前的连接点,执行点为Test.test(),方位为该方法执行前的位置。Spring使用切点对执行点进行定位,而方位则在增强类型中定义。
2.切点(Pointcut)
每个程序都拥有多个连接点,AOP通过“切点”定位特定的连接点。
在Spring中,切点通过org.springframework.aop.Pointcut接口进行描述,它使用类和方法作为连接点的查询条件,Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。更确切的说,是执行点而非连接点,切点只定位到某个方法上,定位到具体的连接点上,还需要提供方位信息。
3.增强(Adivce)
在Spring中,增强除了用于描述一段程序代码外,还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点的方位信息和切点信息,就可以找到特定的连接。
4.目标对象(Target)
增强逻辑的织入目标类。
5.引介(Introduction)
引介是一种特殊的增强,它为类添加一些属性和方法。这样,通过AOP的引介功能,也可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
6.织入(Wearving)
织入是将增强添加到目标类的具体连接点上的过程。AOP有三种织入方式:
<1>编译期织入,这要求使用特殊的java编译器。
<2>类装载期织入,在运行期为目标类添加增强生成子类的方式。
<3>动态代理织入,在运行期为目标类添加增强生成子类的方式。
Spring使用动态代理织入,而AspectJ采用编译期和类装载期织入。
7.代理(Proxy)
一个类被AOP织入增强后,就产生了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以可以采用与调用原类相同的方式调用代理类。
8.切面(Aspect)
切面由切点和增强组成,它既包括横切逻辑的定义,也包括连接点的定义。
Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入切面所指定的连接点中。
最后:
AOP的工作重心在于如何将增强应用于目标对象的连接点上。第一:如何通过切点和增强定位到连接点上。第二:如何在增强中编写切面的代码。