一、理解 “面向切面编程”
面向切面编程(Aspect Oriented Programming,AOP)是软件编程思想发展到一定阶段的产物,是对面向对象编程(Object Oriented Programming,OOP)的有益补充。AOP 一般适用于具有横切逻辑的场合,如访问控制、事务管理、性能监测等。
什么是横切逻辑?观察如下代码段:
public class UserServiceImpl implements UserService { private static final Logger log = Logger.getLogger(UserServiceImpl.class); public boolean addNewUser(User user) { log.info(“添加用户 ” + user.getUsername());//记录日志 SqlSession sqlSession = null; boolean flag = false; //异常处理 try { sqlSession = MyBatisUtil.createSqlSession(); if (sqlSession.getMapper(UserMapper.class).add(user) > 0) flag = true; sqlSession.commit(); //事务控制 } catch (Exception e) { log.error("添加用户 " + user.getUsername() + "失败", e); //记录日志 sqlSession.rollback(); //事务控制 flag = false; } finally { MyBatisUtil.closeSqlSession(sqlSession); } return flag; } }
▶ 这是一个再典型不过的业务处理方法,日志、异常处理、事务控制等,都是一个健壮的业务系统所必需的。但是为了保证系统健壮可用,就要在众多的业务方法中反复编写类的代码,使得原本就很复杂的业务处理代码变得更加复杂。业务功能的开发者还要关注这些 “额外” 的代码是否处理正确,是否有遗漏的地方。如果需要修改日志信息的格式或者安全验证的规则,或者再增加新的铺助功能,都会导致业务代码频繁而大量的修改。
▶ 在业务系统中,总有一些散落、渗透到系统各处且不得不处理的事情,这些穿插在既定业务中的操作就是所谓的 “横切逻辑” ,也称为切面。我们怎样才能不受这些附加要求的干扰,专心于真正的业务逻辑呢?我们很容易想到可以将这些重复性的代码抽取出来,放在专门的类和方法中,这样就便于管理和维护了。但即便如此,依然无法实现既定业务和横切逻辑的彻底解耦合,因为业务代码中还要保留这些方法的调用代码,当需要增加或减少横切逻辑的时侯,还是要修改业务方法中的调用代码才能实现。我们希望无须编写显式的调用,在需要的时侯,系统能够 “自动” 调用所需的功能,这正是 AOP 要解决的主要问题。
▶ 面向切面编程,简单地说就是在不改变原程序的基础上为代码段增加新的功能,对代码段进行增强处理。它的设计思想来源于代理设计模式。
▶ 面向切面编程,简单地说就是在不改变原程序的基础上为代码段增加新的功能,对代码段进行增强处理。它的设计思想来源于代理设计模式。
在代理模式中可以为该对象设置一个代理对象,代理对象为 fun() 提供一个代理方法,当通过代理对象的 fun() 方法调用原对象的 fun() 方法时,就可以在代理方法中添加新的功能,也就是所谓的增强处理。增强的功能既可以插到原对象的 fun() 方法前面,也可以插到后面。在这种模式下,给编程人员的感觉是在原有代码乃至原业务流程都不修改的情况下,直接在业务流程中切入新代码,增强新功能,这就是所谓的面向切面编程。
面向切面相关术语
▶ 切面(Aspect):一个模块化的横切逻辑(或称横切关注点),可能会横切多个对象。
▶ 连接点(Join Point):程序执行中的某个具体的执行点。
▶ 增强处理(Advice):切面在某个特定连接点上执行的代码逻辑。
▶ 切入点(Pointcut):对连接点的特征进行描述,可以使用正则表达式。增强处理和一个切入点表达式相关联,并在与这个切入点匹配的某个连接点上运行。
▶ 目标对象(Target object):被一个或多个切面增强的对象。
▶ AOP 代理(AOP proxy):由 AOP 框架所创建的对象,实现执行增强处理方法等功能。
▶ 织入(Weaving):将增强处理连接到应用程序中的类型或对象上的过程。
▶ 增强处理类型:在原对象的 fun() 方法之前插入的增强处埋为前置增强,该方法正常执行完以后插入的增强处理为后置增强,此外还有环绕增强,异常抛出增强、最终增强等类型。
说明:
1、切面可以理解为由增强处理和切入点组成,既包含了横切逻辑的定义,也包含了连接点的定义。面向切面编程主要关心两个问题,即在什么位置,执行什么功能。 Spring AOP 是负责实施切面的框架,即由 Spring AOP 完成织入工作。
2、Advice 直译为 “通知”,但这种叫法并不确切,在此处翻译成 “增强处理”,更便于大家理解。
2、Advice 直译为 “通知”,但这种叫法并不确切,在此处翻译成 “增强处理”,更便于大家理解。