美文网首页JAVA后端架构
Springboot 中AOP的使用

Springboot 中AOP的使用

作者: AI乔治 | 来源:发表于2019-12-27 21:57 被阅读0次

    面向切面编程(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包及其子包下所有类的所有方法
    

    我自己建了个群,对 JAVA 开发有兴趣的朋友欢迎加入QQ群:976203838 进行技术讨论,里面资深架构师会分享一些整理好的BATJ面试题:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。

    相关文章

      网友评论

        本文标题:Springboot 中AOP的使用

        本文链接:https://www.haomeiwen.com/subject/cikjoctx.html