[Java日志切面 ]

 

目录

 🍚前言:

🍚代码实现:

🍚优化后的代码:

🍚优化后的代码:



 🍚前言:

    最近在打英雄联盟 一下子冲到了 黄金,奥里给

🍚代码实现:

@Aspect
@Component
public class LoggingAspect {

    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Before("execution(* com.example.demo.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        logger.info("Before method: " + joinPoint.getSignature().getName());
    }

    @After("execution(* com.example.demo.service.*.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        logger.info("After method: " + joinPoint.getSignature().getName());
    }

    @AfterReturning(pointcut = "execution(* com.example.demo.service.*.*(..))", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        logger.info("After returning method: " + joinPoint.getSignature().getName() + ", result: " + result);
    }

    @AfterThrowing(pointcut = "execution(* com.example.demo.service.*.*(..))", throwing = "exception")
    public void logAfterThrowing(JoinPoint joinPoint, Exception exception) {
        logger.error("After throwing method: " + joinPoint.getSignature().getName() + ", exception: " + exception.getMessage());
    }
}

示例中,我们使用了Spring AOP框架来实现日志切面。我们定义了一个LoggingAspect类,并使用@Aspect注解将其标记为切面类。我们还使用@Component注解将其标记为Spring组件,以便Spring可以自动扫描并将其实例化。

我们定义了四个切点方法,分别在方法执行前、执行后、执行成功返回后和执行抛出异常后执行。我们使用@Before、@After、@AfterReturning和@AfterThrowing注解来标记这些方法,并使用execution表达式指定切点。在这个示例中,我们使用了通配符来匹配com.example.demo.service包中的所有方法。

在每个切点方法中,我们使用JoinPoint参数来获取当前执行的方法的名称和参数。我们使用LoggerFactory获取一个Logger实例,并使用info()或error()方法记录日志。在@AfterReturning方法中,我们还使用返回值参数来记录方法的返回值。

最后,我们需要在Spring配置文件中启用AOP自动代理,以便Spring可以自动将切面织入我们的应用程序中。我们可以使用以下配置:

<aop:aspectj-autoproxy />

示例只是一个简单的演示,实际的日志切面可能需要更复杂的逻辑和更详细的日志记录

🍚优化后的代码:

@Aspect
@Component
public class LoggingAspect {

    private final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Pointcut("execution(* com.example.demo.service.*.*(..))")
    public void serviceMethods() {}

    @Before("serviceMethods()")
    public void logBefore(JoinPoint joinPoint) {
        logger.info("Before method: {}", joinPoint.getSignature().getName());
    }

    @AfterReturning(pointcut = "serviceMethods()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        logger.info("After returning method: {}, result: {}", joinPoint.getSignature().getName(), result);
    }

    @AfterThrowing(pointcut = "serviceMethods()", throwing = "exception")
    public void logAfterThrowing(JoinPoint joinPoint, Exception exception) {
        logger.error("After throwing method: {}, exception: {}", joinPoint.getSignature().getName(), exception.getMessage());
    }
}

示例中,我们使用了更简洁的语法来定义切点和切点方法。我们使用@Pointcut注解定义了一个名为serviceMethods的切点方法,它匹配com.example.demo.service包中的所有方法。我们还使用{}和参数占位符来更方便地记录日志。

我们还删除了@After注解,因为它不是必需的。如果我们不需要在方法执行后记录日志,我们可以完全省略它。

最后,我们还使用了final关键字来定义Logger实例,以便它不能被修改。这是一个良好的实践,因为Logger实例通常是线程安全的,所以我们不需要在每个方法调用中创建一个新的实例。

🍚优化后的代码:

@Aspect
@Component
public class LoggingAspect {

    private final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Pointcut("execution(* com.example.demo.service.*.*(..))")
    public void serviceMethods() {}

    @Before("serviceMethods()")
    public void logBefore(JoinPoint joinPoint) {
        logger.info("Before method: {}", joinPoint.getSignature().getName());
    }

    @AfterReturning(pointcut = "serviceMethods()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        logger.info("After returning method: {}, result: {}", joinPoint.getSignature().getName(), result);
    }

    @AfterThrowing(pointcut = "serviceMethods()", throwing = "exception")
    public void logAfterThrowing(JoinPoint joinPoint, Exception exception) {
        logger.error("After throwing method: {}, exception: {}", joinPoint.getSignature().getName(), exception.getMessage());
    }

    @Around("serviceMethods()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = null;
        try {
            result = joinPoint.proceed();
            return result;
        } finally {
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            logger.info("Method: {}, execution time: {} ms", joinPoint.getSignature().getName(), duration);
        }
    }
}

示例中,我们添加了一个新的切点方法logAround,它使用@Around注解来拦截方法的执行,并在方法执行前后记录日志。我们使用ProceedingJoinPoint参数来调用原始方法,并使用try-finally块来确保我们在方法执行后记录日志。

我们还添加了一个计时器来记录方法的执行时间。我们使用System.currentTimeMillis()方法来获取当前时间,并在方法执行前和执行后记录时间。我们还使用Object类型的变量result来存储方法的返回值,并在finally块中返回它。

这个示例还演示了如何在同一个切面中使用多个切点方法来拦截不同的方法。我们可以使用不同的execution表达式来匹配不同的方法,并在不同的切点方法中记录日志。这使得我们可以更灵活地控制日志记录的粒度和详细程度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是汤圆丫

怎么 给1分?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值