Spring AOP核心概念与案例

本文介绍了AOP的核心概念,包括连接点、切入点、通知和切面,以及SpringAOP的工作流程。通过一个案例展示了如何在Spring中配置和使用AOP,包括定义通知类、设置切入点和通知类型。此外,还详细解释了AOP的通知类型,如前置、后置、环绕通知等,并说明了如何获取通知中的数据。
摘要由CSDN通过智能技术生成

AOP核心概念

(Aspect Oriented Programming)面向切面编程,一种编程的范式,指导开发者如何组织程序结构作用:在不惊动原始设计的基础上,为其进行功能增强(代理模式可以做增强)


1. 连接点:可以进行切入的方法,在SpringAOP中理解为方法的执行

2. 切入点即为被切入的方法(表示为需要使用Aop包下共用功能的方法)
在SpringAOP中,一个切入点可以描述一个具体的方法,也可匹配多个方法
*一个具体的方法:某个包下的无形参,无返回值的save方法
*匹配多个方法:所有的save方法,所有的get开头的方法,以Dao结尾的任意方法

3. 通知:在切入点处执行的操作,也就是共性方法
4. 通知类

5. 切面:在通知和切面之间进行绑定的关系

在这里插入图片描述

案例

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

1.pom.xml

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>
  </dependencies>

2.定义通知类,制作通知

绑定切入点与通知关系,并指定通知添加到连接点的位置:靠方法名pt()绑定

//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {
    //设置切入点,要求配置在方法上方
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}

    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

3.SpringConfig

开启注解开发AOP功能
@EnableAspectJAutoProxy

@Configuration
@ComponentScan("com.itheima")
//开启注解开发AOP功能
@EnableAspectJAutoProxy
public class SpringConfig {
}


AOP工作流程

    1. Spring容器启动
    1. 读取所有切面配置中的切入点
    1. 初始化bean,判定bean对应的类中的方法是否匹配到切入点
      (1)匹配失败(创建对象)
      (2)匹配成功,创建原始对象(目标对象)的代理对象
    1. 获取bean执行方法
      (1)获取bean,调用方法执行,完成操作
      (2)获取bean的是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作

AOP切入点表达式

execution(void com.itheima.dao.BookDao.update())
execution(void com.itheima.dao.impl.BookDaoImpl.update())

  • 动作关键字:execution
  • 返回类型
  • 包名
  • 类/接口名
  • 方法

可以使用通配符描述切入点
在这里插入图片描述

书写技巧
在这里插入图片描述

AOP通知类型

  • 前置通知
  • 后置通知
  • 环绕通知
@Around("pt2()")
   //会报错
   //原始方法返回类型要与该代理方法一致
/*    public void aroundSelect(ProceedingJoinPoint pjp) throws Throwable {
       System.out.println("around before advice ...");
       //表示对原始操作的调用
       pjp.proceed();
       System.out.println("around after advice ...");
   
   }*/
   public Object aroundSelect(ProceedingJoinPoint pjp) throws Throwable {
       System.out.println("around before advice ...");
       //表示对原始操作的调用
       Integer ret = (Integer) pjp.proceed();
       System.out.println("around after advice ...");
       return ret;
   }
  • 返回后通知
  • 抛出异常后通知

AOP通知获取数据

@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(* com.itheima.dao.BookDao.findName(..))")
    private void pt(){}

    //JoinPoint:用于描述切入点的对象,必须配置成通知方法中的第一个参数,可用于获取原始方法调用的参数
    //@Before("pt()")
    public void before(JoinPoint jp) {
        Object[] args = jp.getArgs();
        System.out.println(Arrays.toString(args));
        System.out.println("before advice ..." );
    }

//    @After("pt()")
    public void after(JoinPoint jp) {
        Object[] args = jp.getArgs();
        System.out.println(Arrays.toString(args));
        System.out.println("after advice ...");
    }

    //ProceedingJoinPoint:专用于环绕通知,是JoinPoint子类,可以实现对原始方法的调用
    //@Around("pt()")
    public Object around(ProceedingJoinPoint pjp) {
        Object[] args = pjp.getArgs();
        System.out.println(Arrays.toString(args));
        //可以在这个地方对参数进行处理
        args[0] = 666;
        Object ret = null;
        try {
            ret = pjp.proceed(args);

        } catch (Throwable t) {
            t.printStackTrace();
        }
        return ret;
    }

    //设置返回后通知获取原始方法的返回值,要求returning属性值必须与方法形参名相同
    @AfterReturning(value = "pt()",returning = "ret")
    public void afterReturning(JoinPoint jp,String ret) {
        System.out.println("afterReturning advice ..."+ret);
    }

    //设置抛出异常后通知获取原始方法运行时抛出的异常对象,要求throwing属性值必须与方法形参名相同
   // @AfterThrowing(value = "pt()",throwing = "t")
    public void afterThrowing(Throwable t) {
        System.out.println("afterThrowing advice ..."+t);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值