Annotation统计某些方法被调用次数

1.所需Jar
cglib.jar 动态代理
asm.jar cglib依赖于asm
2.看代码
2.1 注解定义
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCaseAnnotation {
    int id() default 0;
}
2.2 要统计的方法
public class AnnotationTestTarget {

    @UseCaseAnnotation(id = 1)
    public void test1() {
    }

    @UseCaseAnnotation(id = 2)
    public void test2() {
    }
}
2.3 代理类(代理AnnotationTestTarget)
public class AnnotationProxy implements MethodInterceptor {

    private T target;

    public T proxy(T target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return (T) enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = methodProxy.invoke(target, objects);
        UseCaseAnnotationHandler.countMethodInvokeNumber(method);
        return result;
    }
}
2.4 注解处理类 (根据方法id 统计次数)
public class UseCaseAnnotationHandler {

    private static Map methodInvokeCount = new HashMap<>();

    public static void countMethodInvokeNumber(Method method) {
        UseCaseAnnotation annotation = method.getAnnotation(UseCaseAnnotation.class);
        if (Objects.nonNull(annotation)) {
            int id = annotation.id();
            Integer orDefault = methodInvokeCount.getOrDefault(id, 0);
            methodInvokeCount.put(id, orDefault + 1);
        }
    }

    public static Map getMethodInvokeCount() {
        return methodInvokeCount;
    }
}
2.5 工厂类生成代理对象
public class BeanFactory {

    public static  T getBeanByClass(Class clz) {
        try {
            T instance = clz.newInstance();
            return new AnnotationProxy().proxy(instance);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
3.测试类
@Test
public void testAnnotation() throws Exception {
    AnnotationTestTarget target = BeanFactory.getBeanByClass(AnnotationTestTarget.class);
    if (Objects.isNull(target)) {
        throw new Exception("target为空");
    }
    for (int i = 0; i < 6; i ++) {
        target.test1();
    }
    for (int i = 0; i < 2; i ++) {
        target.test2();
    }
    Map methodInvokeCount = UseCaseAnnotationHandler.getMethodInvokeCount();
    System.out.println(methodInvokeCount);
}

你可能感兴趣的:(Annotation统计某些方法被调用次数)