1.简介
AOP(Aspect Oriented Programming),面向切面编程。面向切面编程是从动态角度考虑程序运行过程。
AOP底层,就是采用动态代理模式实现的。采用了两种代理:JDK的动态代理,与CGLIB的动态代理。
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
- 总结:AOP:面前切面编程,基于动态代理的,可以使用jdk,cglib两种代理方式。
AOP就是动态代理的规范化,把动态代理的实现步骤,方式都定义好了,让开发人员用一种统一的方式,使用动态代理。
2.AOP相关概念
- AOP(Aspect Orient Programming),面向切面编程。
Aspect :切面,给你的目标类增加的功能,就是切面。像之前用的日志,事务就是切面。
切面的特点:一般都是非业务方法,独立使用的。
Orient :面向,对着。
Programming:编程。
OOP:面向对象编程 - 怎么理解面向切面编程?
1)需要在分析项目功能时,找出切面。
2)合理的安排切面的执行时间(在目标方法前,还是目标方法后)
3)合理的安排切面执行的位置,在哪个类,哪个方法增加增强功能。 - 术语:
1)Aspect:切面,表示增强的功能,就是一堆代码,完成某个非业务功能。
2)JoinPoint:连接点,连接业务方法和切面的位置。就是某类中的业务方法。
3)PointCut:切入点,指多个连接点方法的集合。多个方法。
4)目标对象:给哪个类的方法增加功能,这个类就是目标对象。
5)Advice:通知,通知表示切面功能执行的时间,在目标方法之前,还是目标方法之后。
3.AOP的实现
aop是一个规范,是动态的一个规范化,一个标准。
-
aop的技术实现框架:
1.spring:spring在内部实现了aop规范,能做aop的工作。
spring主要在事务处理时使用aop。
我们项目开发中很少使用spring的aop实现,因为spring的aop比较笨重。
2.aspectj:一个开源的专门做aop的框架。spring框架中集成了aspectj框架,通过spring就能使用aspectj的功能。
aspectj框架实现aop有两种方式:
1.使用xml的配置文件
2.使用注解,我们在项目中要做aop功能,一般都使用注解,aspectj有5个注解。 -
学习aspectj框架的使用。
-
1)切面的执行时间,这个执行时间在规范中叫做Advice(通知,增强)。
在aspectj框架中使用注解表示,也可以使用xml配置文件中的标签。
(1)@Before
(2)@AfterReturning
(3)@Around
(4)@AfterThrowing
(5)@After -
2)表示切面执行的位置,使用的是切入点表达式。
AspectJ 定义了专门的表达式用于指定切入点。表达式的原型是:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
其中:
modifiers-pattern: 访问权限类型
ret-type-pattern:返回值类型
declaring-type-pattern:包名类名
name-pattern(param-pattern):方法名(参数类型和参数个数)
throws-pattern:抛出异常类型
?表示可选的部分execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)
execution(访问权限 方法返回值 方法声明(参数) 异常类型)
方法返回值 和 方法声明(参数)必须有
访问权限 异常类型可省
例子:execution(public * *(..)) 指定切入点为:任意公共方法。 execution(* set*(..)) 指定切入点为:任何一个以“set”开始的方法。 execution(* com.xyz.service.*.*(..)) 指定切入点为:定义在 service 包里的任意类的任意方法。 execution(* com.xyz.service..*.*(..)) 指定切入点为:定义在 service 包或者子包里的任意类的任意方法。“..”出现在类名中时,后 面必须跟“*”,表示包、子包下的所有类。 execution(* *..service.*.*(..)) 指定所有包下的 serivce 子包下所有类(接口)中所有方法为切入点