abstract class Foo {
abstract void bar();
abstract void baz();
}
def dyn = [bar: { println 'hello' }, baz: { println 'world'}] as Foo
will generate a proxy class which extends class Foo and delegates method calls to the provided closures.
The generated proxy implements the GroovyObject interface.
Additionally, this proxy generator supports delegation to another object. In that case, if a method is defined
both in the closure map and the delegate, the version from the map is preferred. This allows overriding methods
from delegates with ease.
Internally, the proxy generator makes use of ASM to generate bytecode, for improved performance as compared
to the legacy proxy generation mechanism which made use of string templates.
| Modifier and Type | Class and Description |
|---|---|
| private static class | |
| private static class |
| Modifier and Type | Field and Description |
|---|---|
| private final Class | |
| private final Constructor | |
| private static final String | |
| private static final String | |
| private final Class | |
| private final Map | |
| private static final Object[] | |
| private static final Map | |
| private final boolean | |
| private final boolean | |
| private static final Set | |
| private static List | |
| private final boolean | |
| private final Set | |
| private final ProxyGeneratorAdapter. | |
| private static List | |
| private final Set | |
| private static final AtomicLong | |
| private final String | |
| private final Class | |
| private final Set |
| Access | Constructor and Description |
|---|---|
| public | ProxyGeneratorAdapter(final Map<Object, Object>
the delegates implementations closureMap, final Class<?> corresponding to the superclass class visitor superClass, final Class<T>[] extra interfaces the proxy should implement interfaces, final ClassLoader the class loader which should be used to load the generated proxy proxyLoader, final boolean if set to true, the unimplemented abstract methods will receive an empty body instead of
throwing an emptyBody, final Class<?> UnsupportedOperationException.if not null, generate a delegate field with the corresponding class delegateClass)Construct a proxy generator. |
| Modifier and Type | Method and Description |
|---|---|
| private void | |
| private Class | |
| private void | |
| private static Set | |
| private static boolean | containsEquivalentMethod(final Collection<Method> publicAndProtectedMethods, final Method candidate)
|
| private MethodVisitor | createConstructor(final int access, final String name, final String desc, final String signature, final String[] exceptions)
|
| private static Set | createDelegateMethodList(final Class<T> superClass, final Class<T> delegateClass, final Class<T>[] interfaces)
|
| private MethodVisitor | createGetProxyTargetMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions)
|
| private void | createGroovyObjectSupport()
When an object doesn't implement the GroovyObject interface, we generate bytecode for the
|
| private static ProxyGeneratorAdapter. | |
| public GroovyObject | |
| public static Closure | ensureClosure(final Object o)
Ensures that the provided object is wrapped into a closure if it's not a closure. |
| private ProxyGeneratorAdapter. | |
| private static List | |
| private static int | |
| private static int | |
| private static int | |
| private static String | |
| private static boolean | |
| private void | |
| private void | |
| private static boolean | |
| private static boolean | |
| protected MethodVisitor | makeDelegateCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags)
Generate a call to the delegate object. |
| protected MethodVisitor | makeDelegateToClosureCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags)
|
| public GroovyObject | |
| private String | |
| private static int | |
| private static int | |
| private static void | |
| public void | visit(final int
the class version. The minor version is stored in the 16 most significant bits,
and the major version in the 16 least significant bits. version, final int the class's access flags (see access, final String Opcodes). This parameter also indicates if
the class is deprecated Opcodes#ACC_DEPRECATED or a record Opcodes#ACC_RECORD.the internal name of the class (see name, final String Type#getInternalName()).the signature of this class. May be null if the class is not a
generic one, and does not extend or implement generic classes or interfaces. signature, final String the internal of name of the super class (see superName, final String[] Type#getInternalName()).
For interfaces, the super class is Object. May be null, but only for the
Object class.the internal names of the class's interfaces (see interfaces)Type#getInternalName()). May be null.Overrides org. |
| private void | visitClass(final Class<T>
an class for which to generate bytecode clazz)Visit every class/interface this proxy should implement, and generate the appropriate bytecode for delegation if available. |
| public MethodVisitor | visitMethod(final int
the method's access flags (see access, final String Opcodes). This parameter also indicates if
the method is synthetic and/or deprecated.the method's name. name, final String the method's descriptor (see desc, final String Type).the method's signature. May be null if the method parameters,
return type and exceptions do not use generic types. signature, final String[] the internal names of the method's exception classes (see exceptions)Type#getInternalName()). May be null.Overrides org. |
| cachedClass | back to summary |
|---|---|
| private final Class<T> cachedClass | |
| cachedNoArgConstructor | back to summary |
|---|---|
| private final Constructor<T> cachedNoArgConstructor | |
| CLOSURES_MAP_FIELD | back to summary |
|---|---|
| private static final String CLOSURES_MAP_FIELD | |
| DELEGATE_OBJECT_FIELD | back to summary |
|---|---|
| private static final String DELEGATE_OBJECT_FIELD | |
| delegateClass | back to summary |
|---|---|
| private final Class<T> delegateClass | |
| delegatedClosures | back to summary |
|---|---|
| private final Map<String, Boolean> delegatedClosures | |
| EMPTY_ARGS | back to summary |
|---|---|
| private static final Object[] EMPTY_ARGS | |
| EMPTY_DELEGATECLOSURE_MAP | back to summary |
|---|---|
| private static final Map<String, Boolean> EMPTY_DELEGATECLOSURE_MAP | |
| emptyBody | back to summary |
|---|---|
| private final boolean emptyBody | |
| generateDelegateField | back to summary |
|---|---|
| private final boolean generateDelegateField | |
| GROOVYOBJECT_METHOD_NAMES | back to summary |
|---|---|
| private static final Set<String> GROOVYOBJECT_METHOD_NAMES | |
| GROOVYOBJECT_METHODS | back to summary |
|---|---|
| private static List<Method> GROOVYOBJECT_METHODS | |
| hasWildcard | back to summary |
|---|---|
| private final boolean hasWildcard | |
| implClasses | back to summary |
|---|---|
| private final Set<Class<T>> implClasses | |
| innerLoader | back to summary |
|---|---|
| private final ProxyGeneratorAdapter. | |
| OBJECT_METHODS | back to summary |
|---|---|
| private static List<Method> OBJECT_METHODS | |
| objectDelegateMethods | back to summary |
|---|---|
| private final Set<String> objectDelegateMethods | |
| proxyCounter | back to summary |
|---|---|
| private static final AtomicLong proxyCounter | |
| proxyName | back to summary |
|---|---|
| private final String proxyName | |
| superClass | back to summary |
|---|---|
| private final Class<T> superClass | |
| visitedMethods | back to summary |
|---|---|
| private final Set<Object> visitedMethods | |
| ProxyGeneratorAdapter | back to summary |
|---|---|
| public ProxyGeneratorAdapter(final Map<Object, Object> closureMap, final Class<?> superClass, final Class<T>[] interfaces, final ClassLoader proxyLoader, final boolean emptyBody, final Class<?> delegateClass) Construct a proxy generator. This generator is used when we need to create a proxy object for a class or an interface given a map of closures.
| |
| addDelegateFields | back to summary |
|---|---|
| private void addDelegateFields() Creates delegate fields for every closure defined in the map. | |
| adjustSuperClass | back to summary |
|---|---|
| private Class | |
| boxPrimitiveType | back to summary |
|---|---|
| private void boxPrimitiveType(final MethodVisitor mv, final int idx, final Type arg) | |
| collectTraits | back to summary |
|---|---|
| private static Set | |
| containsEquivalentMethod | back to summary |
|---|---|
| private static boolean containsEquivalentMethod(final Collection<Method> publicAndProtectedMethods, final Method candidate) | |
| createConstructor | back to summary |
|---|---|
| private MethodVisitor createConstructor(final int access, final String name, final String desc, final String signature, final String[] exceptions) | |
| createDelegateMethodList | back to summary |
|---|---|
| private static Set | |
| createGetProxyTargetMethod | back to summary |
|---|---|
| private MethodVisitor createGetProxyTargetMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) | |
| createGroovyObjectSupport | back to summary |
|---|---|
| private void createGroovyObjectSupport() When an object doesn't implement the GroovyObject interface, we generate bytecode for the
| |
| createInnerLoader | back to summary |
|---|---|
| private static ProxyGeneratorAdapter. | |
| delegatingProxy | back to summary |
|---|---|
public GroovyObject delegatingProxy(final Object delegate, final Map<Object, Object> map, Object... constructorArgs)
| |
| ensureClosure | back to summary |
|---|---|
| public static Closure Ensures that the provided object is wrapped into a closure if it's not a closure. Do not trust IDEs, this method is used in bytecode.
| |
| findClassLoader | back to summary |
|---|---|
| private ProxyGeneratorAdapter. | |
| getInheritedMethods | back to summary |
|---|---|
| private static List | |
| getLoadInsn | back to summary |
|---|---|
| private static int getLoadInsn(final Type type) | |
| getReturnInsn | back to summary |
|---|---|
| private static int getReturnInsn(final Type type) | |
| getTypeArgsRegisterLength | back to summary |
|---|---|
| private static int getTypeArgsRegisterLength(Type[] args) | |
| getWrappedClassDescriptor | back to summary |
|---|---|
| private static String getWrappedClassDescriptor(final Type type) | |
| hasMatchingParameterTypes | back to summary |
|---|---|
| private static boolean hasMatchingParameterTypes(final Method method, final Method candidate) | |
| initializeDelegateClosure | back to summary |
|---|---|
| private void initializeDelegateClosure(final MethodVisitor mv, final Type[] args) | |
| initializeDelegateObject | back to summary |
|---|---|
| private void initializeDelegateObject(final MethodVisitor mv, final Type[] args) | |
| isImplemented | back to summary |
|---|---|
| private static boolean isImplemented(final Class<T> clazz, final String name, final String desc) | |
| isPrimitive | back to summary |
|---|---|
| private static boolean isPrimitive(final Type type) | |
| makeDelegateCall | back to summary |
|---|---|
| protected MethodVisitor makeDelegateCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) Generate a call to the delegate object. | |
| makeDelegateToClosureCall | back to summary |
|---|---|
| protected MethodVisitor makeDelegateToClosureCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) | |
| proxy | back to summary |
|---|---|
public GroovyObject proxy(final Map<Object, Object> map, Object... constructorArgs)
| |
| proxyName | back to summary |
|---|---|
| private String proxyName() | |
| registerLen | back to summary |
|---|---|
| private static int registerLen(Type[] args) | |
| registerLen | back to summary |
|---|---|
| private static int registerLen(final Type arg) | |
| unwrapResult | back to summary |
|---|---|
| private static void unwrapResult(final MethodVisitor mv, final String desc) | |
| visit | back to summary |
|---|---|
| public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) Overrides org. Doc from org. Visits the header of the class.
| |
| visitClass | back to summary |
|---|---|
| private void visitClass(final Class<T> clazz) Visit every class/interface this proxy should implement, and generate the appropriate bytecode for delegation if available.
| |
| visitMethod | back to summary |
|---|---|
| public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) Overrides org. Doc from org. Visits a method of the class. This method must return a new
| |
| Modifier and Type | Field and Description |
|---|---|
| pack-priv List |
| Access | Constructor and Description |
|---|---|
| protected |
| Modifier and Type | Method and Description |
|---|---|
| public Class | defineClass(final String name, final byte[] data)
Overrides groovy. |
| public Class | loadClass(final String
The binary name of the class name)Overrides groovy. |
| internalClassLoaders | back to summary |
|---|---|
| pack-priv List<ClassLoader> internalClassLoaders | |
| InnerLoader | back to summary |
|---|---|
| protected InnerLoader(final ClassLoader parent, final Class<T>[] interfaces) | |
| defineClass | back to summary |
|---|---|
| public Class Overrides groovy. Doc from groovy. open up the super class define that takes raw bytes
| |
| loadClass | back to summary |
|---|---|
| public Class Overrides groovy. Doc from java. Loads the class with the specified binary name.
This method searches for classes in the same manner as the
| |
| Modifier and Type | Field and Description |
|---|---|
| private static final long | |
| private final V |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public V | call(final Object... args)
Overrides groovy. |
| serialVersionUID | back to summary |
|---|---|
| private static final long serialVersionUID | |
| value | back to summary |
|---|---|
| private final V value | |
| ReturnValueWrappingClosure | back to summary |
|---|---|
| public ReturnValueWrappingClosure(final V returnValue) | |
| call | back to summary |
|---|---|
| public V call(final Object... args) Overrides groovy. Doc from groovy. Invokes the closure with given argument(s), returning any value if applicable.
| |