1.注解
package com.jun.webpro.common.aspect; import java.lang.annotation.*; /** * 用于出现问题后,方法切换 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Documented public @interface FailOver { /** * 故障出现,切换到新的方法 */ String value() default ""; }
2.实现
package com.jun.webpro.common.aspect.impl; import com.jun.webpro.common.aspect.FailOver; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.util.Objects; @Aspect @Component @Slf4j public class FailOverInterceptor implements ApplicationContextAware { private ApplicationContext applicationContext; /** * 引入spring上下文 */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } // 切点 @Pointcut("@annotation(com.jun.webpro.common.aspect.FailOver)") public void failoverinterceptor() { } @Around(value = "failoverinterceptor()") public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Exception { try { Object proceed = proceedingJoinPoint.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); Signature signature = proceedingJoinPoint.getSignature(); // 新的方法获取到 MethodSignature methodSignature = (MethodSignature) signature; Method targetMethod = methodSignature.getMethod(); // 获取注解上的desc String description = targetMethod.getAnnotation(FailOver.class).value(); // 获取对应的参数的类型 Class[] parameterTypes = targetMethod.getParameterTypes(); // 获取对应的参数 Object[] args = proceedingJoinPoint.getArgs(); String paramClass = description.substring(0, description.lastIndexOf(".")); String methodName = description.substring(description.lastIndexOf(".") + 1); // 生成类和方法 Class clazz = Class.forName(paramClass); Object bean = applicationContext.getBean(clazz); Method method = clazz.getMethod(methodName, parameterTypes); // 动态的生成字节码,加载到jvn中运行 method.invoke(bean, args); } return null; } }