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();//获取目标方法运行参数
}*/
}
springboot AOP动态代理
ikun,ikun2024-02-04 18:44
相关推荐
顾北川_野3 分钟前
Android 手机设备的OEM-unlock解锁 和 adb push文件江深竹静,一苇以航6 分钟前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘confiself22 分钟前
大模型系列——LLAMA-O1 复刻代码解读Wlq041526 分钟前
J2EE平台XiaoLeisj33 分钟前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期杜杜的man37 分钟前
【go从零单排】go中的结构体struct和method幼儿园老大*38 分钟前
走进 Go 语言基础语法llllinuuu39 分钟前
Go语言结构体、方法与接口cookies_s_s40 分钟前
Golang--协程和管道为什么这亚子42 分钟前
九、Go语言快速入门之map