1.自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
int value() default 5;
}
2.被注解的类-方法
@Slf4j
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@MyAnnotation(value = 67)
@GetMapping("/ff")
@ResponseBody
public Object ff() {
throw new RuntimeException("2222222dd");
}
@MyAnnotation()
@GetMapping("/gg")
@ResponseBody
public Object ff(com.example.demo.log.User user1) {
throw new RuntimeException("2222222dd");
}
}
3.aop注解处理类
@Aspect
@Component
public class RepairAspect {
@Pointcut(value = "@annotation(com.example.demo.config.MyAnnotation)")
public void pointCutOfTestAfterThrowing(){
System.out.println("------------------------------");
};
/**
* 异常通知
* @param ex 注意 要和throwing的值一致
*/
@AfterThrowing(pointcut = "pointCutOfTestAfterThrowing()", throwing = "ex")
public void logTestAfterThrowing1(JoinPoint joinPoint, Exception ex) throws ClassNotFoundException {
System.out.println(getControllerMethodInfo(joinPoint));
}
/**
* 前置通知
*/
@Before(value = "pointCutOfTestAfterThrowing()")
public void userBefore(JoinPoint joinPoint) throws ClassNotFoundException {
System.out.println(getControllerMethodInfo(joinPoint));
}
/**
* 获取注解参数值-第一种方式
* @param joinPoint
* @throws NoSuchMethodException
*/
private int getValue(JoinPoint joinPoint) {
return ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(MyAnnotation.class).value();
}
/**
* 获取注解参数值-第二种方式
* @param joinPoint
* @throws NoSuchMethodException
*/
private int getValue(JoinPoint joinPoint) throws NoSuchMethodException {
Class<?> clazz = joinPoint.getTarget().getClass();
String methodName = joinPoint.getSignature().getName();
Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
Method method = clazz.getMethod(methodName, parameterTypes);
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
return annotation.value();
}
/**
* 获取注解参数值-第三种方式 (获取包括被注解类的所有)
* @return 注解参数
*/
public Integer getControllerMethodInfo(JoinPoint joinPoint) throws ClassNotFoundException {
//获取触发目标类名
String targetName = joinPoint.getTarget().getClass().getName();
//获取触发方法名
String methodName = joinPoint.getSignature().getName();
//获取触发相关参数
Object[] arguments = joinPoint.getArgs();
//生成类对象
Class targetClass = Class.forName(targetName);
//获取触发类中的所有方法
Method[] methods = targetClass.getMethods();
//遍历所有方法
a:for (Method m : methods) {
//寻找被指定注解的方法
if (m.isAnnotationPresent(MyAnnotation.class)) {
//判断方法名字是否相同
if(m.getName().equals(methodName)) {
Class[] clazzs = m.getParameterTypes();
//比较方法中参数个数是否相同,原因是方法可以重载
if (clazzs.length == arguments.length) {
//循环方法的参数
for (int i = 0; i < arguments.length; i++) {
//比较参数类型是否相同(防止对象名一样属于不同包 或 参数列表数量 相同 但是参数类型不同)
if(arguments[i].getClass().getName() != clazzs[i].getName()){
continue a ;
}
}
//返回要获取的注解的参数值
return m.getAnnotation(MyAnnotation.class).value();
}
}
}
}
return null;
}
}