zoukankan      html  css  js  c++  java
  • Spring boot Aop 示例

    需要的依赖

    <!-- 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>
    

    ASPECT

    
    
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.sun.org.apache.xpath.internal.operations.String;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    
    @Aspect
    @Component
    public class LogAspect {
    
        private final static Logger logger = LoggerFactory.getLogger(LogAspect.class);
    
        // * 表示所有返回类型  ..表示包及子包 * 表示所有类 .* 指类所有方法 (..) 代表所有参数
        @Pointcut("execution(public * com.gailguo.demo.controller..*.*(..))")
        public void controllerMethod() {
        }
    
    
        @Before("controllerMethod()")
        public void LogRequestInfo(JoinPoint joinPoint) throws Exception {
    
            logger.info("请求结果: Before  " );
    
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
    
            StringBuffer requestLog = new StringBuffer();
            requestLog.append("请求信息:")
                    .append("URL = {" + request.getRequestURI() + "},	")
                    .append("HTTP_METHOD = {" + request.getMethod() + "},	")
                    .append("IP = {" + request.getRemoteAddr() + "},	")
                    .append("CLASS_METHOD = {" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + "},	");
    
            if(joinPoint.getArgs().length == 0) {
                requestLog.append("ARGS = {} ");
            } else {
                requestLog.append("ARGS = " + new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)
                        .writeValueAsString(joinPoint.getArgs()[0]) + "");
            }
    
            logger.info(requestLog.toString());
        }
    
    
        @AfterReturning( pointcut = "controllerMethod()")
        public void logResultVOInfo() throws Exception {
            logger.info("请求结果: after return " );
        }
    
        @After("controllerMethod()")
        public void logAfter(JoinPoint joinPoint){
            logger.info("请求结果: after  " );
        }
    
    
        @AfterThrowing("controllerMethod()")
        public void logException(JoinPoint joinPoint){
            logger.info("请求结果: after AfterThrowing " );
        }
    
        @Around("controllerMethod()")
        public Object logAround(ProceedingJoinPoint joinPoint) throws  Throwable{
    
            Object s=null;
            if(joinPoint.getArgs().length>0){
                 s=joinPoint.getArgs()[0];
                logger.info("Around: 打印传参 "+s.toString() );
            }
            logger.info("Around  1");
            Object obj=joinPoint.proceed(new Object[]{"sss+"+s.toString()});
            logger.info("Around 2");
            return  obj;
    
        }
    
    }
    

    一个简单的controller

    @RestController
    @RequestMapping(path = "/aop")
    public class MyController {
    
    
        @RequestMapping(path ="/test")
        public String   getTest(@RequestParam("id")String id){
            return  "111"+id;
        }
    }
    

      

    Pointcut 执行表达式的格式

    参考 

    https://elim.iteye.com/blog/2395255
    

      

    1: execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) 
    除了返回类型模式(上面代码片断中的ret-type-pattern),

    名字模式和参数模式以外,所有的部分都是可选的。

    返回类型模式决定了方法的返回类型必须依次匹配一个连接点。

    你会使用的最频繁的返回类型模式是 * ,它代表了匹配任意的返回类型。

    一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。

    你可以使用 * 通配符作为所有或者部分命名模式。

    参数模式稍微有点复杂:() 匹配了一个不接受任何参数的方法, 而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)。

    模式 (*) 匹配了一个接受一个任何类型的参数的方法。

    模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型。

     
    一些常见切入点表达式的例子

    execution(public * *(..))  任意公共方法的执行;
    execution(* set*(..))  任何一个以“set”开始的方法的执行; 
    execution(* com.xyz.service.AccountService.*(..))   AccountService接口的任意方法的执行;
    execution(* com.xyz.service.*.*(..))  定义在service包里的任意方法的执行;
    execution(* com.xyz.service..*.*(..))  定义在service包或者子包里的任意方法的执行;

    2. within 是用来指定类型的,指定类型中的所有方法将被拦截

    3. bean 

       bean用于匹配当调用的是指定的Spring的某个bean的方法时。

        “bean(abc)”匹配Spring Bean容器中id或name为abc的bean的方法调用。

        “bean(user*)”匹配所有id或name为以user开头的bean的方法调用。

    @Component
    public class TestInfo {
    
        Logger logger= LoggerFactory.getLogger(TestInfo.class);
    
        public void  testInfo(){
            logger.info("这里是testInfo 方法");
        }
    }
    

      

      @Pointcut("bean(testInfo)")
        public void controllerMethod2(){
    
        }
    

      

     @Around("controllerMethod2()")
        public Object logAround2(ProceedingJoinPoint joinPoint) throws  Throwable{
    
    
            logger.info("Around  testInfo 1");
            Object obj=joinPoint.proceed();
            logger.info("Around  testInfo 2");
            return  obj;
    
        }
    

      

      @Autowired
        TestInfo info;
    
        @RequestMapping(path ="/test")
        public String   getTest(@RequestParam("id")String id){
            info.testInfo();
            return  "111"+id;
        }
    

      

  • 相关阅读:
    案例分析
    202103226-1 编程作业
    阅读任务
    准备工作
    结对作业
    案列分析
    202103226-1 编程作业
    《构建之法》有感
    准备工作
    案例分析作业
  • 原文地址:https://www.cnblogs.com/galibujianbusana/p/11163858.html
Copyright © 2011-2022 走看看