⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxyfactory.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            String key = (String)it.next();            if (key.startsWith(name))                return false;        }        return true;    }    /**     * Returns true if the method is visible from the class.     *     * @param mod       the modifiers of the method.      */    private static boolean isVisible(int mod, String from, Member meth) {        if ((mod & Modifier.PRIVATE) != 0)            return false;        else if ((mod & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0)            return true;        else {            String p = getPackageName(from);            String q = getPackageName(meth.getDeclaringClass().getName());            if (p == null)                return q == null;            else                return p.equals(q);        }    }    private static String getPackageName(String name) {        int i = name.lastIndexOf('.');        if (i < 0)            return null;        else            return name.substring(0, i);    }    private static HashMap getMethods(Class superClass, Class[] interfaceTypes) {        HashMap hash = new HashMap();        for (int i = 0; i < interfaceTypes.length; i++)            getMethods(hash, interfaceTypes[i]);        getMethods(hash, superClass);        return hash;    }    private static void getMethods(HashMap hash, Class clazz) {        Class[] ifs = clazz.getInterfaces();        for (int i = 0; i < ifs.length; i++)            getMethods(hash, ifs[i]);        Class parent = clazz.getSuperclass();        if (parent != null)            getMethods(hash, parent);        Method[] methods = clazz.getDeclaredMethods();        for (int i = 0; i < methods.length; i++)            if (!Modifier.isPrivate(methods[i].getModifiers())) {                Method m = methods[i];                String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m);                hash.put(key, methods[i]);            }    }    private static String keyToDesc(String key) {        return key.substring(key.indexOf(':') + 1);    }    private static MethodInfo makeConstructor(String thisClassName, Constructor cons,                                              ConstPool cp, Class superClass) {        String desc = RuntimeSupport.makeDescriptor(cons.getParameterTypes(),                                                    Void.TYPE);        MethodInfo minfo = new MethodInfo(cp, "<init>", desc);        minfo.setAccessFlags(Modifier.PUBLIC);      // cons.getModifiers() & ~Modifier.NATIVE        setThrows(minfo, cp, cons.getExceptionTypes());        Bytecode code = new Bytecode(cp, 0, 0);        code.addAload(0);        code.addGetstatic(thisClassName, DEFAULT_INTERCEPTOR, HANDLER_TYPE);        code.addOpcode(Opcode.DUP);        code.addOpcode(Opcode.IFNONNULL);        code.addIndex(7);        code.addOpcode(Opcode.POP);        code.addGetstatic(NULL_INTERCEPTOR_HOLDER, DEFAULT_INTERCEPTOR, HANDLER_TYPE);        code.addPutfield(thisClassName, HANDLER, HANDLER_TYPE);        code.addAload(0);        int s = addLoadParameters(code, cons.getParameterTypes(), 1);        code.addInvokespecial(superClass.getName(), "<init>", desc);        code.addOpcode(Opcode.RETURN);        code.setMaxLocals(s + 1);        minfo.setCodeAttribute(code.toCodeAttribute());        return minfo;    }    private static MethodInfo makeDelegator(Method meth, String desc,                ConstPool cp, Class declClass, String delegatorName) {        MethodInfo delegator = new MethodInfo(cp, delegatorName, desc);        delegator.setAccessFlags(Modifier.FINAL | Modifier.PUBLIC                | (meth.getModifiers() & ~(Modifier.PRIVATE                                           | Modifier.PROTECTED                                           | Modifier.ABSTRACT                                           | Modifier.NATIVE                                           | Modifier.SYNCHRONIZED)));        setThrows(delegator, cp, meth);        Bytecode code = new Bytecode(cp, 0, 0);        code.addAload(0);        int s = addLoadParameters(code, meth.getParameterTypes(), 1);        code.addInvokespecial(declClass.getName(), meth.getName(), desc);        addReturn(code, meth.getReturnType());        code.setMaxLocals(++s);        delegator.setCodeAttribute(code.toCodeAttribute());        return delegator;    }    /**     * @param delegatorName     null if the original method is abstract.     */    private static MethodInfo makeForwarder(String thisClassName,                    Method meth, String desc, ConstPool cp,                    Class declClass, String delegatorName, int index) {        MethodInfo forwarder = new MethodInfo(cp, meth.getName(), desc);        forwarder.setAccessFlags(Modifier.FINAL                    | (meth.getModifiers() & ~(Modifier.ABSTRACT                                               | Modifier.NATIVE                                               | Modifier.SYNCHRONIZED)));        setThrows(forwarder, cp, meth);        int args = Descriptor.paramSize(desc);        Bytecode code = new Bytecode(cp, 0, args + 2);        /*         * if (methods[index * 2] == null) {         *   methods[index * 2]         *     = RuntimeSupport.findMethod(this, <overridden name>, <desc>);         *   methods[index * 2 + 1]         *     = RuntimeSupport.findMethod(this, <delegator name>, <desc>);         *     or = null // the original method is abstract.         * }         * return ($r)handler.invoke(this, methods[index * 2],         *                methods[index * 2 + 1], $args);         */        int origIndex = index * 2;        int delIndex = index * 2 + 1;        int arrayVar = args + 1;        code.addGetstatic(thisClassName, HOLDER, HOLDER_TYPE);        code.addAstore(arrayVar);        code.addAload(arrayVar);        code.addIconst(origIndex);        code.addOpcode(Opcode.AALOAD);        code.addOpcode(Opcode.IFNONNULL);        int pc = code.currentPc();        code.addIndex(0);        callFindMethod(code, "findSuperMethod", arrayVar, origIndex, meth.getName(), desc);        callFindMethod(code, "findMethod", arrayVar, delIndex, delegatorName, desc);        code.write16bit(pc, code.currentPc() - pc + 1);        code.addAload(0);        code.addGetfield(thisClassName, HANDLER, HANDLER_TYPE);        code.addAload(0);        code.addAload(arrayVar);        code.addIconst(origIndex);        code.addOpcode(Opcode.AALOAD);        code.addAload(arrayVar);        code.addIconst(delIndex);        code.addOpcode(Opcode.AALOAD);        makeParameterList(code, meth.getParameterTypes());        code.addInvokeinterface(MethodHandler.class.getName(), "invoke",            "(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;",            5);        Class retType = meth.getReturnType();        addUnwrapper(code, retType);        addReturn(code, retType);        forwarder.setCodeAttribute(code.toCodeAttribute());        return forwarder;    }    private static void setThrows(MethodInfo minfo, ConstPool cp, Method orig) {        Class[] exceptions = orig.getExceptionTypes();        setThrows(minfo, cp, exceptions);    }    private static void setThrows(MethodInfo minfo, ConstPool cp,                                  Class[] exceptions) {        if (exceptions.length == 0)            return;        String[] list = new String[exceptions.length];        for (int i = 0; i < exceptions.length; i++)            list[i] = exceptions[i].getName();        ExceptionsAttribute ea = new ExceptionsAttribute(cp);        ea.setExceptions(list);        minfo.setExceptionsAttribute(ea);    }    private static int addLoadParameters(Bytecode code, Class[] params,                                         int offset) {        int stacksize = 0;        int n = params.length;        for (int i = 0; i < n; ++i)            stacksize += addLoad(code, stacksize + offset, params[i]);        return stacksize;    }    private static int addLoad(Bytecode code, int n, Class type) {        if (type.isPrimitive()) {            if (type == Long.TYPE) {                code.addLload(n);                return 2;            }            else if (type == Float.TYPE)                code.addFload(n);            else if (type == Double.TYPE) {                code.addDload(n);                return 2;            }            else                code.addIload(n);        }        else            code.addAload(n);        return 1;    }    private static int addReturn(Bytecode code, Class type) {        if (type.isPrimitive()) {            if (type == Long.TYPE) {                code.addOpcode(Opcode.LRETURN);                return 2;            }            else if (type == Float.TYPE)                code.addOpcode(Opcode.FRETURN);            else if (type == Double.TYPE) {                code.addOpcode(Opcode.DRETURN);                return 2;            }            else if (type == Void.TYPE) {                code.addOpcode(Opcode.RETURN);                return 0;            }            else                code.addOpcode(Opcode.IRETURN);        }        else            code.addOpcode(Opcode.ARETURN);        return 1;    }    private static void makeParameterList(Bytecode code, Class[] params) {        int regno = 1;        int n = params.length;        code.addIconst(n);        code.addAnewarray("java/lang/Object");        for (int i = 0; i < n; i++) {            code.addOpcode(Opcode.DUP);            code.addIconst(i);            Class type = params[i];            if (type.isPrimitive())                regno = makeWrapper(code, type, regno);            else {                code.addAload(regno);                regno++;            }            code.addOpcode(Opcode.AASTORE);        }    }    private static int makeWrapper(Bytecode code, Class type, int regno) {        int index = FactoryHelper.typeIndex(type);        String wrapper = FactoryHelper.wrapperTypes[index];         code.addNew(wrapper);        code.addOpcode(Opcode.DUP);        addLoad(code, regno, type);        code.addInvokespecial(wrapper, "<init>",                              FactoryHelper.wrapperDesc[index]);        return regno + FactoryHelper.dataSize[index];    }    /**     * @param methodName        might be null.     */    private static void callFindMethod(Bytecode code, String findMethod,            int arrayVar, int index, String methodName, String desc) {        String findClass = RuntimeSupport.class.getName();        String findDesc            = "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/reflect/Method;";        code.addAload(arrayVar);        code.addIconst(index);        if (methodName == null)            code.addOpcode(Opcode.ACONST_NULL);        else {            code.addAload(0);            code.addLdc(methodName);            code.addLdc(desc);            code.addInvokestatic(findClass, findMethod, findDesc);        }        code.addOpcode(Opcode.AASTORE);    }    private static void addUnwrapper(Bytecode code, Class type) {        if (type.isPrimitive()) {            if (type == Void.TYPE)                code.addOpcode(Opcode.POP);            else {                int index = FactoryHelper.typeIndex(type);                String wrapper = FactoryHelper.wrapperTypes[index];                code.addCheckcast(wrapper);                code.addInvokevirtual(wrapper,                                      FactoryHelper.unwarpMethods[index],                                      FactoryHelper.unwrapDesc[index]);            }        }        else            code.addCheckcast(type.getName());    }    private static MethodInfo makeWriteReplace(ConstPool cp) {        MethodInfo minfo = new MethodInfo(cp, "writeReplace", "()Ljava/lang/Object;");        String[] list = new String[1];        list[0] = "java.io.ObjectStreamException";        ExceptionsAttribute ea = new ExceptionsAttribute(cp);        ea.setExceptions(list);        minfo.setExceptionsAttribute(ea);        Bytecode code = new Bytecode(cp, 0, 1);        code.addAload(0);        code.addInvokestatic("javassist.util.proxy.RuntimeSupport",                             "makeSerializedProxy",                             "(Ljava/lang/Object;)Ljavassist/util/proxy/SerializedProxy;");        code.addOpcode(Opcode.ARETURN);        minfo.setCodeAttribute(code.toCodeAttribute());        return minfo;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -