public class ProxyGeneratorAdapter
extends org.objectweb.asm.ClassVisitor
implements org.objectweb.asm.Opcodes
abstract class Foo { abstract void bar(); abstract void baz(); } def dyn = [bar: { println 'hello' }, baz: { println 'world'}] as Foowill 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.AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_MANDATED, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASM4, ASM5, ASTORE, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DMUL, DNEG, DOUBLE, DREM, DRETURN, DSTORE, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F_APPEND, F_CHOP, F_FULL, F_NEW, F_SAME, F_SAME1, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAT, FMUL, FNEG, FREM, FRETURN, FSTORE, FSUB, GETFIELD, GETSTATIC, GOTO, H_GETFIELD, H_GETSTATIC, H_INVOKEINTERFACE, H_INVOKESPECIAL, H_INVOKESTATIC, H_INVOKEVIRTUAL, H_NEWINVOKESPECIAL, H_PUTFIELD, H_PUTSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, IMUL, INEG, INSTANCEOF, INTEGER, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISUB, IUSHR, IXOR, JSR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDIV, LLOAD, LMUL, LNEG, LONG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, NULL, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8
Constructor and Description |
---|
ProxyGeneratorAdapter(java.util.Map<java.lang.Object,java.lang.Object> closureMap,
java.lang.Class superClass,
java.lang.Class[] interfaces,
java.lang.ClassLoader proxyLoader,
boolean emptyBody,
java.lang.Class delegateClass)
Construct a proxy generator.
|
Modifier and Type | Method and Description |
---|---|
GroovyObject |
delegatingProxy(java.lang.Object delegate,
java.util.Map<java.lang.Object,java.lang.Object> map,
java.lang.Object... constructorArgs) |
static Closure |
ensureClosure(java.lang.Object o)
Ensures that the provided object is wrapped into a closure if it's not
a closure.
|
protected org.objectweb.asm.MethodVisitor |
makeDelegateCall(java.lang.String name,
java.lang.String desc,
java.lang.String signature,
java.lang.String[] exceptions,
int accessFlags)
Generate a call to the delegate object.
|
protected org.objectweb.asm.MethodVisitor |
makeDelegateToClosureCall(java.lang.String name,
java.lang.String desc,
java.lang.String signature,
java.lang.String[] exceptions,
int accessFlags) |
GroovyObject |
proxy(java.util.Map<java.lang.Object,java.lang.Object> map,
java.lang.Object... constructorArgs) |
void |
visit(int version,
int access,
java.lang.String name,
java.lang.String signature,
java.lang.String superName,
java.lang.String[] interfaces)
Visits the header of the class.
|
org.objectweb.asm.MethodVisitor |
visitMethod(int access,
java.lang.String name,
java.lang.String desc,
java.lang.String signature,
java.lang.String[] exceptions)
Visits a method of the class.
|
public ProxyGeneratorAdapter(java.util.Map<java.lang.Object,java.lang.Object> closureMap, java.lang.Class superClass, java.lang.Class[] interfaces, java.lang.ClassLoader proxyLoader, boolean emptyBody, java.lang.Class delegateClass)
closureMap
- the delegates implementationssuperClass
- corresponding to the superclass class visitorinterfaces
- extra interfaces the proxy should implementproxyLoader
- the class loader which should be used to load the generated proxydelegateClass
- if not null, generate a delegate field with the corresponding classemptyBody
- if set to true, the unimplemented abstract methods will receive an empty body instead of
throwing an UnsupportedOperationException
.public void visit(int version, int access, java.lang.String name, java.lang.String signature, java.lang.String superName, java.lang.String[] interfaces)
org.objectweb.asm.ClassVisitor
visit
in class org.objectweb.asm.ClassVisitor
version
- the class version.access
- the class's access flags (see Opcodes
). This parameter
also indicates if the class is deprecated.name
- the internal name of the class (see
getInternalName
).signature
- 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.superName
- the internal of name of the super class (see
getInternalName
). For
interfaces, the super class is Object
. May be
null, but only for the Object
class.interfaces
- the internal names of the class's interfaces (see
getInternalName
). May be
null.public org.objectweb.asm.MethodVisitor visitMethod(int access, java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions)
org.objectweb.asm.ClassVisitor
MethodVisitor
instance (or null) each time it is called,
i.e., it should not return a previously returned visitor.visitMethod
in class org.objectweb.asm.ClassVisitor
access
- the method's access flags (see Opcodes
). This
parameter also indicates if the method is synthetic and/or
deprecated.name
- the method's name.desc
- the method's descriptor (see Type
).signature
- the method's signature. May be null if the method
parameters, return type and exceptions do not use generic
types.exceptions
- the internal names of the method's exception classes (see
getInternalName
). May be
null.protected org.objectweb.asm.MethodVisitor makeDelegateCall(java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions, int accessFlags)
protected org.objectweb.asm.MethodVisitor makeDelegateToClosureCall(java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions, int accessFlags)
public GroovyObject proxy(java.util.Map<java.lang.Object,java.lang.Object> map, java.lang.Object... constructorArgs)
public GroovyObject delegatingProxy(java.lang.Object delegate, java.util.Map<java.lang.Object,java.lang.Object> map, java.lang.Object... constructorArgs)
public static Closure ensureClosure(java.lang.Object o)