Spring AOP 无法拦截方法 拦截后获取参数却为空.

起因: 项目重构, 期间要拦截请求加日志, 后期日志处理得到数据. 但是一部分内容是MQ推过来的, 发现推过来的部分拦截不到, 如: send发送内容, this.send(xxx)直接发送, send的日志无法拦截.

解决方案: 使用spring填充的类进行调用, MaapSendController 类内增加MaapSendController 的@Autowired实例, 使用该实例可以被AOP拦截到.

 /**
     * controller实例
     */
    @Autowired
    private MaapSendController maapSendController;

    /**
     * 监听器实例
     */
    @Autowired
    private MQMessageListener listenerConcurrently;

    /**
     * 生产者实例
     */
    @Autowired
    @Qualifier("DefaultMQProducer")
    private DefaultMQProducer DefaultMQProducer;

    /**
     * 初始化mq消费
     */
    @PostConstruct
    public void registryListener(){
//        DisableSSLCertificateCheckUtil.disableChecks();
        listenerConcurrently.addListener((msgs, context) -> {
            for(MessageExt msg : msgs) {
                try {
                    String topic = msg.getTopic();
                    log.info("topic = " + topic);
                    byte[] body = msg.getBody();
                    log.info("body:  " + new String(body));
                    String keys = msg.getKeys();
                    log.info("keys = " + keys);
                    String tags = msg.getTags();
                    log.info("tags = " + tags);
                    String bodyJson = new String(body);
                    Message5gSend bodyObj = JSONUtil.toBean(bodyJson, Message5gSend.class, false);
                    maapSendController.send(bodyObj);
                }catch (Exception e){
                    log.error("消息消费失败: {}", e.getMessage());
                }
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
    }

但是这样拦截的时候发现send的参数在拦截的时候getArgs()是Null, 但是我断点的时候却发现point内的methodInvocation内是有参数内容的, 看MethodInvocationProceedingJoinPoint的源码内的getArgs也是能够从这里存在的位置获取参数的. 于是我尝试把point转换为MethodInvocationProceedingJoinPoint后再次getArgs(), 就特么出来了....看来类型下转后getArgs的实现跟着有变化.

    
    //MethodInvocationProceedingJoinPoint的源码

	@Override
	public Object[] getArgs() {
		if (this.args == null) {
			this.args = this.methodInvocation.getArguments().clone();
		}
		return this.args;
	}
        // 获取请求参数
        // 获取请求参数
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = null;
        Object[] args = null;
        if(attributes != null) {
            request = attributes.getRequest();
            args = point.getArgs();
        }
        if(args == null){
            // 处理直接调用的情况
            if(point instanceof MethodInvocationProceedingJoinPoint){
                MethodInvocationProceedingJoinPoint miPoint = (MethodInvocationProceedingJoinPoint)point;
                log.info(miPoint.getArgs() + "");
                args = miPoint.getArgs();
                // 转换后使用下级类的getArgs()可以获得内容
            }
        }

问题解决, 无法拦截的问题网上有解决方案, 但是无参数的问题完全没发现有相关文章. 找到问题写篇文章做点贡献.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值