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

Springboot 中AOP的使用

程序员文章站 2023-10-29 10:37:16
面向切面编程(Aspect Oriented Programming) 是软件编程思想发展到一定阶段的产物,是面向对象编程的有益补充。AOP一般适用于具有横切逻辑的场合,如访问控制、事务管理、性能检测等。 日志、异常处理、事务控制等都是一个健壮的业务系统所必须的。但是为了保证系统健壮可用,就要再众多 ......

面向切面编程(aspect oriented programming) 是软件编程思想发展到一定阶段的产物,是面向对象编程的有益补充。aop一般适用于具有横切逻辑的场合,如访问控制、事务管理、性能检测等。

日志、异常处理、事务控制等都是一个健壮的业务系统所必须的。但是为了保证系统健壮可用,就要再众多业务方法中反复编写类似的代码,使得原本就很复杂的业务处理代码变得更加复杂。业务功能的开发者还要考两次这些额外的代码是否处理正确,是否有遗漏的地方,如果需要修改日志信息的格式或者安全验证的规则,或者再增加辅助功能,都会导致业务代码频繁而大量的修改。

面向切面编程,就是在不改变原程序的基础上为代码增加新的功能,对代码段进行增强处理。他的设计思想来源于代理设计模式。

Springboot  中AOP的使用

 

 

 

1.在原对象方法之前插入的增强处理为前置增强

2.该方法执行完以后插入的增强处理为后置增强

3.环绕在方法前后的增强处理为环绕增强,是最强大的增强处理,可以获取或者修改目标方法的参数、返回值、异常处理、甚至决定目标方法是否执行。

4.该方法抛出异常时的增强处理为异常抛出增强 

5.最终增强处理,无论方法抛出异常还是正常退出都会得到执行,类似于异常处理机制中finally块的作用,一般用于释放资源

 

在springboot中使用注解

需要引入所需要的jar :spring-boot-starter-aop

创建一个aop增强处理类

@slf4j
@aspect
@component
public class loggeraspect {

    // 匹配 com.lzz.lzzapp.common.user包及子包下所有类的所有方法
    @pointcut("execution(* com.lzz.lzzapp.common.user..*.*(..))")
    public void logpointcut(){

    }
    //前置增强 在连接点执行之前执行的通知
    @before("logpointcut()")
    public void before(){
        log.info("即将调用业务方法");
    }
    //最终增强 在连接点执行之后执行的通知(返回通知和异常通知的异常)
    @after("logpointcut()")
    public void after(){
        log.info("业务方法调用完成");
    }

    /**
     * 后置增强 在连接点执行之后执行的通知(返回通知)
     */
    @afterreturning(value="logpointcut()",returning="result")
    public void doafterreturning(joinpoint joinpoint, object result){
        string methodname = joinpoint.getsignature().getname();
        log.info("调用"+joinpoint.gettarget()+"的"+methodname+"方法。参数:"+arrays.tostring(joinpoint.getargs())
                +"。方法返回值:"+result);
    }

    /**
     * 异常增强 在连接点执行之后执行的通知(异常通知)
     */
    @afterthrowing("logpointcut()")
    public void doafterthrowing(){
        log.info("异常处理完成");
    }

    /**
     * 环绕增强
     */
    @around("logpointcut()")
    public void doaround(proceedingjoinpoint jp){
        log.info("调用"+jp.gettarget()+"的"+jp.getsignature().getname()+"方法。参数:"+arrays.tostring(jp.getargs()));
        try {
            object result=jp.proceed();//执行目标方法
            log.info("方法返回值:"+result);
        }catch (throwable e){
            log.error(jp.getsignature().getname()+"方法发生异常");
            e.printstacktrace();
        }
    }

}

 

使用@aspect定义切面,@pointcut定义切入点

切入点匹配的执行点为连接点为jointpoint,spring会自动注入该实例,通过joinpoint 的gettarget()方法可以得到被代理对象,getsignature()方法返回被代理的目标方法。getargs()方法返回传递给目标方法的参数数组

对于后置增强,还可以定义一个用于接收被代理方法的返回值,必须在 @afterreturning 注解中通过returning 属性指定该参数的名称

execution是切入点指示符,他括号中是一个切入点表达式,可以配置要切入的方法,切入点表达式支持模糊匹配

public * adduser(com.entity.user)     * 表示匹配所有类型的返回值
public void *(com.entity.user)           * 表示匹配所有方法名
public void adduser(..)                     .. 表示匹配所有参数个数和类型                
* com.user.*.*(..)               表示匹配com.entity包下所有类的所有方法
* com.user..*.*(..)              表示匹配com.entity包及其子包下所有类的所有方法