美文网首页
注解记录->Component、Aspect

注解记录->Component、Aspect

作者: 云鲸鱼rain | 来源:发表于2019-02-14 11:39 被阅读0次

    1、Component
    放在类上的注解,将此类实例化到spring容器当中。可以在别的service这样的类中能够注入该类并使用。

    @Component
    public class ProjectUrlConfig {
    
    }
    
    @Service
    public class PushMessageImpl implements PushMessageService {
    
        @Autowired
        private ProjectUrlConfig projectUrlConfig;
    
    }
    

    2、Aspect
    切面。
    AOP这里需要注意的是:
    (1) execution表达式
    (2) Spring AOP不进入before和业务方法,却进入其他切面的问题。原因:没写环绕通知进程方法
    (3) 单个方法被多个Aspect方法拦截的顺序问题
    (4) Spring AOP不进入afterThrowing方法问题。原因:around方法没抛出异常

    以下代码基于spring boot

    @Aspect
    @Component
    public class GameAspect {
    
        private final static Logger logger = LoggerFactory.getLogger(GameAspect.class);
    
        @Pointcut("execution(public * com.tianci.controller.GameController.*(..))")
        public void game() {}
    
        @Before("game()")
        public void doBefore(JoinPoint joinPoint) {
            logger.info("before");
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = servletRequestAttributes != null ? servletRequestAttributes.getRequest() : null;
            //url
            logger.info("url={}", request != null ? request.getRequestURL() : null);
            //method
            logger.info("method={}", request != null ? request.getMethod() : null);
            //ip
            logger.info("ip={}", request != null ? request.getRemoteAddr() : null);
            //类方法
            logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
            //参数
            logger.info("args={}", joinPoint.getArgs());
        }
    
        @After("game()")
        public void doAfter() {
            logger.info("after");
        }
    
        @AfterReturning("game()")
        public void doAfterReturning() {
            logger.info("afterReturning");
        }
    
        @AfterThrowing("game()")
        public void doAfterThrowing() {
            logger.info("afterThrowing");
        }
    
        @Around("game()")
        public void around(JoinPoint joinPoint) {
            logger.info("around前");
            ProceedingJoinPoint proceedingJoinPoint = (ProceedingJoinPoint)joinPoint;
            try {
                Object obejct = proceedingJoinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            logger.info("around后");
        }
    
    }
    
    package com.tianci.controller;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * Create by tianci
     * 2019/2/13 14:34
     */
    @RestController
    public class GameController {
    
        private final static Logger logger = LoggerFactory.getLogger(GameController.class);
    
        @GetMapping("/doGame")
        public void doGame() {
            logger.info("sing...");
        }
    
    }
    

    运行结果:

    : around前
    : before
    //////////////////////////////////参数部分
    : url=http://localhost:8080/doGame
    : method=GET
    : ip=0:0:0:0:0:0:0:1
    : class_method=com.tianci.controller.GameController.doGame
    : args={}
    ////////////////////////////////////////
    : sing...
    : around后
    : after
    : afterReturning
    

    以上是正确运行的结果,接下来演示抛出异常的运行结果。
    这时候就有问题了。
    将测试类改成

    package com.tianci.controller;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * Create by tianci
     * 2019/2/13 14:34
     */
    @RestController
    public class GameController {
    
        private final static Logger logger = LoggerFactory.getLogger(GameController.class);
    
        @GetMapping("/doGame")
        public void doGame() {
            throw new IllegalArgumentException("异常");
            //logger.info("sing");
        }
    
    }
    

    发现并没有执行 afterThrowing() 方法。
    开始找问题,这个问题网上查了好久,但都没有解决,但是却有成功执行afterThrowing()的例子,一步一步的查找异同。发现了问题所在。
    原因在于:
    切面的around方法中把异常catch掉了,应该在方法上 throws Throwable
    于是将around方法改为(当然注释掉around方法也可以解决这个问题):

    @Around("game()")
        public void around(JoinPoint joinPoint) throws Throwable {
            logger.info("around前");
            ProceedingJoinPoint proceedingJoinPoint = (ProceedingJoinPoint)joinPoint;
             Object obejct = proceedingJoinPoint.proceed();
            logger.info("around后");
        }
    

    说下单个方法被多个Aspect方法拦截的顺序问题,order注解可以解决,值越小,优先级越高

    @Order(1)
    @Aspect
    @Component
    public class GameAspect {}
    

    相关文章

      网友评论

          本文标题:注解记录->Component、Aspect

          本文链接:https://www.haomeiwen.com/subject/ggfnqqtx.html