SpringAOP
编程范式
面向过程编程
面向对象编程
函数式编程
事件驱动编程
面向切面编程
AOP是什么
- 是一种编程范式,不是编程语言
- 解决特定问题,不能解决所有问题
- 是OOP(面相对象)的补充,不是替代
- 解决代码重复性问题,解决关注点分离
关注点分离:
水平分离:展示层à服务层à持久层
垂直分离:模块划分(订单,库存等)
切面分离:分离功能性需求与非功能性需求(AOP)
AOP优点:
集中处理某一关注点/横切逻辑
可以很方便的添加删除关注点
侵入性少,增强代码可读性及维护性
AOP的使用场景
权限控制
缓存控制
事务控制
审计日志
性能监控
分布式追踪
异常处理
支持AOP的语言
Java
.NET
C/C++
Ruby
Python
PHP
AOP使用方式
xml配置
注解方式
主要注解
Aspect J(注解)
@Aspect(标注类是一个面向切面的类)
@Pointcut(在哪些类哪些方法注入代码)
Advice(这些代码在什么时机注入,执行之前执行之后)
Pointcut express(切面表达式)
Expression:
Designators:(指示器:描述你通过什么样的方式去匹配java类的哪些方法)
匹配方法:execution()
匹配注解:@target()
@args()
@within()
@annotation()
匹配包/类型:within()
匹配对象:this()
bean()
target()
匹配参数:args()
Wildcards:(通配符)
*:匹配任意数量的字符
..:一般用于匹配任意数的子包或参数
+:匹配指定的类及其子类
Operators:(运算符)
&&:与操作符
||:或操作符
!:非操作符
Advice(5种)
匹配包/类型
//匹配ProductService类里头的所有方法
@Pointcut(“within(com.imooc.service.ProductService)”)
public void mathType(){}
//匹配com.imooc包及子包下所有类的方法
@Pointcut(“within(com.imooc..*)”)
public void mathPackage(){}
匹配对象
public class DemoDao implements IDao{}
//匹配AOP对象的目标对象为指定类型的方法,即DemoDao的aop代理对象的方法
可以拦截DeclareParent(Introduction)
@Pointcut(“this(com.imooc.DemoDao)”)
public void thisDemo(){}
//匹配实现IDao接口的目标对象(而不是aop代理后的对象)的方法,这里即DemoDao的方法, 不可以拦截DeclareParent(Introduction)
@Pointcut(“target(com.imooc.IDao)”)
public void targetDemo(){}
//匹配所有以Service结尾的bean里头的方法
@Pointcut(“bean(*Service)”)
public void beanDemo(){}
匹配参数
//匹配任何以find开头而且只有一个Long参数的方法
@Pointcut(“execution(* *..find*(Long))”)
public void argsDemo1(){}
//匹配任何只有一个Long参数的方法
@Pointcut(“args(Long)”)
public void argsDemo2(){}
//匹配任何以find开头的而且第一个参数为Long型的方法
@Pointcut(“execution(* *..find*(Long,..))”)
public void argsDemo3(){}
//匹配第一个参数为Long型的方法
@Pointcut(“args(Long,..)”)
public void argsDemo4(){}
匹配注解
//匹配方法标注有AdminOnly的注解的方法 匹配方法级别
@Pointcut(“@annotation(com.imooc.demo.security.AdminOnly)”)
public void annoDemo(){}
//匹配标注有Beta的类底下的方法,要求的annotation的RetentionPolicy级别为CLASS 匹配类级别
@Pointcut(“@within(com.google.common.annotations.Beta)”)
public void annoWithinDemo(){}
//匹配标注有Reository的类底下的方法,要求的annotation的RetentionPolicy级别为RUNTIME 匹配类级别
@Pointcut(“@target(org.springframework.stereotype.Repository)”)
public void annoTargetDemo(){}
//匹配传入的参数类标注有Repository注解的方法
@Pointcut(“@args(org.springframework.stereotype.Repository)”)
public void annoArgsDemo(){}