AOP
全称:Aspect-Orented Progranmming 面向切面编程 或 面向方面编程
作用:对系统需求进行模块化组织,简化系统需求与实现之间的对比,是系统更具模块化。
通俗描述:不修改源代码的方式,在主干功能里添加功能
Java实现AOP机制
引入动态代理(Dynamic Proxy)机制,为相应接口动态生成对应的代理对象。
实现机制:
代理模式:
AOP术语
①JoinPoint(连接点):目标对象中,所有可以增强的方法,就是spring允许你是通知(Advice)的地方,那可就真多了,基本每个方法的前、后(两者都有也行),或抛出异常是时都可以是连接点,spring只支持方法连接点。
类里面哪些方法可以被增强,这些方法被成为连接点
常见类型:
方法调用 方法调用时,所处程序执行点
方法调用执行 方法在执行时
类初始化 类中某些静态类型或者静态快的初始化时点
②Pointcut(切入点):目标对象中,已经被增强的方法。调用这几个方法之前、之后或者抛出异常时干点什么,那么就用切入点来定义这几个方法。
实际被增强的方法,成为切入点。
③Advice(通知/增强) :增强方法的代码、想要的功能。
Before Advice :在切入点之前执行的增强类型
After Advice:在切入点之后的增强类型
包含:After returning Advice 返回增强
After throwing Advice 异常增强
After Advice 类似finally
Around Advice 环绕增强 目标方法之前和之后都调用
④Target(目标对象):被代理对象,被通知的对象,被增强的类对象。
⑤Weaving(织入):将通知应用到连接点形成切入点的过程
⑥Proxy(代理):将通知织入到目标对象之后形成的代理对象
⑦aspect(切面):切入点+通知————通知(Advice)说明了干什么的内容(即方法体代码)和什么时候干(什么时候通过方法名中的before,after,around等就能知道),二切入点说明了在哪干(指定到底是哪个方法),切点表达式等定义。
1、连接点JoinPoint
Spring仅支持方法执行类型的JoinPoint
2、切入点PointCut
PointCut最顶层接口,包含了定义了两个方法:
ClassFilter和MethodMatcher分别用于匹配将执行织入操作的对象以及相应方法
ClassFilter接口作用强制让某个子类重写相应的方法。
MethodMatcher接口中定义了三个布尔型方法
1、不考虑JoinPoint的方法参数,这种MethodMatcher称为StaticMethodMatcher
2、每次都要考虑JoinPoint的方法参数这种MethodMatcher称为DynamicMethodMatcher,效率低。
常见的Pointcut实现类
1、NameMethodMatcherPointcut 最简单实现类 根据自身指定的一组方法名称与Jionpoint的方法的方法名称进行匹配
2、JdRegexpMethodMatcherPointcut和Per15RegexpMethodMatcherPointcut 提供基于正则表达式的实现分支
3、AnnotationMethodMatcherPointcut 根据目标对象是否存在指定类型的注解来匹配
3、Advice通知
AOP中Advice分支:
1、Before Advice
实现MethodBeforeAdvice接口即可,实现before 方法
2、ThrowsAdvice
实现ThrowsAdvice接口i,重写以下三个方法:
3、AfterRetureningAdvice
实现AfterRetureningAdvice接口中的afterReturening
4、Around Advice
AOP没有直接定于定义的Around Advice实现接口,而是通过MethodInterceptor实现:
4、per-instance类型的Advice
per-instance类型的Advice不会再目标类所有对象实例之间共享。
Introduction
是Spring Aop中唯一的per-instance类型的Advice。
Introduction可以再不改变咪表类定义的情况下,为目标添加新的属性以及行为
Introduction相关类结构:
AOP动态代理
1、JDK动态代理创建接口实现类代理对象,增强类的方法
2、CGLIB动态代理创建子类的代理对象,增强类的方法
基于JDK动态代理
使用Proxy类方法创建代理对象
调用newProxyInstance方法,
增强方法
代理类要实现InvocationHander接口中的invoke方法
基于Aspect J注解方式实现AOP
切入点PointCut表达式:
语法结构: execution([权限修饰符] [返回类型] [类全路径] 方法名称 )
举例 1:对 com.atguigu.dao.BookDao 类里面的 add 进行增强 execution(* com.atguigu.dao.BookDao.add(…))
举例 2:对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强 execution(* com.atguigu.dao.BookDao.* (…))
举例 3:对 com.atguigu.dao 包里面所有类,类里面所有方法进行增强 execution(* com.atguigu.dao.. (…)
步骤:
1、开启注解扫描
<context:component-scan basepackage=“com.atguigu.spring5.aopanno”></context:component-scan>
2、配置增强类和被增强类 类名上
@Component
3、配置切面
@Aspect 增强类名上
4、再Spring配置文件中开启生成代理对象
开启Aspect生成代理对象
aop:aspectj-autoproxy</aop:aspectj-autoproxy>
5、进行通知配置
再增强类中,@Before 前置通知 @AfterReturning 后置通知 @After 最终通知 @AfterThrowing异常通知 @Around 环绕通知
6、相同切入点抽取 @Pointcut(value = “路径”)
7、多个增强类对同一地方增强 通过设置@Order(数值越低,优先级越高)
基于配置文件增加
1、创建被增强类和增强类
2、创建Bean对象
3、在Spring配置文件中的配置切入点