动态代理实现超时和降级

之前使用

实现postProcessBeforeInstantiation 接口的方式来生成bean,并且把advisor织入到指定的方法,但是却导致aop的日志没有打印出来。

原因是返回了bean,因为返回了bean就不会执行

PostProcessorsAfterInitialization,而aop的实现又恰恰是实现了这个接口。所以换成实现
postProcessAfterInitialization接口就可以了

 

修改后的代码

 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (!bean.getClass().getName().contains("rose.sal")) {
            return bean;
        }
        if (bean.getClass().isInterface()) {
            return bean;
        }
        Boolean hasTimeOutAnno = false;
        for (Method method : bean.getClass().getMethods()) {
            if (method.getAnnotation(TimeOut.class) != null) {
                hasTimeOutAnno = true;
                break;
            }
        }

        if (!hasTimeOutAnno) {
            return bean;
        }
        ProxyFactoryBean pfb = new ProxyFactoryBean();
        pfb.setTarget(bean);
        pfb.setAutodetectInterfaces(false);

        pfb.addAdvice((MethodInterceptor) invocation -> {
            TimeOut timeOut = AnnotationUtils.findAnnotation(invocation.getMethod(), TimeOut.class);
            if (timeOut != null) {
                RpcContext context = RpcContext.getContext();
                FutureTask<Object> futureTask = new FutureTask<>(new TimeOutTask(context, invocation));
                TimeOutProxy.threadPoolExecutor.submit(futureTask);
                Object ret;
                try {
                    long exceedTime = timeOut.time();
                    ret = futureTask.get(exceedTime, TimeUnit.MILLISECONDS);
                } catch (TimeoutException e) {
                    futureTask.cancel(true);
                    // 其他异常返回系统错误
                    log.error("TimeOUT error.Method name is {}", invocation.getMethod().getName(), e);
                    Method method = null;
                    try {
                        method = invocation.getMethod().getDeclaringClass().getMethod("fallback",
                                Exception.class, String.class);
                    } catch (NoSuchMethodException except) {
                        // do nothing
                    }
                    if (method != null) {
                        return method.invoke(bean, e, invocation.getMethod().getName());
                    }
                    throw e;
                } catch (Exception ex) {
                    log.error("invoke error.Method name is {}", invocation.getMethod().getName(), ex);
                    Method method = bean.getClass().getMethod("fallback", Exception.class);
                    if (method != null) {
                        return method.invoke(bean, ex, invocation.getMethod().getName());
                    }
                    throw ex;
                }
                return ret;
            } else {
                return invocation.proceed();
            }
        });
        return pfb.getObject();
    }

 

修改前的代码:

 public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (!beanClass.getCanonicalName().contains("rose.sal")) {
            return null;
        }
        if (beanClass.isInterface()) {
            return null;
        }
        Boolean hasTimeOutAnno = false;
        for (Method method : beanClass.getMethods()) {
            if (method.getAnnotation(TimeOut.class) != null) {
                hasTimeOutAnno = true;
                break;
            }
        }
        if (hasTimeOutAnno == false) {
            return null;
        }
        ProxyFactoryBean pfb = new ProxyFactoryBean();
        Object targetBean = this.postProcess(BeanUtils.instantiateClass(beanClass));
        pfb.setTarget(targetBean);
        pfb.setAutodetectInterfaces(false);

        pfb.addAdvice((MethodInterceptor) invocation -> {
            TimeOut timeOut = AnnotationUtils.findAnnotation(invocation.getMethod(), TimeOut.class);
            if (timeOut != null) {
                RpcContext context = RpcContext.getContext();
                FutureTask<Object> futureTask = new FutureTask<>(new TimeOutTask(context, invocation));
                TimeOutProxy.threadPoolExecutor.submit(futureTask);
                Object ret;
                try {
                    long exceedTime = timeOut.time();
                    ret = futureTask.get(exceedTime, TimeUnit.MILLISECONDS);
                } catch (TimeoutException e) {
                    futureTask.cancel(true);
                    // 其他异常返回系统错误
                    log.error("TimeOUT error.Method name is {}", invocation.getMethod().getName(), e);
                    Method method = null;
                    try {
                        method = invocation.getMethod().getDeclaringClass().getMethod("fallback",
                                Exception.class, String.class);
                    } catch (NoSuchMethodException except) {
                        // do nothing
                    }
                    if (method != null) {
                        return method.invoke(targetBean, e, invocation.getMethod().getName());
                    }
                    throw e;
                } catch (Exception ex) {
                    log.error("invoke error.Method name is {}", invocation.getMethod().getName(), ex);
                    Method method = beanClass.getMethod("fallback", Exception.class);
                    if (method != null) {
                        return method.invoke(targetBean, ex, invocation.getMethod().getName());
                    }
                    throw ex;
                }
                return ret;
            } else {
                return invocation.proceed();
            }
        });
        return pfb.getObject();
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值