JDK动态代理

Proxy

/** parameter types of a proxy class constructor */
 private static final Class<?>[] constructorParams = { InvocationHandler.class };

/**
 \* a cache of proxy classes
 */
 private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
   proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

newProxyInstance

public static Object newProxyInstance(ClassLoader loader,
                    Class<?>[] interfaces,
                    InvocationHandler h)
   throws IllegalArgumentException
 {

final Class<?>[] intfs = interfaces.clone();

/*
 \* Look up or generate the designated proxy class.
 */
 Class<?> cl = getProxyClass0(loader, intfs);//main

final Constructor<?> cons = cl.getConstructor(constructorParams);
 final InvocationHandler ih = h;

return cons.newInstance(new Object[]{h});
/**
 \* Generate a proxy class. Must call the checkProxyAccess method
 \* to perform permission checks before calling this.
 */
 private static Class<?> getProxyClass0(ClassLoader loader,
                    Class<?>... interfaces) {
   if (interfaces.length > 65535) {
     throw new IllegalArgumentException("interface limit exceeded");
   }

   // If the proxy class defined by the given loader implementing
   // the given interfaces exists, this will simply return the cached copy;
   // otherwise, it will create the proxy class via the ProxyClassFactory
   return proxyClassCache.get(loader, interfaces);
 }
/**
 \* A factory function that generates, defines and returns the proxy class given
 \* the ClassLoader and array of interfaces.
 */
 private static final class ProxyClassFactory
   implements BiFunction<ClassLoader, Class<?>[], Class<?>>
 {

@Override
 public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

return generateProxy(proxyName, interfaces, loader, methodsArray, exceptionsArray);
private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
                       ClassLoader loader, Method[] methods,
                       Class<?>[][] exceptions);

// END Android-changed: How proxies are generated.

Proxy_generateProxy

art/runtime/native/java_lang_reflect_Proxy.cc

static JNINativeMethod gMethods[] = {
  FAST_NATIVE_METHOD(Proxy, generateProxy, "(Ljava/lang/String;[Ljava/lang/Class;Ljava/lang/ClassLoader;[Ljava/lang/reflect/Method;[[Ljava/lang/Class;)Ljava/lang/Class;"),
};
static jclass Proxy_generateProxy(JNIEnv* env, jclass, jstring name, jobjectArray interfaces,
                                  jobject loader, jobjectArray methods, jobjectArray throws) {
  ScopedFastNativeObjectAccess soa(env);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  return soa.AddLocalReference<jclass>(class_linker->CreateProxyClass(
      soa, name, interfaces, loader, methods, throws));
}

ClassLinker::CreateProxyClass

art/runtime/class_linker.cc

mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& soa,
                                             jstring name,
                                             jobjectArray interfaces,
                                             jobject loader,
                                             jobjectArray methods,
                                             jobjectArray throws) {
  
  Thread* self = soa.Self();
  StackHandleScope<10> hs(self);
  MutableHandle<mirror::Class> temp_klass(hs.NewHandle(
  AllocClass(self, GetClassRoot(kJavaLangClass), sizeof(mirror::Class))));
  
  
  temp_klass->SetObjectSize(sizeof(mirror::Proxy));
  // Set the class access flags incl. VerificationAttempted, so we do not try to set the flag on
  // the methods.
  temp_klass->SetAccessFlags(kAccClassIsProxy | kAccPublic | kAccFinal | kAccVerificationAttempted);
  temp_klass->SetClassLoader(soa.Decode<mirror::ClassLoader>(loader));
  DCHECK_EQ(temp_klass->GetPrimitiveType(), Primitive::kPrimNot);
  temp_klass->SetName(soa.Decode<mirror::String>(name));
  temp_klass->SetDexCache(GetClassRoot(kJavaLangReflectProxy)->GetDexCache());
  // Object has an empty iftable, copy it for that reason.
  temp_klass->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
  mirror::Class::SetStatus(temp_klass, ClassStatus::kIdx, self);
  
  //insert into classtable
  ObjPtr<mirror::Class> existing = InsertClass(descriptor.c_str(), temp_klass.Get(), hash);
  
  LengthPrefixedArray<ArtField>* sfields = AllocArtFieldArray(self, allocator, num_fields);
  temp_klass->SetSFieldsPtr(sfields);
  // 1. Create a static field 'interfaces' that holds the _declared_ interfaces implemented by
  // our proxy, so Class.getInterfaces doesn't return the flattened set.
  ArtField& interfaces_sfield = sfields->At(0);
  interfaces_sfield.SetDexFieldIndex(0);
  interfaces_sfield.SetDeclaringClass(temp_klass.Get());
  interfaces_sfield.SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
  // 2. Create a static field 'throws' that holds exceptions thrown by our methods.
  ArtField& throws_sfield = sfields->At(1);
  throws_sfield.SetDexFieldIndex(1);
  throws_sfield.SetDeclaringClass(temp_klass.Get());
  throws_sfield.SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
  
   // They have as many virtual methods as the array
  auto h_methods = hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Method>>(methods));
  // Create the methods array.
  LengthPrefixedArray<ArtMethod>* proxy_class_methods = AllocArtMethodArray(
        self, allocator, num_direct_methods + num_virtual_methods);
  // Create the single direct method.
  CreateProxyConstructor(temp_klass, temp_klass->GetDirectMethodUnchecked(0, image_pointer_size_));
  // Create virtual method using specified prototypes.
  // TODO These should really use the iterators.
  for (size_t i = 0; i < num_virtual_methods; ++i) {
    auto* virtual_method = temp_klass->GetVirtualMethodUnchecked(i, image_pointer_size_);
    auto* prototype = h_methods->Get(i)->GetArtMethod();
    CreateProxyMethod(temp_klass, prototype, virtual_method);
    DCHECK(virtual_method->GetDeclaringClass() != nullptr);
    DCHECK(prototype->GetDeclaringClass() != nullptr);
  }
  // The super class is java.lang.reflect.Proxy
  temp_klass->SetSuperClass(GetClassRoot(kJavaLangReflectProxy));
  // Now effectively in the loaded state.
  mirror::Class::SetStatus(temp_klass, ClassStatus::kLoaded, self);
  
  LinkClass(self, descriptor.c_str(), temp_klass, h_interfaces, &klass)
    
  Runtime::Current()->GetRuntimeCallbacks()->ClassPrepare(temp_klass, klass);
  
  SubtypeCheck<ObjPtr<mirror::Class>>::EnsureInitialized(klass.Get());
    // Lock on klass is released. Lock new class object.
    ObjectLock<mirror::Class> initialization_lock(self, klass);
    mirror::Class::SetStatus(klass, ClassStatus::kInitialized, self);
  
  return klass.Get();
}

ClassStatus

enum class ClassStatus : uint8_t {
  kNotReady = 0,  // Zero-initialized Class object starts in this state.
  kRetired = 1,  // Retired, should not be used. Use the newly cloned one instead.
  kErrorResolved = 2,
  kErrorUnresolved = 3,
  kIdx = 4,  // Loaded, DEX idx in super_class_type_idx_ and interfaces_type_idx_.
  kLoaded = 5,  // DEX idx values resolved.
  kResolving = 6,  // Just cloned from temporary class object.
  kResolved = 7,  // Part of linking.
  kVerifying = 8,  // In the process of being verified.
  kRetryVerificationAtRuntime = 9,  // Compile time verification failed, retry at runtime.
  kVerifyingAtRuntime = 10,  // Retrying verification at runtime.
  kVerified = 11,  // Logically part of linking; done pre-init.
  kSuperclassValidated = 12,  // Superclass validation part of init done.
  kInitializing = 13,  // Class init in progress.
  kInitialized = 14,  // Ready to go.
  kLast = kInitialized
};