Springboot5 AOP 编程解析

简介

应用场景

日志

  • 日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此。

事务

  • 调用方法前开启事务, 调用方法后提交关闭事务

术语

切点

连接点

JDK代理

CGLIB代理

Spring 5 代理

代理机制

  • 默认是JDK代理,因为是建议多用接口来设计程序
  • 也可以强制使用CGLIB代理
    在这里插入图片描述

Springboot

Springboot 2.x 代理

  • Spring 5.x中AOP默认依旧使用JDK动态代理
  • SpringBoot 2.x开始,为了解决使用JDK动态代理可能导致的类型转换异常,而使用CGLIB。
  • 在SpringBoot 2.x中,如果需要替换使用JDK动态代理可以通过配置项spring.aop.proxy-target-class=false来进行修改,proxyTargetClass配置已无效。

Springboot Aop 例子

@Aspect
@Component
public class FaultEventAnalyzeAspect {


    private static Logger log = LoggerFactory.getLogger(FaultEventAnalyzeAspectTest.class);
    @Autowired
    FaultEventUtil faultEventUtil;

    /**
     * @Description: analyseEvents为前缀的方法
     * @Param:
     * @return:
     */
    @Pointcut("execution(public * com.dfe.e8800p.scheduler.service.impl.*.analyze(..))")
    public void excutePoint() {
        log.info("analyse方法 为切点");

    }




//    // 前置通知:在目标方法执行之前执行
//    @Before(value = "excutePoint()")
//    public void befor(JoinPoint joinPoint) {
//        String name = joinPoint.getSignature().getName();
//        System.out.println(name + "方法, 执行 befor");
//    }
//
//    // 后置通知:在目标方法执行之后执行
//    @After(value = "excutePoint()")
//    public void after(JoinPoint joinPoint) {
//        String name = joinPoint.getSignature().getName();
//        System.out.println(name + "方法, 执行 after");
//    }
//
//    // 返回通知:获取目标方法的返回值
//    @AfterReturning(value = "excutePoint()", returning = "result")
//    public void afterReturning(JoinPoint joinPoint, Object result) {
//        String name = joinPoint.getSignature().getName();
//        System.out.println(name + "方法, 执行 " + "afterReturning" + ", 返回: " + result);
//    }
//
//    // 异常通知:当目标方法出现异常时,会执行该方法
//    @AfterThrowing(value = "excutePoint()", throwing = "e")
//    public void afterThrowing(JoinPoint joinPoint, Exception e) {
//        String name = joinPoint.getSignature().getName();
//        System.out.println(name + "方法, 执行 " + "afterThrowing" + ", 抛出异常: " + e);
//    }
//


    // 环绕通知:可实现任意通知,可调用 proceedingJoinPoint.proceed() 方法使目标方法继续执行

    /**
     * @Description: 分析事件之前打印日志,统计耗时
     * @Param:
     * @return:
     */
    @Around(value = "excutePoint()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        Date start = new Date();
        String[] nameArr = proceedingJoinPoint.getSignature().getDeclaringTypeName().split("\\.");
        String name=nameArr[nameArr.length-1];
        log.info(name + " start");
        /*执行方法*/
        Object object = null;

        try {
            object=proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }


        /*分析结果保存到数据库*/
        faultEventUtil.insertEventsList();
        log.info(name + " finished,cost " + DateUtil.between(start, new Date(), DateUnit.SECOND) + " s");

        return object;



    }

}

常用的AOP通知类型

参考链接

Aspect Oriented Programming with Spring
SpringBoot AOP的使用
SpringBoot在2.x默认使用Cglib动态代理
SpringBoot - 面向切面编程 AOP 的配置和使用(附样例)
Spring AOP切点表达式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值