Springboot 中AOP的使用

面向切面编程(Aspect Oriented Programming) 是软件编程思想发展到一定阶段的产物,是面向对象编程的有益补充。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包及其子包下所有类的所有方法

猜你喜欢

转载自www.cnblogs.com/double-yuan/p/12101231.html