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

📄 proxyfactory.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    }    private void setField(String fieldName, Object value) {        if (thisClass != null && value != null)            try {                Field f = thisClass.getField(fieldName);                f.setAccessible(true);                f.set(null, value);                f.setAccessible(false);            }            catch (Exception e) {                throw new RuntimeException(e);            }    }    static MethodFilter getFilter(Class clazz) {        return (MethodFilter)getField(clazz, METHOD_FILTER_FIELD);    }    static MethodHandler getHandler(Class clazz) {        return (MethodHandler)getField(clazz, DEFAULT_INTERCEPTOR);    }    private static Object getField(Class clazz, String fieldName) {        try {            Field f = clazz.getField(fieldName);            f.setAccessible(true);            Object value = f.get(null);            f.setAccessible(false);            return value;        }        catch (Exception e) {            throw new RuntimeException(e);        }    }    /**     * A provider of class loaders.     *     * @see #classLoaderProvider     * @since 3.4     */    public static interface ClassLoaderProvider {        /**         * Returns a class loader.         *         * @param pf    a proxy factory that is going to obtain a class loader.         */        public ClassLoader get(ProxyFactory pf);    }    /**     * A provider used by <code>createClass()</code> for obtaining     * a class loader.     * <code>get()</code> on this <code>ClassLoaderProvider</code> object     * is called to obtain a class loader.     *     * <p>The value of this field can be updated for changing the default     * implementation.     *     * <p>Example:     * <ul><pre>     * ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() {     *     public ClassLoader get(ProxyFactory pf) {     *         return Thread.currentThread().getContextClassLoader();     *     }     * };     * </pre></ul>     *     * @since 3.4     */    public static ClassLoaderProvider classLoaderProvider        = new ClassLoaderProvider() {              public ClassLoader get(ProxyFactory pf) {                  return pf.getClassLoader0();              }          };    protected ClassLoader getClassLoader() {        return classLoaderProvider.get(this);    }    protected ClassLoader getClassLoader0() {        ClassLoader loader = null;        if (superClass != null && !superClass.getName().equals("java.lang.Object"))            loader = superClass.getClassLoader();        else if (interfaces != null && interfaces.length > 0)            loader = interfaces[0].getClassLoader();         if (loader == null) {            loader = getClass().getClassLoader();            // In case javassist is in the endorsed dir            if (loader == null) {                loader = Thread.currentThread().getContextClassLoader();                if (loader == null)                    loader = ClassLoader.getSystemClassLoader();            }        }        return loader;    }    protected ProtectionDomain getDomain() {        Class clazz;        if (superClass != null && !superClass.getName().equals("java.lang.Object"))            clazz = superClass;        else if (interfaces != null && interfaces.length > 0)            clazz = interfaces[0];        else            clazz = this.getClass();        return clazz.getProtectionDomain();    }    /**     * Creates a proxy class and returns an instance of that class.     *     * @param paramTypes    parameter types for a constructor.     * @param args          arguments passed to a constructor.     * @param mh            the method handler for the proxy class.     * @since 3.4     */    public Object create(Class[] paramTypes, Object[] args, MethodHandler mh)        throws NoSuchMethodException, IllegalArgumentException,               InstantiationException, IllegalAccessException, InvocationTargetException    {        Object obj = create(paramTypes, args);        ((ProxyObject)obj).setHandler(mh);        return obj;    }    /**     * Creates a proxy class and returns an instance of that class.     *     * @param paramTypes    parameter types for a constructor.     * @param args          arguments passed to a constructor.     */    public Object create(Class[] paramTypes, Object[] args)        throws NoSuchMethodException, IllegalArgumentException,               InstantiationException, IllegalAccessException, InvocationTargetException    {        Class c = createClass();        Constructor cons = c.getConstructor(paramTypes);        return cons.newInstance(args);    }    /**     * Sets the default invocation handler.  This invocation handler is shared     * among all the instances of a proxy class unless another is explicitly     * specified.     */    public void setHandler(MethodHandler mi) {        handler = mi;        setField(DEFAULT_INTERCEPTOR, handler);    }    private static int counter = 0;    private static synchronized String makeProxyName(String classname) {        return classname + "_$$_javassist_" + counter++;    }    private ClassFile make() throws CannotCompileException {        String superName, classname;        if (interfaces == null)            interfaces = new Class[0];        if (superClass == null) {            superClass = OBJECT_TYPE;            superName = superClass.getName();            classname = interfaces.length == 0 ? superName                                               : interfaces[0].getName();         }        else {            superName = superClass.getName();            classname = superName;        }        if (Modifier.isFinal(superClass.getModifiers()))            throw new CannotCompileException(superName + " is final");        classname = makeProxyName(classname);        if (classname.startsWith("java."))            classname = "org.javassist.tmp." + classname;        ClassFile cf = new ClassFile(false, classname, superName);        cf.setAccessFlags(AccessFlag.PUBLIC);        setInterfaces(cf, interfaces);        ConstPool pool = cf.getConstPool();        FieldInfo finfo = new FieldInfo(pool, DEFAULT_INTERCEPTOR, HANDLER_TYPE);        finfo.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);        cf.addField(finfo);        FieldInfo finfo2 = new FieldInfo(pool, HANDLER, HANDLER_TYPE);        finfo2.setAccessFlags(AccessFlag.PRIVATE);        cf.addField(finfo2);        FieldInfo finfo3 = new FieldInfo(pool, METHOD_FILTER_FIELD,                                            "Ljavassist/util/proxy/MethodFilter;");        finfo3.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);        cf.addField(finfo3);        HashMap allMethods = getMethods(superClass, interfaces);        int size = allMethods.size();        makeConstructors(classname, cf, pool, classname);        int s = overrideMethods(cf, pool, classname, allMethods);        addMethodsHolder(cf, pool, classname, s);        addSetter(classname, cf, pool);        try {            cf.addMethod(makeWriteReplace(pool));        }        catch (DuplicateMemberException e) {            // writeReplace() is already declared in the super class/interfaces.        }        thisClass = null;                  return cf;    }    private static void setInterfaces(ClassFile cf, Class[] interfaces) {        String setterIntf = ProxyObject.class.getName();        String[] list;        if (interfaces == null || interfaces.length == 0)            list = new String[] { setterIntf };        else {            list = new String[interfaces.length + 1];            for (int i = 0; i < interfaces.length; i++)                list[i] = interfaces[i].getName();            list[interfaces.length] = setterIntf;        }        cf.setInterfaces(list);    }    private static void addMethodsHolder(ClassFile cf, ConstPool cp,                                         String classname, int size)        throws CannotCompileException    {        FieldInfo finfo = new FieldInfo(cp, HOLDER, HOLDER_TYPE);        finfo.setAccessFlags(AccessFlag.PRIVATE | AccessFlag.STATIC);        cf.addField(finfo);        MethodInfo minfo = new MethodInfo(cp, "<clinit>", "()V");        Bytecode code = new Bytecode(cp, 0, 0);        code.addIconst(size * 2);        code.addAnewarray("java.lang.reflect.Method");        code.addPutstatic(classname, HOLDER, HOLDER_TYPE);        code.addOpcode(Bytecode.RETURN);        minfo.setCodeAttribute(code.toCodeAttribute());        cf.addMethod(minfo);    }    private static void addSetter(String classname, ClassFile cf, ConstPool cp)        throws CannotCompileException    {        MethodInfo minfo = new MethodInfo(cp, HANDLER_SETTER,                                          HANDLER_SETTER_TYPE);        minfo.setAccessFlags(AccessFlag.PUBLIC);        Bytecode code = new Bytecode(cp, 2, 2);        code.addAload(0);        code.addAload(1);        code.addPutfield(classname, HANDLER, HANDLER_TYPE);        code.addOpcode(Bytecode.RETURN);        minfo.setCodeAttribute(code.toCodeAttribute());        cf.addMethod(minfo);    }    private int overrideMethods(ClassFile cf, ConstPool cp, String className,                                HashMap allMethods)        throws CannotCompileException    {        String prefix = makeUniqueName("_d", allMethods);        Set entries = allMethods.entrySet();        Iterator it = entries.iterator();        int index = 0;        while (it.hasNext()) {            Map.Entry e = (Map.Entry)it.next();            String key = (String)e.getKey();            Method meth = (Method)e.getValue();            int mod = meth.getModifiers();            if (!Modifier.isFinal(mod) && !Modifier.isStatic(mod)                    && isVisible(mod, className, meth))                if (methodFilter == null || methodFilter.isHandled(meth))                    override(className, meth, prefix, index++,                             keyToDesc(key), cf, cp);        }        return index;    }    private void override(String thisClassname, Method meth, String prefix,                          int index, String desc, ClassFile cf, ConstPool cp)        throws CannotCompileException    {        Class declClass = meth.getDeclaringClass();        String delegatorName = prefix + index + meth.getName();        if (Modifier.isAbstract(meth.getModifiers()))            delegatorName = null;        else {            MethodInfo delegator                = makeDelegator(meth, desc, cp, declClass, delegatorName);            // delegator is not a bridge method.  See Sec. 15.12.4.5 of JLS 3rd Ed.            delegator.setAccessFlags(delegator.getAccessFlags() & ~AccessFlag.BRIDGE);            cf.addMethod(delegator);        }        MethodInfo forwarder            = makeForwarder(thisClassname, meth, desc, cp, declClass,                            delegatorName, index);        cf.addMethod(forwarder);    }    private void makeConstructors(String thisClassName, ClassFile cf,            ConstPool cp, String classname) throws CannotCompileException    {        Constructor[] cons = superClass.getDeclaredConstructors();        for (int i = 0; i < cons.length; i++) {            Constructor c = cons[i];            int mod = c.getModifiers();            if (!Modifier.isFinal(mod) && !Modifier.isPrivate(mod)                    && isVisible(mod, classname, c)) {                MethodInfo m = makeConstructor(thisClassName, c, cp, superClass);                cf.addMethod(m);            }        }    }    private static String makeUniqueName(String name, HashMap hash) {        Set keys = hash.keySet();        if (makeUniqueName0(name, keys.iterator()))            return name;        for (int i = 100; i < 999; i++) {            String s = name + i;            if (makeUniqueName0(s, keys.iterator()))                return s;        }        throw new RuntimeException("cannot make a unique method name");    }    private static boolean makeUniqueName0(String name, Iterator it) {        while (it.hasNext()) {

⌨️ 快捷键说明

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