简介:讲解什么是AOP⾯向切⾯编程
- 假话:⽅便开发者,提⾼开发效率,为了⼴⼤程序员谋福利
- 真话:就是“懒” -> 懒⼈智慧才是厉害的
- 什么是AOP
- Aspect Oriented Program ⾯向切⾯编程
- 在不改变原有逻辑上增加额外的功能,⽐如解决系统层⾯的问题,或者增加新的功能
- 场景
- 权限控制
- 缓存 ⽇志处理 事务控制
- AOP思想把功能分两个部分,分离系统中的各种关注点
-
核⼼关注点
- 业务的主要功能
- 横切关注点 ⾮核⼼、额外增加的功能
-
核⼼关注点
- 好处
- 减少代码侵⼊,解耦
- 可以统⼀处理横切逻辑 ⽅便添加和删除横切逻辑
简介:讲解AOP⾯向切⾯编程相关核⼼概念
横切、通知、连接点、切⼊点、切⾯???
- 横切关注点
- 对哪些⽅法进⾏拦截,拦截后怎么处理,这些就叫横切关注点
- ⽐如 权限认证、⽇志、事物
-
通知
Advice
- 在特定的切⼊点上执⾏的增强处理,有5种通知,后⾯讲解
- 做啥? ⽐如你需要记录⽇志,控制事务 ,提前编写好通⽤的模块,需要的地⽅直接调⽤
- 连接点 JointPoint
- 要⽤通知的地⽅,业务流程在运⾏过程中需要插⼊切⾯的具体位置
- ⼀般是⽅法的调⽤前后,全部⽅法都可以是连接点
- 只是概念,没啥特殊
- 切⼊点 Pointcut
- 不能全部⽅法都是连接点,通过特定的规则来筛选连接点, 就是Pointcut,选中那⼏个你想要 的⽅法
- 在程序中主要体现为书写切⼊点表达式(通过通配、正则表达式)过滤出特定的⼀组 JointPoint 连接点
- 过滤出相应的 Advice 将要发⽣的 joinpoint 地⽅
- 切⾯ Aspect
- 通常是⼀个类,⾥⾯定义 切⼊点 + 通知 , 定义在什么地⽅; 什么时间点、做什么事情
- 通知 advice 指明了时间和做的事情(前置、后置等) 切⼊点 pointcut 指定在什么地⽅⼲这个事情 web 接⼝设计中, web 层 -> ⽹关层 -> 服务层 -> 数据层,每⼀层之间也是⼀个切⾯,对象和对 象,⽅法和⽅法之间都是⼀个个切⾯
- ⽬标 target
- ⽬标类,真正的业务逻辑,可以在⽬标类不知情的条件下,增加新的功能到⽬标类的链路上
-
织⼊
Weaving
- 把切⾯(某个类)应⽤到⽬标函数的过程称为织⼊
- AOP代理
- AOP框架创建的对象,代理就是⽬标对象的加强
- Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理
简介:讲解AOP⾥⾯Advice通知的讲解
- @Before前置通知
- 在执⾏⽬标⽅法之前运⾏
-
@After
后置通知
- 在⽬标⽅法运⾏结束之后
- @AfterReturning返回通知
- 在⽬标⽅法正常返回值后运⾏
- @AfterThrowing异常通知
- 在⽬标⽅法出现异常后运⾏
- @Around环绕通知
- 在⽬标⽅法完成前、后做增强处理 , 环绕通知是最重要的通知类型 , 像事务 , ⽇志等都是环绕通知, 注意编程中核⼼是⼀个 ProceedingJoinPoint ,需要⼿动执⾏ joinPoint.procced()
//⽬标类 VideoOrderService; ⾥⾯每个⽅法都是连接点,;切⼊点是CUD类型的⽅法,R读取的不作为切⼊点 //CRDU全称:增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete) //定义JointPoint方法 一些连接点 //新增订单 int addOrder(VideoOrder videoOrder); //删除订单 int delOrder(VideoOrder videoOrder); //查询订单 ListfindOrderById(); //更新订单 int updateOrder(VideoOrder videoOrder);
- 接⼝业务流程例⼦
//权限切⾯类 = 切⼊点+通知 PermissionAspects{ //切⼊点 定义了什么地⽅ @Pointcut("execution(public int net.xdclass.sp.service.VideoOrderService.*(..))") public void pointCut(){} //before 通知 表示在⽬标⽅法执⾏前切⼊, 并指定在哪个⽅法前切⼊ //什么时候,做什么事情 @Before("pointCut()") public void permissionCheck(){ System.out.println("在 xxx 之前执⾏权限校验"); } .... } //⽇志切⾯类 = 切⼊点+通知 LogAspect{ //切⼊点 定义了什么地⽅ @Pointcut("execution(public int net.xdclass.sp.service.VideoOrderService.*(..))") public void pointCut(){} //after 通知 表示在⽬标⽅法执⾏后切⼊, 并指定在哪个⽅法前切⼊ //什么时候,做什么事情 @After("pointCut()") public void logStart(){ System.out.println("在 xxx 之后记录⽇志"); } .... }第5集 Spring5.X AOP切⼊点表达式讲解
简介:讲解Spring5.X的AOP切⼊点表达式
切⼊点表示式 除了返回类型、⽅法名和参数外,其它项都是可选的 ( 修饰符基本都是省略不写 )访问修饰符 返回值类型(必填) 包和类 ⽅法 (必填) execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name pattern(param-pattern) throws-pattern?)
- @Pointcut("execution(public int net.xdclass.sp.service.VideoOrderService.*(..))")
- 常⻅匹配语法
- * :匹配任何数量字符 单个;
- .. :匹配任何数量字符 , 可以多个,在类型模式中匹配任何数量⼦包;在⽅法参数模式中匹配任何数量参数
() 匹配⼀个不接受任何参数的⽅法 (..) 匹配⼀个接受任意数量参数的⽅法 (*) 匹配了⼀个接受⼀个任何类型的参数的⽅法 (*,Integer) 匹配了⼀个接受两个参数的⽅法,其中第⼀个参数是任意类型,第⼆个参数必须 是 Integer 类型
- 常⻅例⼦
-
任意公共⽅法
- execution ( public * * ( .. ))
-
任意公共⽅法
- 任何⼀个名字以“save”开始的⽅法
- execution ( * save* ( .. ))
-
VideoService
接⼝定义的任意⽅法(识别)
- execution ( * net.xdclass.service.VideoService.* ( ..))
- 在service包中定义的任意⽅法(识别)
- execution(* net.xdclass.service.*.*(..))
- 匹配 service 包,⼦孙包下所有类的所有⽅法(识别)
- execution(* net.xdclass.service..*.*(..))