1 AOP
Aspect Oriented Programming面向切面编程
增强
AOP 采取横向抽取机制(动态代理),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。
简单的说,AOP 的作用就是保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。AOP 就是代理模式的典型应用。
动态代理:增强的是委托类的全部方法
AOP:增强的是容器中的组件里特定(有机会选择)的方法
范围:容器中的组件
把一些和核心业务无关的内容提取出来,通用的事情,比如参数校验、事务、程序状态检测、日志,释放资源等
2 核心术语
通过切入点指定容器中的组件里的方法,通知指导他们做增强
如果方法在切入点增强的范围内,该方法对应的组件就会被增强(变成Proxy)
3 动态代理
AOP底层就是使用动态代理来进行增强:JDK动态代理和CGlib动态代理都有使用。
如果有接口的实现,用的是JDK动态代理
如果没有接口实现,用的是CGlib动态代理
4 AOP实战
4.1 动态代理
参考昨天作业
4.2 SpringAOP
类似于UserServiceProxyFactoryBean
4.2.1 通知组件
4.2.2 代理组件
4.2.3 哪里不够好
繁琐:注册代理组件、取出
方法的指定不灵活
4.3 ★★AspectJ
狸猫换太子
注册过程中不需要一一指定委托类组件,取出过程也不需要指定组件id
4.3.1 Pointcut
切入点:指定增强方法(容器中的组件的方法)。
切入点表达式 👉 配置文件中配置
标签<aop:pointcut id expression/>,作为aop:config的子标签
4.3.1.1 引入aop的schema
可以手动改造,也可以输入aop:通过提示来引入(一定不要引入错了schema)
4.3.1.2 execution(修饰符 返回值 包名、类名、方法名(形参))
判断方法(容器中的组件的方法)是否满足表达式,如果满足就增强
1、 能否省略
2、 能否通配
3、 特殊用法
4.3.1.2.1 修饰符
修饰符可以省略 👉 代表任意修饰符
4.3.1.2.2 返回值
返回值不能省略
返回值可以使用*作为通配符
JavaBean类要写全类名
4.3.1.2.3 包名、类名、方法名
可以部分省略,头和尾(包名的第一级、方法名)不能省略,中间的任意一部分都可以省略。
使用…进行省略
通配符:可以使用通配符
4.3.1.2.4 形参
可以省略不写,省略不写代表的是无参方法
可以通配:
*👉单个任意类型的参数
… 👉任意参数:数量上的任意、类型上的任意
JavaBean要写全类名
4.3.1.3 @annotation(自定义注解的全类名)
注解加在哪个方法(容器中的组件的方法)上,哪个方法就被增强
4.3.2 Aspectj的advisor
<aop:advisor advice-ref pointcut(-ref)/>
2 ★★aspect
pointcut + advice
aspect给我们提供了一些通知:通知是在什么时间做什么事情,做的事情是我们自己写的,但是aspect给我们提供了时间
before、after、around、after-returning、after-throwing 相对于委托类方法的时间
2.1 切面中的通知方法
2.2 配置
2.3 after-throwing通知
2.4 小结
使用通知的话是否全部通知都会使用:通常只用一到两个
重构周末作业,使用什么通知:around
相对时间:相对于委托类方法的执行时间
增加这些通知方法:在代理对象执行方法的时候,会在对应的时机调用切面组件中的通知方法
2.5 JoinPoint 连接点
增强过程中的点,增强过程就是执行通知的方法,拿到过程中的值
提供了获得增强过程中的值的方法
getThis 代理对象
getTarget 委托类对象
getSignature 方法相关的
getArguments 参数
2.6 ★注解
将我们aspectj使用aspect的这种形式使用注解和类表达出来,干掉aop:aspect标签
2.6.1 打开注解开关
< aop:aspectj-autoproxy/>
2.6.2 配置切面类
指定了切面组件
切入点配置
指定切面组件中方法使用什么通知方法
通知方法对应的切入点或切入点表达式
returning和throwing指定形参来接收委托类方法执行结果或抛出的异常
2.6.2.1 指定切面组件
组件上增加一个新的注解@Aspect
2.6.2.2 切入点配置
以方法的形式存在,引入一个新的注解@Pointcut
id的配置、表达式的配置
2.6.2.3 通知注解
@Before、@After、@Around、@AfterReturning、@AfterThrowing
2.6.2.4 引用切入点表达式或切入点id
通知注解的value属性中