springboot AOP动态代理

复制代码
package com.example.tlias.AOPbao;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/*AOP是什么:
动态代理是面向切面编程最主流的实现。
而SpringAOP是Spring框架的高级技术,
旨在管理bean对象的过程中,
主要通过底层的动态代理机制,对特定的方法进行编程
其他就是一个动态代理可以增强或者增加一个或者多个方法功能

AOP需要的依赖
<!--AOP相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>    */

//把AOP类加入IOC  ben里
@Component

//@Aspect  表示这是一个AOP类
@Aspect

//日志注解
@Slf4j
public class AOPdongtaidaili {
   /*@Pointcut该注解的作用是将公共的切点表达式抽取出来,
       需要用到时引用该切点表达式即可。 抽取共性内容
      比如@Around("pt()")这样调用
   */

    @Pointcut("execution(* com.example.tlias.sevicechuli.*.*(..))")
    public void pt() {
    }

       /*
      AOP常用注解:
     1. @Around:  环绕通知,此注解标注的通知方法在目标方法前、后都被执行 只这个方法需要添加形参
      ProceedingJoinPoint   joinPoint   调用   joinPoint.proceed(); 来让原始方法执行,
      其他通知不需要考虑目标方法执行
      @Around环绕通知方法的返回值,必须指定为0bject,来接收原始方法的返回值。

     2. @Before:   前置通知,此注解标注的通知方法在目标方法前被执行
     3. @After :   后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
     4. @AfterReturning :  返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
     5. @AfterThrowing:   异常后通知,此注解标注的通知方法发生异常后执行
      */

      /*
   AOP切入点解析
  @Around表示切这是一个AOP类

   1.execution切入点表达式写法
   注意空格 ?号表示可以省略
   切入点表达式格式   execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数)throws 异常?)
   切入点表达式: @Around("execution(* com.example.tlias.sevicechuli.*.*(..))")
   这里的*表示可以任意返回值

    1.com.example.tlias.sevicechuli需要代理的类或接口所存放的位置
    2.  *  :单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、任意类型的一个参数,
    也可以通配包、类、方法名的一部分比如delete*表示delete开头的任意方法都可以
    可以写成@Around("execution(* com.itheima.*.impl.DeptServiceImpl.*())")

   @Around("execution(* com.itheima.*.impl.DeptServiceImpl.*(..))")
    3.   ..  : 多个连续的任意符号,可以通配任意层级的包,或任意类型、任意个数的参数
    注意他只能替换包和形参和*不同的是他表示可以是任意数量  *表示一个*表示一个
    比如@Around("execution(* com.itheima.*.impl.DeptServiceImpl.*(*))")只能表示一个哦

    4.如果是@Around("execution(* com.itheima.service.impl.DeptServiceImpl.list ())")
    表示只list ()方法被代理

    5.也可以加上 &&  || !  符号比如
    @Around("execution(* com.itheima.service.impl.DeptServiceImpl.list ()) ||  execution(* com.itheima.service.impl.DeptServiceImpl.list ()) ")
   */

      /*  1.不同切面类中,默认按照切面类的类名字母排序:
       ◆目标方法前的通知方法:字母排名靠前的先执行.
       比如方法名字 ABC1和BAC1  则ABC1先执行 比完第一个字母一样接着比第二个以此类推

       ◆目标方法后的通知方法:字母排名靠前的后执行
       比如方法名字 ABC1和BAC1  则BAC1先执行 比完第一个字母一样接着比第二个以此类推

     2.用 @Order(数字) 加在切面类上来控制顺序
              目标方法前的通知方法:数字小的先执行
              比如:
              @Order(1)
              @Around("pt()")
              public Object aopp(ProceedingJoinPoint joinPoint){}

              目标方法后的通知方法:数字小的后执行
               比如:
              @Order(1)
              @Around("pt()")
              public Object aopp(ProceedingJoinPoint joinPoint){}
            */

       /*
      2.@annotation()切入点表达式写法是基于自定义注解的只要加上注解就会执行
       1.自定义注解实例:
       @Retention(RetentionPolicy.RUNTIME)//这个注解表示这是一个运行时期注解
      @Target(ElementType.METHOD)//这个注解表示可以加在方法上
       public @interface mylog { }

          2.具体演示代码:
         1.需要被执行方法:
          @mylog  //加上就会执行
          public void add(dept poST) {}

        2.抽出共同的切入点表达式写法:
        这里指的是注解在那个包
       @Pointcut("@annotation(com.example.tlias.sevicechuli.mylog)")
       public void pt(){}
      */

     /*
     连接点:
     在Spring中用joinPoint抽象了连接点,用它可以获得方法执行时的相关信息,
     如目标类名、方法名、方法参数等,
     连接点就是AOP目前方法执行前后需要执行的方法
      这里主要介绍joinPoint里面形参的 如何获取类名、方法名、方法参数
      joinPoint是ProceedingJoinPoint的父类他们的方法是共用的可以用在除@Around
      环绕通知以外的注解上

        1.实例代码:
         @Order(1)
        @Around("pt()")//切入点表达式
        //加入ProceedingJoinPoint joinPoint  表示那个类需要被AOP动态代理
        public void aopp(JoinPoint zhixing) throws Throwable {

        String name = zhixing.getTarget().getClass().getName();  //获取目标类名

        Signature signature = zhixing.getSignature();  //获取目标方法名

        String name1 = zhixing.getSignature().getName();//获取操作方法名 com.example.tlias.conller.conllemp

        Object[] args = zhixing.getArgs();//获取目标方法运行参数
    }
     */




    @Order(1)
    @Around("pt()")//切入点表达式
    //加入ProceedingJoinPoint joinPoint  表示那个类需要被AOP动态代理
    public Object aopp(ProceedingJoinPoint joinPoint) throws Throwable {
        long l = System.currentTimeMillis();

        //调用被代理的原方法
        Object proceed = joinPoint.proceed();//环绕通知专属

        long l2 = System.currentTimeMillis();

        long shu = l - l2;

        //记录时间日记输出用时
        log.info("当前方法所需用时" + shu + "毫秒");

        return proceed;

    }

    /*@Order(1)
    @Around("pt()")//切入点表达式
    //加入ProceedingJoinPoint joinPoint  表示那个类需要被AOP动态代理
    public void aopp(JoinPoint zhixing) throws Throwable {

        String name = zhixing.getTarget().getClass().getName();  //获取目标类名
        Signature signature = zhixing.getSignature();  //获取目标方法签名
        String name1 = zhixing.getSignature().getName();//获取目标方法名
        Object[] args = zhixing.getArgs();//获取目标方法运行参数

    }*/



}
相关推荐
松仔log6 分钟前
Java多线程——对象的组合
java·开发语言·jvm
酷爱码23 分钟前
springboot 动态配置定时任务
java·spring boot·后端
计算机-秋大田37 分钟前
基于SpringBoot的美食烹饪互动平台的设计与实现(源码+SQL脚本+LW+部署讲解等)
vue.js·spring boot·后端·课程设计·美食
从未止步..43 分钟前
Jenkins未在第一次登录后设置用户名,第二次登录不进去怎么办?
java·运维·jenkins
老马啸西风1 小时前
IM 即时通讯系统-42-基于netty实现的IM服务端,提供客户端jar包,可集成自己的登录系统
java
加油,旭杏1 小时前
【go语言】grpc 快速入门
开发语言·后端·golang
2501_903238651 小时前
Java 9模块开发:Eclipse实战指南
java·开发语言·eclipse·个人开发
brzhang1 小时前
墙裂推荐一个在 Apple Silicon 上创建和管理虚拟机的轻量级开源工具:lume
前端·后端
test猿1 小时前
hive为什么建表,表存储什么
java
程序猿零零漆2 小时前
SpringCloud系列教程:微服务的未来(二十)Seata快速入门、部署TC服务、微服务集成Seata
java·spring·spring cloud·微服务