CGLib FastClass

作者: 毛小力 | 来源:发表于2019-01-17 19:47 被阅读0次

    1. 举例

    • 委托类
    public class DelegateClass {
    
        public DelegateClass() {
        }
    
        public DelegateClass(String string) {
        }
    
        public boolean add(String string, int i) {
            System.out.println("This is add method: " + string + ", " + i);
            return true;
        }
    
        public void update() {
            System.out.println("This is update method");
        }
    }
    
    • 测试
    public static void main(String[] args) throws Exception {
        // 保留生成的FastClass类文件
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\Temp\\CGLib\\FastClass");
    
        Class delegateClass = DelegateClass.class;
    
        // Java Reflect
    
        // 反射构造类
        Constructor delegateConstructor = delegateClass.getConstructor(String.class);
        // 创建委托类实例
        DelegateClass delegateInstance = (DelegateClass) delegateConstructor.newInstance("Tom");
    
        // 反射方法类
        Method addMethod = delegateClass.getMethod("add", String.class, int.class);
        // 调用方法
        addMethod.invoke(delegateInstance, "Tom", 30);
    
        Method updateMethod = delegateClass.getMethod("update");
        updateMethod.invoke(delegateInstance);
    
        // CGLib FastClass
    
        // FastClass动态子类实例
        FastClass fastClass = FastClass.create(DelegateClass.class);
    
        // 创建委托类实例
        DelegateClass fastInstance = (DelegateClass) fastClass.newInstance(
            new Class[] {String.class}, new Object[]{"Jack"});
    
        // 调用委托类方法
        fastClass.invoke("add", new Class[]{ String.class, int.class}, fastInstance, 
            new Object[]{ "Jack", 25});
    
        fastClass.invoke("update", new Class[]{}, fastInstance, new Object[]{});
    }
    

    2. FastClass

    FastClass不使用反射类(Constructor或Method)来调用委托类方法,而是动态生成一个新的类(继承FastClass),向类中写入委托类实例直接调用方法的语句,用模板方式解决Java语法不支持问题,同时改善Java反射性能。

    动态类为委托类方法调用语句建立索引,使用者根据方法签名(方法名+参数类型)得到索引值,再通过索引值进入相应的方法调用语句,得到调用结果。

    • FastClass
    public abstract class FastClass{
    
        // 委托类
        private Class type;
        
        // 子类访问构造方法
        protected FastClass() {}
        protected FastClass(Class type) {
            this.type = type;
        }
        
        // 创建动态FastClass子类
        public static FastClass create(Class type) {
            // Generator:子类生成器,继承AbstractClassGenerator
            Generator gen = new Generator();
            gen.setType(type);
            gen.setClassLoader(type.getClassLoader());
            return gen.create();
        }
        
        /**
         * 调用委托类方法
         *
         * @param name 方法名
         * @param parameterTypes 方法参数类型
         * @param obj 委托类实例
         * @param args 方法参数对象
         */
        public Object invoke(String name, Class[] parameterTypes, Object obj, Object[] args) {
            return invoke(getIndex(name, parameterTypes), obj, args);
        }
        
        /**
         * 根据方法描述符找到方法索引
         *
         * @param name 方法名
         * @param parameterTypes 方法参数类型
         */
        public abstract int getIndex(String name, Class[] parameterTypes);
        
        
        /**
         * 根据方法索引调用委托类方法
         *
         * @param index 方法索引
         * @param obj 委托类实例
         * @param args 方法参数对象
         */
        public abstract Object invoke(int index, Object obj, Object[] args);
        
        /**
         * 调用委托类构造方法
         * 
         * @param parameterTypes 构造方法参数类型
         * @param args 构造方法参数对象
         */
        public Object newInstance(Class[] parameterTypes, Object[] args) throws {
            return newInstance(getIndex(parameterTypes), args);
        }
        
        /**
         * 根据构造方法描述符(参数类型)找到构造方法索引
         *
         * @param parameterTypes 构造方法参数类型
         */
        public abstract int getIndex(Class[] parameterTypes);
        
        /**
         * 根据构造方法索引调用委托类构造方法
         *
         * @param index 构造方法索引
         * @param args 构造方法参数对象
         */
        public abstract Object newInstance(int index, Object[] args);
        
    }
    
    • 动态子类
    public class DelegateClass$$FastClassByCGLIB$$4af5b667 extends FastClass {
        
        /**
         * 动态子类构造方法
         */
        public DelegateClass$$FastClassByCGLIB$$4af5b667(Class delegateClass) {
            super(delegateClass);
        }
    
        /**
         * 根据方法签名得到方法索引
         *
         * @param name 方法名
         * @param parameterTypes 方法参数类型
         */
        public int getIndex(String methodName, Class[] parameterTypes) {
            switch(methodName.hashCode()) {
                
                // 委托类方法add索引:0
                case 96417:
                    if (methodName.equals("add")) {
                        switch(parameterTypes.length) {
                            case 2:
                                if (parameterTypes[0].getName().equals("java.lang.String") && 
                                    parameterTypes[1].getName().equals("int")) {
                                    return 0;
                                }
                        }
                    }
                    break;
                
                // 委托类方法update索引:1
                case -838846263:
                    if (methodName.equals("update")) {
                        switch(parameterTypes.length) {
                            case 0:
                                return 1;
                        }
                    }
                    break;
                    
                // Object方法equals索引:2
                case -1295482945:
                    if (methodName.equals("equals")) {
                        switch(parameterTypes.length) {
                            case 1:
                                if (parameterTypes[0].getName().equals("java.lang.Object")) {
                                    return 2;
                                }
                        }
                    }
                    break;
                
                // Object方法toString索引:3
                case -1776922004:
                    if (methodName.equals("toString")) {
                        switch(parameterTypes.length) {
                            case 0: return 3;
                        }
                    }
                    break;
                
                // Object方法hashCode索引:4
                case 147696667:
                    if (methodName.equals("hashCode")) {
                        switch(parameterTypes.length) {
                            case 0:
                                return 4;
                        }
                    }
            }
    
            return -1;
        }
        
        /**
         * 根据方法索引调用委托类方法
         *
         * @param methodIndex 方法索引
         * @param delegateInstance 委托类实例
         * @param parameterValues 方法参数对象
         */
        public Object invoke(int methodIndex, Object delegateInstance, Object[] parameterValues) {
            DelegateClass instance = (DelegateClass) delegateInstance;
            int index = methodIndex;
            try {
                switch(index) {
                    case 0:
                        // 委托类实例直接调用方法语句
                        return new Boolean(instance.add((String)parameterValues[0], 
                                ((Number)parameterValues[1]).intValue()));
                    case 1:
                        instance.update();
                        return null;
                    case 2:
                        return new Boolean(instance.equals(parameterValues[0]));
                    case 3:
                        return instance.toString();
                    case 4:
                        return new Integer(instance.hashCode());
                }
            } catch (Throwable t) {
                throw new InvocationTargetException(t);
            }
    
            throw new IllegalArgumentException("Cannot find matching method/constructor");
        }
    
        /**
         * 根据构造方法描述符(参数类型)找到构造方法索引
         *
         * @param parameterTypes 构造方法参数类型
         */
        public int getIndex(Class[] parameterTypes) {
            switch(parameterTypes.length) {
                // 无参构造方法索引:0
                case 0:
                    return 0;
                
                // 有参构造方法索引:1
                case 1:
                    if (parameterTypes[0].getName().equals("java.lang.String")) {
                        return 1;
                    }
                default:
                    return -1;
            }
        }
        
        /**
         * 根据构造方法索引调用委托类构造方法
         *
         * @param methodIndex 构造方法索引
         * @param parameterValues 构造方法参数对象
         */
        public Object newInstance(int methodIndex, Object[] parameterValues) {
            // 创建委托类实例
            DelegateClass newInstance = new DelegateClass;
            DelegateClass newObject = newInstance;
            int index = methodIndex;
            try {
                switch(index) {
                    // 调用构造方法(<init>)
                    case 0:
                        newObject.<init>();
                        return newInstance;
                    case 1:
                        newObject.<init>((String)parameterValues[0]);
                        return newInstance;
                }
            } catch (Throwable t) {
                throw new InvocationTargetException(t);
            }
    
            throw new IllegalArgumentException("Cannot find matching method/constructor");
        }
    
        public int getMaxIndex() {
            return 4;
        }
    }
    

    相关文章

      网友评论

        本文标题:CGLib FastClass

        本文链接:https://www.haomeiwen.com/subject/evnidqtx.html