AOP学习

AOP概述

AOP(Aspect Oriented Programming):⾯向切⾯编程,它是⼀种思想,它是对某⼀类事情的集中处理。

什么是SpringAOP?

⽽ AOP 是⼀种思想,⽽ Spring AOP 是⼀个框架,提供了⼀种对 AOP 思想的实现,它们的关系和 IoC 与 DI 类似。

为什要用 AOP?

在开发中,我们对于公共方法的处理分为三个阶段:

>>每个方法都去实现(初级)

>>抽取公共方法(中级)

>>采用AOP的方式,对代码进行无侵入式实现(高级)

因此,对于这种功能统⼀,且使⽤的地⽅较多的功能,在之前我们会抽取公共方法去实现,但是现在有更好的一个办法来处理这个问题,就是AOP。

也就是使⽤ AOP 可以扩充多个对象的某个能⼒,所以 AOP 可以说是 OOP(Object Oriented Programming,⾯向对象编程)的补充和完善。

AOP的作用?

提供声明式事务;允许用户自定义切面,保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。

日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

Spring AOP的术语

名称说明
Joinpoint(连接点)应用执行过程中能够插入切面的一个点,这个点可以是方法调用时,抛出异常时,甚至修改字段时。切面代码可以利用这些点插入到应用的正常流程之中,并添加新的行为。
Pointcut(切入点)Pointcut的作用就是提供一组规则 来匹配Join Point,给满足规则的Join Point 添加Advice。
Advice(通知)切面也有目标-他必须要完成的工作。在AOP中,切面的工作被称为通知。
Target(目标)指代理的目标对象
Weaving(植入)指把增强代码应用到目标上,生成代理对象的过程
Proxy(代理)
Aspect(切面)由切点(Pointcut)和通知(Advice)组成,既包含了横切逻辑的定义,也包含了连接点的定义。

AOP使用来对某一类事情进行集中处理的,那么处理事情,这个整体就是一个切面,处理事情的范围就是切点,范围中具体的事物就是连接点,怎么处理就是通知。

 

AOP的通知分类

通知又名拦截器,它定义了切面是做什么以及何时使用,即在某个特定的连接点上执行的动作,它是切面的具体实现。以目标方法为参照点,根据放置位置的地方不同,通知分为如下5种类型通知:

通知说明
before(前置通知)通知方法在目标方法调用之前执行
after(后置通知)通知方法在目标方法返回或异常后调用
after-returning(返回后通知)通知方法会在目标方法返回后调用
after-throwing(抛出异常通知)通知方法会在目标方法抛出异常后调用
around(环绕通知)通知方法会将目标方法封装起来

 AOP的实现

添加 Spring AOP 框架⽀持

创建一个控制类EasyAController

@RestController
public class EasyAController {

    //连接点
    @RequestMapping("testA")
    public String testA(){
        System.out.println("testA方法------");
        return "EasyA method";
    }

}

 创建一个切点,并实现通知

@Aspect
@Component
public class AOPObj {

    //定义切点
    //execution(* cn.xxx.dao..*(..))
    @Pointcut("execution(* com.easy.controller.EasyAController.testA(..))")
    public void pointCutTestA(){
        //切点
    }

    //通过动态代理来实现的面向切面的思想,以此在不修改源代码的情况下对已有功能进行增强
    @Before("pointCutTestA()")
    public void before(){
        System.out.println("前置通知----------");
    }

    @After("pointCutTestA()")
    public void after(){
        System.out.println("后置通知----------");
    }

    @AfterThrowing("pointCutTestA()")
    public void afterThrowing(){
        System.out.println("异常后通知----------");
    }

    @AfterReturning("pointCutTestA()")
    public void afterReturning(){
        System.out.println("返回后通知----------");
    }

}

@Aspect是aop框架中提供的,表示是一个切面。切面类中最先定义的是切点,用@Pointcut注解表示是一个切点,括号里边是切点表达式。后边的是五大类型的通知。分别是用五大类名称进行注解。

切点表达式

AspectJ(Java 语言的一个 AOP 实现) ⽀持三种通配符

*匹配任意字符,只匹配⼀个元素(包,类,或⽅法,⽅法参数)
...匹配任意字符,可以匹配多个元素 ,在表示类时,必须和 * 联合使⽤。
+表示按照类型匹配指定类的所有类,必须跟在类名后⾯,如 com.cad.Car+ ,表示继承该类的所有⼦类包括本身

切点表达式由切点函数组成,execution是最常用的切点函数,语法为:

execution(modifier? ret-type declaring-type?name-pattern(param-pattern) throws-pattern?)

modifier:匹配修饰符,public, private 等,省略时匹配任意修饰符

ret-type:匹配返回类型,使用 * 匹配任意类型

declaring-type:匹配目标类,省略时匹配任意类型

        … 匹配包及其子包的所有类

name-pattern:匹配方法名称,使用 * 表示通配符

        *匹配任意方法

        set* 匹配名称以 set 开头的方法

param-pattern:匹配参数类型和数量

        () 匹配没有参数的方法

        (…) 匹配有任意数量参数的方法

        (*) 匹配有一个任意类型参数的方法(*,String) 匹配有两个参数的方法,并且第一个为任意类型,第二个为 String 类型

throws-pattern:匹配抛出异常类型,省略时匹配任意类型

使用示例

// 匹配public方法
execution(public * *(..))

// 匹配名称以set开头的方法
execution(* set*(..))

// 匹配AccountService接口或类的方法
execution(* com.xyz.service.AccountService.*(..))

// 匹配service包及其子包的类或接口
execution(* com.xyz.service..*(..))

  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值