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;
}
}