欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Springboot使用AOP整合日志

程序员文章站 2022-05-15 17:33:31
...

spring-boot 使用 AOP 切面的方式记录 web 请求日志
切面的概念:通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术

@Aspect //定义这是一个切面
Pointcut配置使用:表示式(expression)和签名(signature)
//Pointcut表示式:
@Pointcut("execution(public * com.cn.log.aop.controller.*Controller.*(..))")
//Point签名
private void log(){}

Pointcut使用详细语法:
任意公共方法的执行:execution(public * *(..))
任何一个以“set”开始的方法的执行:execution(* set*(..))
AccountService 接口的任意方法的执行:execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行: execution(* com.xyz.service.*.*(..))
定义在service包和所有子包里的任意类的任意方法的执行:execution(* com.xyz.service..*.*(..))
第一个*表示匹配任意的方法返回值, ..(两个点)表示零个或多个,第一个..表示service包及其子包,第二个*表示所有类, 第三个*表示所有方法,第二个..表示方法的任意参数个数
定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
pointcutexp包里的任意类: within(com.test.spring.aop.pointcutexp.*)
pointcutexp包和所有子包里的任意类:within(com.test.spring.aop.pointcutexp..*)
实现了Intf接口的所有类,如果Intf不是接口,限定Intf单个类:this(com.test.spring.aop.pointcutexp.Intf)
带有@Transactional标注的所有类的任意方法:
@within(org.springframework.transaction.annotation.Transactional) // 亲测成功
@target(org.springframework.transaction.annotation.Transactional) // 亲测未成功


作者:Saxon_323e
链接:https://www.jianshu.com/p/830e799e099b
来源:简书

JointPoint(连接点): 程序执行过程中明确的点,一般是方法的调用
Pointcut(切入点): 带有通知的连接点,在程序中主要体现为书写切入点表达式
Advice(通知): AOP在特定的切入点上执行的增强处理:
Aspect(切面):是切入点和通知的结合,即对连接点的拦截定义和增强的逻辑或通知。
Introduction(引介):引介是一种特殊的通知,在不修该类代码的前提下,Introduction可以在运行期为类动态地 添加一些方法和属性。
Target(目标对象):代理的目标对象(即需要增强的类)
Weaving(织入):是把增强应用到目标的过程,把advice应用到target的过程。
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类。

5种注解类型
@Before: 标识一个前置增强方法,相当于BeforeAdvice的功能
@After: final增强,不管是抛出异常或者正常退出都会执行。
@Around: 环绕增强,相当于MethodInterceptor
@AfterReturning: 后置增强,似于AfterReturningAdvice, 方法正常退出时执行
@AfterThrowing: 异常抛出增强,相当于ThrowsAdvice

下面两张图是一个方法被一个Aspect类切,第一张图正常返回,第二张图抛出异常
图一
Springboot使用AOP整合日志

图二
Springboot使用AOP整合日志
AOP Proxy:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类

jdk动态代理是jdk原生就支持的一种代理方式,它的实现原理,就是通过让target类和代理类实现同一接口,代理类持有target对象,来达到方法拦截的作用,这样通过接口的方式就有两个弊端,一是必须保证target类有接口,第二个是如果想要对target类的方法进行拦截,那么就要保证这些方法在接口中声明

CGLIB(Code Genertation Library)是一个开源项目。意为强大的高性能代码生成包,底层通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类,可在运行期扩展java类与实现java接口。

个人理解:先定义某个类为切面,在该类中定义pointcut(切入点),这个切入点是一个公式,会指定方法,这个时候你就可以在这个方法执行前后进行你想要的操作,@Before(),@Around(),@After()等,@Before(“log()”)等注解中需要放入切面,@Before所在的方法中可以传入切点作为参数

Springboot使用AOP整合日志