注解转发接口请求

2020-05-25  本文已影响0人  風暴之灵

重构需要转发请求,使用切面实现,不需要转发时直接注掉相关注解即可
注解写在需要转发的Controller接口上,beanName为转发的类名,methodName为转发的函数名

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Forward {

    String beanName() default "";

    String methodName() default "";

    int[] paramsIndex() default 0;

    Class[] paramsType() default String.class;
}

切面类

@Slf4j
@Aspect
@Component
public class ForwardAspect {

    @Autowired
    private SpringContextUtil springContextUtil;

    @Pointcut("@annotation(com.xes.stone.clazz.rest.forward.Forward)")
    public void pointcut(){


    }

    @Around(value = "pointcut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        Method method = this.getSpecificmethod(pjp);
        Forward forward = method.getAnnotation(Forward.class);
        if (forward != null) {
            Object object = springContextUtil.getBean(forward.beanName());
            Method forwardMethod;
            Object[] obj = pjp.getArgs();
            Object result;
            if(obj!=null&&obj.length>0){
                forwardMethod=object.getClass().getMethod(forward.methodName(), forward.paramsType());

                int[] index=forward.paramsIndex();
                Object[] objParams=new Object[index.length];
                for(int i=0;i<index.length;i++){
                    objParams[i]=obj[index[i]];
                }
                result=forwardMethod.invoke(object,objParams);
            }else{
                forwardMethod=object.getClass().getMethod(forward.methodName());
                result=forwardMethod.invoke(object);
            }
            return result;
        }
        log.warn("注意未走转发逻辑:{}",method.getName());
        return pjp.proceed();
    }

    private Method getSpecificmethod(ProceedingJoinPoint pjp) {
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method method = methodSignature.getMethod();
        Class<?> targetClass = AopProxyUtils.ultimateTargetClass(pjp.getTarget());
        if (targetClass == null && pjp.getTarget() != null) {
            targetClass = pjp.getTarget().getClass();
        }
        Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
        specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
        return specificMethod;
    }

}

提供applicationContext.getBean的工具类

@Component
public class SpringContextUtil implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public Object getBean(String name) {
        return applicationContext.getBean(name);
    }
}
上一篇下一篇

猜你喜欢

热点阅读