springboot自定义日志注解@Log

  1. 创建自定义注解接口

    package com.example.lambda.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * @author: WZ
     * @create: 2022-10-17 09:18
     * @description: 1、自定义日志注解接口
     * @Target(ElementType.TYPE) // 接口、类、枚举、注解
     * @Target(ElementType.FIELD) // 字段、枚举的常量
     * @Target(ElementType.METHOD) //方法
     * @Target(ElementType.PARAMETER) //方法参数
     * @Target(ElementType.CONSTRUCTOR) //构造函数
     * @Target(ElementType.LOCAL_VARIABLE)//局部变量
     * @Target(ElementType.ANNOTATION_TYPE)//注解
     * @Target(ElementType.PACKAGE) ///包
     * @Retention注解: 这个参数有三种,一般默认第三种
     * <p>
     * 1. RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,
     * <p>
     * 编译时就会被忽略
     * <p>
     * 2. RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,
     * <p>
     * 但JVM将会忽略
     * <p>
     * 3. RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,
     * <p>
     * 所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。
     * 第二种写法:
     * @Documented 和 @Order(优先级:数字越小优先级越高)
     * @Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中。
     * @Order标记定义了组件的加载顺序,这个标记包含一个value属性。属性接受整形值。 如:1,2 等等。值越小拥有越高的优先级。
     * <p>
     * Ordered.HIGHEST_PRECEDENCE这个属性值是最高优先级的属性,它的值是-2147483648,对应的最低属性值是Ordered.LOWEST_PRECEDENCE,它的值是2147483647。
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Log {
        /**
         * 模块
         */
        String title() default "";
    
        /**
         * 是否保存请求的参数
         */
        boolean isSaveRequestData() default true;
    
        /**
         * 是否保存响应的参数
         */
        boolean isSaveResponseData() default true;
    }
    
    
  2. 创建LogAspect类对自定义注解进行操作

    package com.example.lambda.annotation;
    
    import com.alibaba.fastjson.JSONObject;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.Collection;
    import java.util.Map;
    
    /**
     * 操作日志记录处理
     *
     * @author: WZ
     * @create: 2022-10-17 09:18
     * @description: 2、自定义注解操作
     */
    @Aspect
    @Component
    @Slf4j
    public class LogAspect {
    
    
        /**
         * 配置织入点
         */
        @Pointcut("@annotation(com.example.lambda.annotation.Log)")
        public void logPointCut() {
        }
    
        /**
         * 处理完请求后执行
         *
         * @param joinPoint 切点
         */
        @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
        public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
            handleLog(joinPoint, controllerLog, null, jsonResult);
        }
    
        /**
         * 拦截异常操作
         *
         * @param joinPoint 切点
         * @param e         异常
         */
        @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
        public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
            handleLog(joinPoint, controllerLog, e, null);
        }
    
        protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
            try {
                //获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息
                Signature signature = joinPoint.getSignature();
                //获取传入目标方法的参数对象
                Object[] args = joinPoint.getArgs();
                //获取被代理的对象
                Object target = joinPoint.getTarget();
                //获取代理的对象
                Object aThis = joinPoint.getThis();
                //接口请求方式
                String method = getHttpMethod();
    
                String params = argsArrayToString(joinPoint.getArgs());
                /**
                 * 是否保存请求的参数
                 */
                if (controllerLog.isSaveRequestData()) {
    
                }
                /**
                 * 是否保存响应的参数
                 */
                if (controllerLog.isSaveResponseData()) {
    
                }
    
                log.info("---------------------signature:{}", signature);
                log.info("---------------------params:{}", params);
                log.info("---------------------target:{}", target);
                log.info("---------------------aThis:{}", aThis);
                log.info("---------------------method:{}", method);
                log.info("---------------------异常信息:{}", e);
                log.info("---------------------jsonResult:{}", jsonResult);
    
            } catch (Exception exp) {
                // 记录本地异常日志
                log.error("==前置通知异常==");
                log.error("异常信息:{}", exp.getMessage());
                exp.printStackTrace();
            }
        }
    
        /**
         * 获取请求方式
         *
         * @return
         */
        public static ServletRequestAttributes getAttributes() {
            RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
            return (ServletRequestAttributes) attributes;
        }
    
        public static String getHttpMethod() {
            String method = getAttributes().getRequest().getMethod();
            return method;
        }
    
        /**
         * 参数拼装
         */
        private String argsArrayToString(Object[] paramsArray) {
            String params = "";
            if (paramsArray != null && paramsArray.length > 0) {
                for (Object o : paramsArray) {
                    if (o != null && !isFilterObject(o)) {
                        try {
                            Object jsonObj = JSONObject.toJSONString(o);
                            params += jsonObj.toString() + " ";
                        } catch (Exception e) {
                        }
                    }
                }
            }
            return params.trim();
        }
    
        /**
         * 判断是否需要过滤的对象。
         *
         * @param o 对象信息。
         * @return 如果是需要过滤的对象,则返回true;否则返回false。
         */
        @SuppressWarnings("rawtypes")
        public boolean isFilterObject(final Object o) {
            Class<?> clazz = o.getClass();
            if (clazz.isArray()) {
                return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
            } else if (Collection.class.isAssignableFrom(clazz)) {
                Collection collection = (Collection) o;
                for (Object value : collection) {
                    return value instanceof MultipartFile;
                }
            } else if (Map.class.isAssignableFrom(clazz)) {
                Map map = (Map) o;
                for (Object value : map.entrySet()) {
                    Map.Entry entry = (Map.Entry) value;
                    return entry.getValue() instanceof MultipartFile;
                }
            }
            return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
                || o instanceof BindingResult;
        }
    }
    
    
  3. 使用自定义注解@Log

    	@PostMapping("test2")
        @Log(title = "测试自定义日志post")
        public Object test1(@RequestBody Map map) {
            return new HashMap<String,Object>(){
                {
                    put("name", "张三");
                    put("age", 18);
                    put("sex", "男");
                }
            };
        }
    
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
文档内容 一、 Spring介绍 1 1.1、SpringBoot简介 1 1.2、系统要求: 1 1.3、SpringBoot和SpringMVC区别 1 1.4、SpringBoot和SpringCloud区别 2 1.5常见错误 2 二、快速入门 2 2.1、创建一个Maven工程 2 2.2、pom文件引入依赖 3 2.3、编写HelloWorld服务 3 2.4、@RestController 4 2.5、@EnableAutoConfiguration 4 2.6 SpringApplication.run(HelloController.class, args); 4 2.7、SpringBoot启动方式1 4 2.8、SpringBoot启动方式2 4 2.9、SpringBoot启动方式3 5 三、 Web开发 5 3.1、静态资源访问 5 3.2、渲染Web页面 5 3.3、使用Freemarker模板引擎渲染web视图 6 3.3.1、pom文件引入: 6 3.3.2、后台代码 6 3.3.3、前台代码 6 3.3.4、Freemarker其他用法 7 3.3.5、Freemarker配置 8 3.4、使用JSP渲染Web视图 8 3.4.1、pom文件引入以下依赖 8 3.4.2、在application.properties创建以下配置 9 3.4.3、后台代码 9 3.5、全局捕获异常 10 四、 数据访问 10 4.1、springboot整合使用JdbcTemplate 10 4.2、springboot整合使用mybatis 12 4.3、springboot整合使用springjpa 18 4.4、springboot整合多数据源 19 五、 事物管理 25 5.1.1SpringBoot整合事物管理 25 5.1.2SpringBoot分布式事物管理 25 六、 日志管理 30 6.1使用log4j记录日志 30 6.2使用AOP统一处理Web请求日志 32 6.3Spring Boot集成lombok让代码更简洁 33 七、 缓存支持 35 7.1注解配置与EhCache使用 35 7.2使用Redis集成缓存 37 八、 热部署 37 8.1 什么是热部署 37 8.2 项目演示案例 37 8.3 热部署原理 37 8.4 Devtools依赖 38 8.5 Devtools原理 38 九、 监控管理 38 Actuator监控应用 38 Maven依赖 38 YML配置 39 Actuator访问路径 40 Admin-UI分布式微服务监控中心 40 Admin-UI-Server 40 Admin-UI-Client 41 十、 性能优化 43 组件自动扫描带来的问题 43 将Servlet容器变成Undertow 44 SpringBoot JVM参数调优 44 十一、 2.0版本新特性 45 以Java 8 为基准 45 内嵌容器包结构调整 45 Servlet-specific 的server properties调整 45 Actuator 默认映射 46 Spring Loaded不再支持 46 支持Quartz Scheduler 46 OAuth 2.0 支持 46 支持Spring WebFlux 46 版本要求 46 十二、 其他内容 47 12.1、使用@Scheduled创建定时任务 47 12.2、使用@Async实现异步调用 47 12.3、自定义参数 49 12.4、多环境配置 50 12.5、修改端口号 50 12.6、SpringBoot yml 使用 50 12.7、SpringBoot整合拦截器 51 12.8、发布打包 52
Spring Boot 基础教程(基于1.3.x-1.5.x) 快速入门 chapter1:基本项目构建(可作为工程脚手架),引入web模块,完成一个简单的RESTful API 使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程 工程配置 chapter2-1-1:配置文件详解:自定义属性、随机数、多环境配置等 chapter2-1-2:2.0 新特性(一):配置绑定全解析 chapter2-2-1:2.0 新特性(二):新增事件ApplicationStartedEvent Web开发 chapter3-1-1:构建一个较为复杂的RESTful API以及单元测试 chapter3-1-2:使用Thymeleaf模板引擎渲染web视图 chapter3-1-3:使用Freemarker模板引擎渲染web视图 chapter3-1-4:使用Velocity模板引擎渲染web视图 chapter3-1-5:使用Swagger2构建RESTful API chapter3-1-6:统一异常处理 chapter3-1-7:使用Java 8中LocalDate等时间日期类的问题解决 chapter3-1-8:扩展XML请求和响应的支持 数据访问 chapter3-2-1:使用JdbcTemplate chapter3-2-2:使用Spring-data-jpa简化数据访问层(推荐) chapter3-2-3:多数据源配置(一):JdbcTemplate chapter3-2-4:多数据源配置(二):Spring-data-jpa chapter3-2-5:使用NoSQL数据库(一):Redis chapter3-2-6:使用NoSQL数据库(二):MongoDB chapter3-2-7:整合MyBatis chapter3-2-8:MyBatis注解配置详解 chapter3-2-9:使用Flyway来管理数据库版本 chapter3-2-10:使用LDAP来统一管理用户信息 chapter3-2-11:Spring Boot中增强对MongoDB的配置(连接池等) 事务管理 chapter3-3-1:使用事务管理 chapter3-3-2:[分布式事务(未完成)] 其他内容 chapter4-1-1:使用@Scheduled创建定时任务 chapter4-1-2:使用@Async实现异步调用 chapter4-1-3:使用@Async实现异步调用:自定义线程池 chapter4-1-4:使用@Async实现异步调用:资源优雅关闭 chapter4-1-5:使用@Async实现异步调用:使用Future以及定义超时 日志管理 chapter4-2-1:默认日志的配置 chapter4-2-2:使用log4j记录日志 chapter4-2-3:对log4j进行多环境不同日志级别的控制 chapter4-2-4:使用AOP统一处理Web请求日志 chapter4-2-5:使用log4j记录日志到MongoDB chapter4-2-6:Spring Boot 1.5.x新特性:动态修改日志级别] 安全管理 chapter4-3-1:使用Spring Security chapter4-3-2:[使用Spring Session(未完成)] 缓存支持 chapter4-4-1:注解配置与EhCache使用 chapter4-4-2:使用Redis做集中式缓存 邮件发送 chapter4-5-1:实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件 消息服务 chapter5-1-1:[JMS(未完成)] chapter5-2-1:Spring Boot中使用RabbitMQ 其他功能 chapter6-1-1:使用Spring StateMachine框架实现状态机 Spring Boot Actuator监控端点小结 在传统Spring应用中使用spring-boot-actuator模块提供监控端点 Spring Boot应用的后台运行配置 Spring Boot自定义Banner Dubbo进行服务治理 chapter9-2-1:Spring Boot中使用Dubbo进行服务治理 chapter9-2-2:Spring Boot与Dubbo中管理服务依赖
springboot学习资料 一、 Spring介绍 1 1.1、SpringBoot简介 1 1.2、系统要求: 1 二、快速入门 1 2.1、创建一个Maven工程 1 2.2、pom文件引入依赖 2 2.3、编写HelloWorld服务 2 2.4、@RestController 3 2.5、@EnableAutoConfiguration 3 2.6 SpringApplication.run(HelloController.class, args); 3 @SpringbootApplication 3 2.7、SpringBoot启动方式1 4 2.8、SpringBoot启动方式2 4 三、 Web开发 5 3.1、静态资源访问 5 3.2、全局捕获异常 5 3.3、渲染Web页面 6 3.4、使用Freemarker模板引擎渲染web视图 6 3.4.1、pom文件引入: 6 3.4.2、后台代码 6 3.4.3、前台代码 7 3.4.4、Freemarker其他用法 7 3.4.5、Freemarker配置 8 3.5、使用JSP渲染Web视图 8 3.5.1、pom文件引入以下依赖 8 3.5.2、在application.properties创建以下配置 9 3.5.3、后台代码 9 四、 数据访问 9 4.1、springboot整合使用JdbcTemplate 9 4.2、springboot整合使用mybatis 9 4.3、springboot整合使用springjpa 9 4.4、springboot整合多数据源 9 五、 事物管理 9 5.1.1springboot整合事物管理 9 5.1.2SpringBoot分布式事物管理 9 六、 日志管理 9 6.1使用log4j记录日志 9 6.2使用AOP统一处理Web请求日志 9 七、 缓存支持 9 7.1注解配置与EhCache使用 9 使用Redis做集中式缓存 9 八、 其他内容 9 8.1、使用@Scheduled创建定时任务 9 8.2、使用@Async实现异步调用 9 8.3、自定义参数 9 8.4、多环境配置 9 8.5、修改端口号 9 8.6、SpringBoot yml 使用 9 8.7、发布打包 9

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值