美文网首页
注解记录->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