重构需要转发请求,使用切面实现,不需要转发时直接注掉相关注解即可
注解写在需要转发的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);
}
}