java Java中的缓存反射访问(来自Spring Framework代码库)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java Java中的缓存反射访问(来自Spring Framework代码库)相关的知识,希望对你有一定的参考价值。

/**
 * Heavily inspired by Spring's {@link org.springframework.util.ReflectionUtils}
 * but preferring not to mess with it, as per its own documentation.
 */

void clearCache() { declaredMethodsCache.clear(); }

///////////////////////////////////////
//
//  Spring code base (more or less)
//
///////////////////////////////////////

private Method findMethod(Class<?> clazz, String name) { return findMethod(clazz, name, new Class<?>[0]); }

private Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
    required(clazz);
    required(name);

    Class<?> searchType = clazz;
    while (searchType != null) {
        Method[] methods = (searchType.isInterface() ? searchType.getMethods() : getDeclaredMethods(searchType));
        for (Method method : methods) {
            if (name.equals(method.getName()) &&
                (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) {
                return method;
            }
        }
        searchType = searchType.getSuperclass();
    }

    return null;
}

private Method[] getDeclaredMethods(Class<?> clazz) {
    required(clazz);

    Method[] result = declaredMethodsCache.get(clazz);
    if (result == null) {
        try {

            Method[] declaredMethods = clazz.getDeclaredMethods();
            List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz);
            if (defaultMethods != null) {

                result = new Method[declaredMethods.length + defaultMethods.size()];
                arraycopy(declaredMethods, 0, result, 0, declaredMethods.length);

                int index = declaredMethods.length;
                for (Method defaultMethod : defaultMethods) {
                    result[index] = defaultMethod;
                    index++;
                }

            } else {
                result = declaredMethods;
            }
            declaredMethodsCache.put(clazz, (result.length == 0 ? NO_METHODS : result));

        } catch (Throwable ex) {
            LOG.error("??? Failed to introspect Class [" + clazz.getName() + "] from ClassLoader [" +
                      clazz.getClassLoader() + "]", ex);
        }
    }
    return result;
}

private static List<Method> findConcreteMethodsOnInterfaces(Class<?> clazz) {
    List<Method> result = null;
    for (Class<?> ifc : clazz.getInterfaces()) {
        for (Method ifcMethod : ifc.getMethods()) {
            if (!isAbstract(ifcMethod.getModifiers())) {
                if (result == null) {
                    result = new LinkedList<>();
                }
                result.add(ifcMethod);
            }
        }
    }
    return result;
}

/** Avoiding <code>static</code> fields to rely on Garbage Collection releasing unneeded memory */
private final Map<Class<?>, Method[]> declaredMethodsCache = new ConcurrentReferenceHashMap<>(256);

private static final Method[] NO_METHODS = {};

以上是关于java Java中的缓存反射访问(来自Spring Framework代码库)的主要内容,如果未能解决你的问题,请参考以下文章

如何利用缓存机制实现JAVA类反射性能提升30倍

如何利用缓存机制实现JAVA类反射性能提升30倍

如何限制开发人员使用反射访问Java中的私有方法和构造函数?

使用 Java 反射访问测试用例中的受保护方法

Hibernate Session缓存

java中的反射机制-----转载