总所周知,Java是一门面向对象(OOP)编程语言。面向对象的特点是封装、继承和多态。而封装就是将不同的功能封装到不同的对象中(职责分配,例如在做登录、删除等业务时就会封装为独立的类),增加了代码复用性,降低了代码复杂程度。
但是在职责分配的代码中,也增加了部分代码的重复性。比如在添加性能统计、日志、事务管理的代码时,就需要在每个功能的代码文件中添加重复的代码。当然也可以把这部分代码重新封装到一个新的类中,但这样一来上面哪些独立的功能封装类就出现了耦合。那怎样才能在代码中随意的加入代码且不破坏类的封装呢? 这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。
面向切面编程基于动态代理实现。
OOP从纵向上区分出一个个类来,而AOP从横向上加入特定的代码。如下图:
OOP:
AOP:Joinpoint连接点:被拦截需要曾强的方法。where:到哪里去做曾强
Pointcut:切入点,哪些包中的哪些类中的哪些方法,可认为是连接点的集合。
Advice:增强,当拦截到Joinpoint之后,在方法执行的什么时机(when)做什么样(what)的增强.
根据时机分为:前置增强、后置增强、异常增强、最终增强、环绕增强。
Aspect:切面,Pointcut+Advice,去那些地方+在什么时机+做什么增强
Target:目标对象,被代理的目标对象
Weaving:织入,把Advice加到Target上之后,创建出Proxy对象的过程。
Proxy:一个类被AOP织入增强后,产生的代理类。
增强 | 备注 | 应用场景 |
---|---|---|
aop:before(前置增强) | 在方法执行之前执行增强 | 权限控制、记录调用日志等 |
aop:after-returning(后置增强) | 在方法正常执行完成之后执行增强(中间没有遇到任何异常) | 统计分析结果数据 |
aop:throwing(异常增强) | 在方法抛出异常退出时执行增强 | 通过日志记录方法异常信息 |
aop:after(最终增强) | 在方法执行之后,相当于在finally里面执行;可以通过配置throwing来获得拦截到的异常信息 释放资源 | |
aop:around(环绕增强) | 最强大的一种增强类型,环绕增强可以在方法调用前后完成自定义的行为,环绕增强有两个要求: 1. 方法需要返回一个Object(返回的结果)2. 方法的第一个参数必须是ProceedingJoinPoint(可以继续向下传递连接点) | 缓存、性能日志、权限、事务管理等 |