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

  • 相关阅读:
    接口测试常见bug
    软件测试面试题含答案
    每个测试都该知道的测试用例方法及细节设计
    从“如何测试一个杯子”理解功能、界面、性能、安全测试?
    小白必看:测试人有必要参考的软件测试工作规范
    经验分享:给软件测试人员15个最好的测试管理工具
    DFS路径规划
    Trian(列车调度)
    GAIA
    CSWS_E_ROB深度估计方法
  • 原文地址:https://www.cnblogs.com/java-hardly-road/p/11170751.html
Copyright © 2011-2022 走看看