自定义注解+AOP切面日志+源码

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 自定义注解+AOP切面日志+源码

注解

前言

注解是JavaEE的基础,更是在Spring中发扬光大。AOP中有大量使用。

说明

本案例主要通过俩个实操讲解、演示

  1. 切面注解日志
  2. 切面注解锁
  3. 切面注解权限

后俩个分别再出一个Demo,源码全部都在gitee免费提供

代码讲解

切面注解日志

1. 新建接口

新建接口用于测试

com\javapub\demo\annotation\springbootannotation\controller
2. 引入依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
3. 注解
package com.javapub.demo.annotation.springbootannotation.annotation;

/**
 * @Author: JavaPub
 * @License: https://github.com/Rodert/ https://gitee.com/rodert/
 * @Contact: https://javapub.blog.csdn.net/
 * @Date: 2022/1/25 15:22
 * @Version: 1.0
 * @Description: #自定义日志注解。
 * <p>
 * ①:什么时候使用该注解,我们定义为运行时;
 * ②:注解用于什么地方,我们定义为作用于方法上;
 * ③:注解是否将包含在 JavaDoc 中;
 * ④:注解名为 Log;
 * ⑤:定义一个属性,默认为空字符串;
 */

import java.lang.annotation.*;


@Target(ElementType.METHOD) //注解用于什么地方,我们定义为作用于方法上;
@Retention(RetentionPolicy.RUNTIME) //什么时候使用该注解,我们定义为运行时;
@Documented //注解是否将包含在 JavaDoc 中;
public @interface Log {//注解名为Log

    String value() default ""; //定义一个属性,默认为空字符串;

}
4. AOP切点类
  1. 这里实现了对自定义注解的环绕增强切点,对使用了自定义注解的方法进行AOP切面处理;
  2. 对方法运行时间进行监控;
  3. 对方法名,参数名,参数值,对日志描述的优化处理;

在方法上增加 @Aspect 注解声明切面,使用 @Pointcut 注解定义切点,标记方法。

使用切点增强的时机注解:@Before (前置通知),@Around,@AfterReturning,@AfterThrowing,@After(后置通知)

package com.javapub.demo.annotation.springbootannotation.aop;

/**
 * @Author: JavaPub
 * @License: https://github.com/Rodert/ https://gitee.com/rodert/
 * @Contact: https://javapub.blog.csdn.net/
 * @Date: 2022/1/25 15:42
 * @Version: 1.0
 * @Description: 注释式日志切面
 */

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@Slf4j
@Aspect //@Aspect:声明该类为一个注解类
@Component
public class LogAspect {

    /**
     * @Pointcut:定义一个切点,后面跟随一个表达式,表达式可以定义为切某个注解,也可以切某个 package 下的方法;
     * <p>
     * 此处的切点是注解的方式,也可以用包名的方式达到相同的效果
     * '@Pointcut("execution(* com.javapub.demo.annotation.springbootannotation.*.*(..))")'
     */
    @Pointcut("@annotation(com.javapub.demo.annotation.springbootannotation.annotation.Log)")
    public void logPointCut() {
    }

    /**
     * @param joinPoint
     * @return
     * @throws Throwable
     * @Around 环绕,可以在切入点前后织入代码,并且可以自由的控制何时执行切点;
     * @Description: 这里其实应该使用 try{}catch(){}finally{} 做容错,为了代码简洁易懂就不加了
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long beginTime = System.currentTimeMillis();
        // 执行方法
        Object result = joinPoint.proceed();
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //异步保存日志
        saveLog(joinPoint, time);
        return result;
    }

    void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = signature.getName();
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        System.out.println("**************************");
        System.out.println(method);
        log.info("------------------------接口日志-----------------------" + "\n"
                + "类名称:" + className + "\n"
                + "方法名:" + methodName + "\n"
                + "执行时间:" + time + "毫秒");
        log.info("接口参数" + "\n" + Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * 在切点之前,织入相关代码;
     *
     * @param joinPoint
     */
    @Before("logPointCut()")
    public void doBeforeAdvice(JoinPoint joinPoint) {
        log.info("进入方法前执行.....");
    }

    /**
     * 在切点返回内容后,织入相关代码,一般用于对返回值做些加工处理的场景;
     *
     * @param ret
     */
    @AfterReturning(returning = "ret", pointcut = "logPointCut()")
    public void doAfterReturning(Object ret) {
        log.info("方法的返回值 : {}", ret);
    }

    /**
     * 用来处理当织入的代码抛出异常后的逻辑处理;
     */
    @AfterThrowing("logPointCut()")
    public void throwss(JoinPoint jp) {
        log.info("方法异常时执行.....");
    }


    /**
     * 后置最终通知,final增强,不管是抛出异常或者正常退出都会执行
     */
    @After("logPointCut()")
    public void after(JoinPoint jp) {
        log.info("方法最后执行.....");
    }
}

测试

http://127.0.0.1:9001/order/order-info?id=1


http://127.0.0.1:9001/order/order-info-2/1


源码仓库:https://gitee.com/rodert/SpringBoot-javapub

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
Java API 数据安全/隐私保护
(工作经验)优雅实现接口权限校验控制:基于自定义注解、AOP与@ConditionalOnProperty配置开关的通用解决方案
(工作经验)优雅实现接口权限校验控制:基于自定义注解、AOP与@ConditionalOnProperty配置开关的通用解决方案
81 1
|
2月前
|
XML Java 数据格式
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
本文介绍了如何使用Spring框架的注解方式实现AOP(面向切面编程)。当目标对象没有实现接口时,Spring会自动采用CGLIB库进行动态代理。文中详细解释了常用的AOP注解,如`@Aspect`、`@Pointcut`、`@Before`等,并提供了完整的示例代码,包括业务逻辑类`User`、配置类`SpringConfiguration`、切面类`LoggingAspect`以及测试类`TestAnnotationConfig`。通过这些示例,展示了如何在方法执行前后添加日志记录等切面逻辑。
321 2
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
|
1月前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
48 1
|
2月前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
83 2
|
4月前
|
XML Java 数据库
Spring5入门到实战------10、操作术语解释--Aspectj注解开发实例。AOP切面编程的实际应用
这篇文章是Spring5框架的实战教程,详细解释了AOP的关键术语,包括连接点、切入点、通知、切面,并展示了如何使用AspectJ注解来开发AOP实例,包括切入点表达式的编写、增强方法的配置、代理对象的创建和优先级设置,以及如何通过注解方式实现完全的AOP配置。
|
3月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
AOP(面向切面编程)能够帮助我们在不修改现有代码的前提下,为应用程序添加新的功能或行为。Micronaut框架中的AOP模块通过动态代理机制实现了这一目标。AOP将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,提高模块化程度。在Micronaut中,带有特定注解的类会在启动时生成代理对象,在运行时拦截方法调用并执行额外逻辑。例如,可以通过创建切面类并在目标类上添加注解来记录方法调用信息,从而在不侵入原有代码的情况下增强应用功能,提高代码的可维护性和可扩展性。
73 1
|
1月前
|
安全 Java 编译器
什么是AOP面向切面编程?怎么简单理解?
本文介绍了面向切面编程(AOP)的基本概念和原理,解释了如何通过分离横切关注点(如日志、事务管理等)来增强代码的模块化和可维护性。AOP的核心概念包括切面、连接点、切入点、通知和织入。文章还提供了一个使用Spring AOP的简单示例,展示了如何定义和应用切面。
129 1
什么是AOP面向切面编程?怎么简单理解?
|
1月前
|
XML Java 开发者
论面向方面的编程技术及其应用(AOP)
【11月更文挑战第2天】随着软件系统的规模和复杂度不断增加,传统的面向过程编程和面向对象编程(OOP)在应对横切关注点(如日志记录、事务管理、安全性检查等)时显得力不从心。面向方面的编程(Aspect-Oriented Programming,简称AOP)作为一种新的编程范式,通过将横切关注点与业务逻辑分离,提高了代码的可维护性、可重用性和可读性。本文首先概述了AOP的基本概念和技术原理,然后结合一个实际项目,详细阐述了在项目实践中使用AOP技术开发的具体步骤,最后分析了使用AOP的原因、开发过程中存在的问题及所使用的技术带来的实际应用效果。
67 5
|
3月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
【9月更文挑战第9天】AOP(面向切面编程)通过分离横切关注点提高模块化程度,如日志记录、事务管理等。Micronaut AOP基于动态代理机制,在应用启动时为带有特定注解的类生成代理对象,实现在运行时拦截方法调用并执行额外逻辑。通过简单示例展示了如何在不修改 `CalculatorService` 类的情况下记录 `add` 方法的参数和结果,仅需添加 `@Loggable` 注解即可。这不仅提高了代码的可维护性和可扩展性,还降低了引入新错误的风险。
54 13
|
2月前
|
Java 容器
AOP面向切面编程
AOP面向切面编程
46 0
下一篇
DataWorks