深入理解Java中的反射机制和使用原理!详细解析invoke方法的执行和使用 (4)

首先用Reflection.quickCheckMemberAccess(clazz, modifiers) 方法检查方法是否为public
1.1 如果是public方法的话,就跳过本步
1.2 如果不是public方法的话,就用Reflection.getCallerClass()方法获取调用这个方法的Class对象,这是一个native方法

@CallerSensitive public static native Class<?> getCallerClass(); ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 在OpenJDK中可以找到getCallerClass方法的JNI入口-Reflection.c JNIEXPORT jclass JNICALL Java_sun_reflect_Reflection_getCallerClass__ (JNIEnv *env, jclass unused) { return JVM_GetCallerClass(env, JVM_CALLER_DEPTH); } --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - JVM_GetCallerClass的源码位于jvm.cpp中 VM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env, int depth)) JVMWrapper("JVM_GetCallerClass"); // Pre-JDK 8 and early builds of JDK 8 don't have a CallerSensitive annotation; or // sun.reflect.Reflection.getCallerClass with a depth parameter is provided // temporarily for existing code to use until a replacement API is defined. if (SystemDictionary::reflect_CallerSensitive_klass() == NULL || depth != JVM_CALLER_DEPTH) { Klass* k = thread->security_get_caller_class(depth); return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror()); } // Getting the class of the caller frame. // // The call stack at this point looks something like this: // // [0] [ @CallerSensitive public sun.reflect.Reflection.getCallerClass ] // [1] [ @CallerSensitive API.method ] // [.] [ (skipped intermediate frames) ] // [n] [ caller ] vframeStream vfst(thread); // Cf. LibraryCallKit::inline_native_Reflection_getCallerClass for (int n = 0; !vfst.at_end(); vfst.security_next(), n++) { Method* m = vfst.method(); assert(m != NULL, "sanity"); switch (n) { case 0: // This must only be called from Reflection.getCallerClass if (m->intrinsic_id() != vmIntrinsics::_getCallerClass) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetCallerClass must only be called from Reflection.getCallerClass"); } // fall-through case 1: // Frame 0 and 1 must be caller sensitive. if (!m->caller_sensitive()) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), err_msg("CallerSensitive annotation expected at frame %d", n)); } break; default: if (!m->is_ignored_by_security_stack_walk()) { // We have reached the desired frame; return the holder class. return (jclass) JNIHandles::make_local(env, m->method_holder()->java_mirror()); } break; } } return NULL; JVM_END

获取Class对象caller后使用checkAccess方法进行一次快速的权限校验 ,checkAccess方法实现如下:

volatile Object securityCheckCache; void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers) throws IllegalAccessException { if(caller == clazz){ // 快速校验 return; // 权限通过校验 } Object cache = securityCheckCache; // 读取volatile Class<?> targetClass = clazz; if (obj != null && Modifier.isProtected(modifiers) && ((targetClass = obj.getClass()) != clazz)) { // 必须匹配caller,targetClass中的一个 if (cache instanceof Class[]) { Class<?>[] cache2 = (Class<?>[]) cache; if (cache2[1] == targetClass && cache[0] == caller) { return; // 校验通过 } } } else if (cache == caller) { return; // 校验通过 } slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass); }

首先先执行一次快速校验,一旦Class正确则权限检查通过;如果未通过,则创建一个缓存,中间再进行检查

如果上面所有的权限检查都未通过,将会执行更详细的检查:

void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers, Class<?> targetClass) throws IllegalAccessException { Refelection.ensureMemberAccess(caller, clazz, obj, modifiers); // 如果成功,就更新缓存 Object cache = ((targetClass == clazz) ? caller : new Class<?>[] {caller, targetClass}); securityCheckCache = cache; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydsyj.html