[非官方]苍穹平台@注解支持探究(二)注解解析和方法存储原创
金蝶云社区-shiro
shiro
5人赞赏了该文章 539次浏览 未经作者许可,禁止转载编辑于2022年09月08日 09:23:18

上一P我们介绍了我们的注解体系,下面说一下我们的实现方法。

下面我们讲解一下如何获得那些那些函数,这里涉及一些反射的知识,我简要介绍细节不赘述。

public class AnnotationSupport {
    //方法缓存
    private static final Map<Class<? extends AbstractFormAnnotationPlugin>, Map<String, Method>> methodCache = new ConcurrentHashMap<>();



虽然反射出来的Class对象本身包含类的方法,但是反射是一个相当耗时的操作,所以这里提供了一个静态的方法缓存。







    //工厂方法获取helper
    public static AnnotationHelper start(AbstractFormAnnotationPlugin obj) {
        Class<? extends AbstractFormAnnotationPlugin> clazz = obj.getClass();
        //缓存
        if (methodCache.containsKey(clazz)) {
            Map<String, Method> methods = methodCache.get(clazz);
            return new AnnotationHelper(methods, obj);
        } else {
            //获取方法列表
            Method[] methods = clazz.getDeclaredMethods();
            //用于构造helper的方法集合,标识为key,方法为value
            Map<String, Method> methodMap = new HashMap<>();
            for (Method method : methods) {
                //方法有且只有一个参数EventObject或空参会被缓存
                Parameter[] parameters = method.getParameters();
                if (parameters.length == 1) {
                    Class<?> type = parameters[0].getType();
                    if (!EventObject.class.isAssignableFrom(type)) {
                        continue;
                    }
                } else if (parameters.length == 0) {
                    //pass
                } else {
                    continue;
                }
上面的代码很简单我们首先反射出了类的所有方法,然后对他们进行过滤。
有且仅有一个EventObject类型及其子类的参数或者空参的方法,复合了FormEvent注解才会被缓存起来。
AnnotationUtils.findAnnotation(method, FormEvent.class);这个类在org.springframework.core.annotation包下,有兴趣可以阅读源码,如果想用spring是开源的可以复制过来。






                //如果注解复合了FormEvent就会被放入helper的map中
                FormEvent annotation = AnnotationUtils.findAnnotation(method, FormEvent.class);
                if (annotation == null) {
                    continue;
                }
                String name = method.getName();
                if (methodMap.containsKey(name)) {
                    System.out.println("函数" + name + "重载,已采用重载后的函数");
                }
                methodMap.put(name, method);

            }
            methodCache.put(clazz, methodMap);
            return new AnnotationHelper(methodMap, obj);
        }


    }


赞 5