[spring]Spring AOP 及 代理模式

一. AOP介绍

Spring框架两大核心:

  1. IoC
  2. AOP
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

二. AOP使用

  1. 引入依赖
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
 </dependency>
  1. 编写AOP程序
    记录Controller中每个方法的执行时间

@Slf4j
@Aspect
@Component
public class TimeAspect {
    @Around("execution(* com.example.demo.controller.*.*(..))")
    public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
        //记录方法执行开始时间
        long begin = System.currentTimeMillis();
        //执行方法
        Object result = pjp.proceed();
        //记录执行方法结束时间
        long end = System.currentTimeMillis();
        //记录方法执行耗时
        log.info(pjp.getSignature() + "耗时: {} ms",end-begin);
        return result;
    }
}

在这里插入图片描述

Spring AOP核心概念

切点

在这里插入图片描述
在这里插入图片描述
这就是切点表达式

连接点

在这里插入图片描述

@RequestMapping("/test")
@RestController
public class TestController {
    @RequestMapping("/t1")
    public String t1() {
        return "t1";
    }
    @RequestMapping("/t2")
    public Boolean t2() {

        return true;
    }
    @RequestMapping("/t3")
    public Integer t3() {
        return 1;
    }
}

这些方法都是连接点

通知

在这里插入图片描述
在这里插入图片描述

切面

在这里插入图片描述
在这里插入图片描述
切⾯所在的类,我们⼀般称为切⾯类(被@Aspect注解标识的类)

通知类型

在这里插入图片描述

@Slf4j
@Aspect
@Component
public class TimeAspect {
    @Around("execution(* com.example.demo.controller.*.*(..))")
    public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
        //记录方法执行开始时间
        long begin = System.currentTimeMillis();
        //执行方法
        Object result = pjp.proceed();
        //记录执行方法结束时间
        long end = System.currentTimeMillis();
        //记录方法执行耗时
        log.info(pjp.getSignature() + "耗时: {} ms",end-begin);
        return result;
    }

    @Before("execution(* com.example.demo.controller.*.*(..))")
    public void doBefore(){
        log.info("执行before方法");
    }
    @After("execution(* com.example.demo.controller.*.*(..))")
    public void doAfter(){
        log.info("执行After方法");

    }
    @AfterReturning("execution(* com.example.demo.controller.*.*(..))")
    public void doAfterReturning(){
        log.info("执行AfterReturning方法");

    }
    @AfterThrowing("execution(* com.example.demo.controller.*.*(..))")
    public void doAfterThrowing(){
        log.info("执行AfterThrowing方法");

    }
    @Around("execution(* com.example.demo.controller.*.*(..))")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("Around方法开始前");
        Object object = joinPoint.proceed();
        log.info("Around方法开始后");
        return object;
    }
}

测试:
在这里插入图片描述
在这里插入图片描述

发生异常:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@PointCut

在这里插入图片描述

 @Pointcut("execution(* com.example.demo.controller.*.*(..))")
    public void pt(){}

    @Before("pt()")
    public void doBefore(){
        log.info("执行before方法");
    }

在这里插入图片描述

切面优先级@Order

现有两个切面类, 分别有before和after方法, 那么方法的执行顺序为:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

切点表达式

在这里插入图片描述

execution(…)

execution() 是最常⽤的切点表达式,⽤来匹配⽅法,语法为:

execution(<访问修饰符> <返回类型> <包名.类名.⽅法(⽅法参数)> <异常>)

其中:访问修饰符和异常可以省略
在这里插入图片描述
在这里插入图片描述

@annotation

可是使用自定义注解和@annotation的方式来描述哪些方法需要切面
在这里插入图片描述

自定义注解

在这里插入图片描述

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAspect {
}

在这里插入图片描述

使用@annotation

使用@annotation来描述自定义注解, 放在切点表达式中
表示, 只有加了自定义注解的方法, 才是连接点

@Aspect
@Component
@Slf4j
public class MyAspectDemo {
    @Around("@annotation(com.example.demo.aspect.MyAspect)")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("方法前");
        Object object = joinPoint.proceed();
        log.info("方法后");
        return object;
    }
}

在这里插入图片描述

添加自定义注解

在这里插入图片描述

只给t3加注解, 测试:
在这里插入图片描述

三. 代理模式

在这里插入图片描述
使用代理前:
在这里插入图片描述
使用代理后:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

静态代理:在程序运⾏前,代理类的.class⽂件就已经存在了
相⽐于静态代理来说,动态代理更加灵活
在这里插入图片描述
Spring AOP是基于动态代理实现的
Java也对动态代理进⾏了实现,并给我们提供了⼀些API,常⻅的实现⽅式有两种:
在这里插入图片描述
JDK动态代理有⼀个最致命的问题是其只能代理实现了接⼝的类
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值