zoukankan      html  css  js  c++  java
  • spring-data-aop 进行切面编程日志记录

    spring-data-aop

    用途主要是记录日志和做切面增强
    项目demo: https://github.com/woyaochengweidaniu/spring

    项目启动直接访问接口即可在控制台看到效果--------------------

    依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.lcm</groupId>
        <artifactId>aop</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>aop</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
                <version>2.1.6.RELEASE</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>4.5.11</version>
            </dependency>
            <!-- 解析 UserAgent 信息 -->
            <dependency>
                <groupId>eu.bitwalker</groupId>
                <artifactId>UserAgentUtils</artifactId>
                <version>1.21</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.8</version>
                <scope>provided</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.1.6.RELEASE</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    
    

    切点可以用注解 也可以用表达式

    1创建注解
    package com.lcm.aop.annon;
    
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    /**
     * 创建注解
     * RetentionPolicy.RUNTIME   生命周期   运行时
     *ElementType.METHOD   标记在什么地方    方法上
     *
     * @author lcm
     * @date created in 2019 7 11
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface OpLog {
    
        String operation() default "";
    
        String target() default "";
    }
    
    

    创建切面

    package com.lcm.aop.aspectj;
    
    
    import com.lcm.aop.annon.OpLog;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    /**
     * <p>进行注解式切面编程</p>
     * @author lcm
     * @date created in 2019 7 11
     *
     */
    @Slf4j
    @Aspect
    @Component
    public class OpreationLog {
    
    
        /**
         *<p>只需要在方法上添加注解即可</p>
         */
        @Pointcut("@annotation(com.lcm.aop.annon.OpLog)")
        public void operation(){}
    
    
        /**
         * <p>带有log的注解并且切入点是operation  返回的是Object</p>
         * @param joinPoint
         * @param opLog
         * @param o
         */
        @AfterReturning(value = "operation()&&@annotation(opLog)",returning = "o")
        public void AfterReturning(JoinPoint joinPoint, OpLog opLog, Object o){
    
            log.info("操作类型:{}",opLog.operation());
            log.info("操作目标:{}",opLog.target());
            log.info("返回对象:{}",o);
    
            Object[] args = joinPoint.getArgs();
            for (Object object:args) {
    
                log.info("参数:{}",object);
    
            }
    
    
        }
    }
    
    

    创建service

    package com.lcm.aop.service;
    
    import com.lcm.aop.annon.OpLog;
    import org.springframework.stereotype.Service;
    
    /**
     * @author lcm
     */
    @Service
    public class TestSerivce {
    
    
        @OpLog(operation = "删除",target = "订单")
        public Object delete(String id){
            System.out.println(id);
            return "success";
    
        }
    
    }
    
    

    创建controller

    package com.lcm.aop.api;
    
    import com.lcm.aop.service.TestSerivce;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author lcm
     */
    @RestController
    public class ApiController {
    
        @Autowired
        private TestSerivce serivce;
    
        /**
         * 测试方法
         *
         * @param id 测试参数
         */
        @GetMapping("/test2")
        public Object test2(String  id) {
            Object delete = serivce.delete(id);
            return delete;
        }
    
    }
    
    

    2使用表达式进行切点切入

    package com.lcm.aop.aspectj;
    
    import cn.hutool.json.JSONUtil;
    import eu.bitwalker.useragentutils.UserAgent;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.Map;
    import java.util.Objects;
    
    /**
     * @author lcm
     * <P>记录切面日志</P>
     * @date created in 2019 7 11
     * @author lcm
     * @deprecated 切面不仅可以做日志 还可以做方法增强
     *
     */
    @Aspect
    @Component
    @Slf4j
    public class AopLog {
        private static final String START_TIME = "request-start";
    
        /**
         * 切入点
         */
        @Pointcut("execution(public * com.lcm.aop.controller.*Controller.*(..))")
        public void log() {
    
        }
    
        /**
         * 前置操作
         *
         * @param point 切入点
         */
        @Before("log()")
        public void beforeLog(JoinPoint point) {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    
            HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
    
            log.info("【请求 URL】:{}", request.getRequestURL());
            log.info("【请求 IP】:{}", request.getRemoteAddr());
            log.info("【请求类名】:{},【请求方法名】:{}", point.getSignature().getDeclaringTypeName(), point.getSignature().getName());
    
            Map<String, String[]> parameterMap = request.getParameterMap();
            log.info("【请求参数】:{},", JSONUtil.toJsonStr(parameterMap));
            Long start = System.currentTimeMillis();
            request.setAttribute(START_TIME, start);
        }
    
        /**
         * 环绕操作
         *
         * @param point 切入点
         * @return 原方法返回值
         * @throws Throwable 异常信息
         */
        @Around("log()")
        public Object aroundLog(ProceedingJoinPoint point) throws Throwable {
            Object result = point.proceed();
            log.info("【返回值】:{}", JSONUtil.toJsonStr(result));
            return result;
        }
    
        /**
         * 后置操作
         */
        @AfterReturning("log()")
        public void afterReturning() {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
    
            Long start = (Long) request.getAttribute(START_TIME);
            Long end = System.currentTimeMillis();
            log.info("【请求耗时】:{}毫秒", end - start);
    
            String header = request.getHeader("User-Agent");
            UserAgent userAgent = UserAgent.parseUserAgentString(header);
            log.info("【浏览器类型】:{},【操作系统】:{},【原始User-Agent】:{}", userAgent.getBrowser().toString(), userAgent.getOperatingSystem().toString(), header);
        }
    }
    
    
    

    创建controller

    package com.lcm.aop.controller;
    
    import cn.hutool.core.lang.Dict;
    import cn.hutool.core.util.StrUtil;
    import com.lcm.aop.service.TestSerivce;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * <p>
     * 测试 Controller
     * </p>
     *
     * @package: com.xkcoding.log.aop.controller
     * @description: 测试 Controller
     * @author: yangkai.shen
     * @date: Created in 2018/10/1 10:10 PM
     * @copyright: Copyright (c) 2018
     * @version: V1.0
     * @modified: yangkai.shen
     */
    @RestController
    public class TestController {
    	@Autowired
    	private TestSerivce serivce;
    
    	/**
    	 * 测试方法
    	 *
    	 * @param who 测试参数
    	 * @return {@link Dict}
    	 */
    	@GetMapping("/test1")
    	public Dict test1(String who) {
    		return Dict.create().set("who", StrUtil.isBlank(who) ? "me" : who);
    	}
    
    
    
    }
    
    
    

    启动项目然后访问端口 如果端口号指定了,就按照指定的端口号访问

    浏览器输入:http://localhost:8081/test1
    浏览器输入:http://localhost:8081/test2

  • 相关阅读:
    2020.10.23 19级training 补题报告
    2020.10.17 天梯赛练习 补题报告
    2020.10.16 19级training 补题报告
    2020.10.9 19级training 补题报告
    2020.10.10 天梯赛练习 补题报告
    2020.10.3 天梯赛练习 补题报告
    2020.10.2 19级training 补题报告
    第十届山东省ACM省赛复现补题报告
    VVDI Key Tool Plus Adds VW Passat 2015 Key via OBD
    Xhorse VVDI Prog Software V5.0.3 Adds Many MCUs
  • 原文地址:https://www.cnblogs.com/java-hardly-road/p/11170751.html
Copyright © 2011-2022 走看看