• 将dubbo中使用的动态代理作为工具类


    ReflectUtils

    package per.qiao.util.javassistUtil;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    
    /**
     * Create by IntelliJ Idea 2018.2
     *
     * @author: qyp
     * Date: 2019-07-14 19:50
     */
    public class ReflectUtils {
    
        /**
         * void(V).
         */
        public static final char JVM_VOID = 'V';
    
        /**
         * boolean(Z).
         */
        public static final char JVM_BOOLEAN = 'Z';
    
        /**
         * byte(B).
         */
        public static final char JVM_BYTE = 'B';
    
        /**
         * char(C).
         */
        public static final char JVM_CHAR = 'C';
    
        /**
         * double(D).
         */
        public static final char JVM_DOUBLE = 'D';
    
        /**
         * float(F).
         */
        public static final char JVM_FLOAT = 'F';
    
        /**
         * int(I).
         */
        public static final char JVM_INT = 'I';
    
        /**
         * long(J).
         */
        public static final char JVM_LONG = 'J';
    
        /**
         * short(S).
         */
        public static final char JVM_SHORT = 'S';
    
        public static String getDesc(final Method m) {
            StringBuilder ret = new StringBuilder(m.getName()).append('(');
            Class<?>[] parameterTypes = m.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++)
                ret.append(getDesc(parameterTypes[i]));
            ret.append(')').append(getDesc(m.getReturnType()));
            return ret.toString();
        }
    
        public static String getName(final Method m) {
            StringBuilder ret = new StringBuilder();
            ret.append(getName(m.getReturnType())).append(' ');
            ret.append(m.getName()).append('(');
            Class<?>[] parameterTypes = m.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                if (i > 0) {
                    ret.append(',');
                }
                ret.append(getName(parameterTypes[i]));
            }
            ret.append(')');
            return ret.toString();
        }
    
        /**
         * get name.
         * java.lang.Object[][].class => "java.lang.Object[][]"
         *
         * @param c class.
         * @return name.
         */
        public static String getName(Class<?> c) {
            if (c.isArray()) {
                StringBuilder sb = new StringBuilder();
                do {
                    sb.append("[]");
                    c = c.getComponentType();
                }
                while (c.isArray());
    
                return c.getName() + sb.toString();
            }
            return c.getName();
        }
    
    
        /**
         * get class desc.
         * boolean[].class => "[Z"
         * Object.class => "Ljava/lang/Object;"
         *
         * @param c class.
         * @return desc.
         */
        public static String getDesc(Class<?> c) {
            StringBuilder ret = new StringBuilder();
    
            while (c.isArray()) {
                ret.append('[');
                c = c.getComponentType();
            }
    
            if (c.isPrimitive()) {
                String t = c.getName();
                if ("void".equals(t)) { ret.append(JVM_VOID);}
                else if ("boolean".equals(t)) { ret.append(JVM_BOOLEAN); }
                else if ("byte".equals(t)) {ret.append(JVM_BYTE);}
                else if ("char".equals(t)) { ret.append(JVM_CHAR);}
                else if ("double".equals(t)) { ret.append(JVM_DOUBLE); }
                else if ("float".equals(t)) { ret.append(JVM_FLOAT); }
                else if ("int".equals(t)) { ret.append(JVM_INT); }
                else if ("long".equals(t)) { ret.append(JVM_LONG); }
                else if ("short".equals(t)) { ret.append(JVM_SHORT); }
            } else {
                ret.append('L');
                ret.append(c.getName().replace('.', '/'));
                ret.append(';');
            }
            return ret.toString();
        }
    
        /**
         * get constructor desc.
         * "()V", "(Ljava/lang/String;I)V"
         *
         * @param c constructor.
         * @return desc
         */
        public static String getDesc(final Constructor<?> c) {
            StringBuilder ret = new StringBuilder("(");
            Class<?>[] parameterTypes = c.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++)
                ret.append(getDesc(parameterTypes[i]));
            ret.append(')').append('V');
            return ret.toString();
        }
    
        /**
         * get method desc.
         * "(I)I", "()V", "(Ljava/lang/String;Z)V"
         *
         * @param m method.
         * @return desc.
         */
        public static String getDescWithoutMethodName(Method m) {
            StringBuilder ret = new StringBuilder();
            ret.append('(');
            Class<?>[] parameterTypes = m.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++)
                ret.append(getDesc(parameterTypes[i]));
            ret.append(')').append(getDesc(m.getReturnType()));
            return ret.toString();
        }
    
    }
    
    

    ClassHelper

    package per.qiao.util.javassistUtil;
    
    import java.util.*;
    
    /**
     * Create by IntelliJ Idea 2018.2
     *
     * @author: qyp
     * Date: 2019-07-13 23:27
     */
    public class ClassHelper {
    
    
        /**
         * Map with primitive type name as key and corresponding primitive type as
         * value, for example: "int" -> "int.class".
         */
        private static final Map<String, Class<?>> primitiveTypeNameMap = new HashMap<String, Class<?>>(16);
        /**
         * Map with primitive wrapper type as key and corresponding primitive type
         * as value, for example: Integer.class -> int.class.
         */
        private static final Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new HashMap<Class<?>, Class<?>>(8);
    
        static {
            primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
            primitiveWrapperTypeMap.put(Byte.class, byte.class);
            primitiveWrapperTypeMap.put(Character.class, char.class);
            primitiveWrapperTypeMap.put(Double.class, double.class);
            primitiveWrapperTypeMap.put(Float.class, float.class);
            primitiveWrapperTypeMap.put(Integer.class, int.class);
            primitiveWrapperTypeMap.put(Long.class, long.class);
            primitiveWrapperTypeMap.put(Short.class, short.class);
    
            Set<Class<?>> primitiveTypeNames = new HashSet<Class<?>>(16);
            primitiveTypeNames.addAll(primitiveWrapperTypeMap.values());
            primitiveTypeNames.addAll(Arrays
                    .asList(new Class<?>[]{boolean[].class, byte[].class, char[].class, double[].class,
                            float[].class, int[].class, long[].class, short[].class}));
            for (Iterator<Class<?>> it = primitiveTypeNames.iterator(); it.hasNext(); ) {
                Class<?> primitiveClass = (Class<?>) it.next();
                primitiveTypeNameMap.put(primitiveClass.getName(), primitiveClass);
            }
        }
        /**
         * get class loader
         *
         * @param cls
         * @return class loader
         */
        public static ClassLoader getClassLoader(Class<?> cls) {
            ClassLoader cl = null;
            try {
                cl = Thread.currentThread().getContextClassLoader();
            } catch (Throwable ex) {
                // Cannot access thread context ClassLoader - falling back to system class loader...
            }
            if (cl == null) {
                // No thread context class loader -> use class loader of this class.
                cl = cls.getClassLoader();
            }
            return cl;
        }
    }
    

    ClassGenerator

    package per.qiao.util.javassistUtil;
    
    
    import javassist.*;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    import java.security.ProtectionDomain;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.atomic.AtomicLong;
    
    /**
     * Create by IntelliJ Idea 2018.2
     *
     * @author: qyp
     * Date: 2019-07-13 23:13
     */
    public final class ClassGenerator {
        private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(0);
        private static final String SIMPLE_NAME_TAG = "<init>";
        /**
         * ClassLoader - ClassPool
         */
        private static final Map<ClassLoader, ClassPool> POOL_MAP = new ConcurrentHashMap<ClassLoader, ClassPool>();
        private ClassPool mPool;
        private CtClass mCtc;
        private String mClassName, mSuperClass;
        private Set<String> mInterfaces;
        private List<String> mFields, mConstructors, mMethods;
        /**
         * <method desc,method instance>
         */
        private Map<String, Method> mCopyMethods;
        // <constructor desc,constructor instance>
        private Map<String, Constructor<?>> mCopyConstructors;
        private boolean mDefaultConstructor = false;
    
        private ClassGenerator() {
        }
    
        private ClassGenerator(ClassPool pool) {
            mPool = pool;
        }
    
        public static ClassGenerator newInstance() {
            return new ClassGenerator(getClassPool(Thread.currentThread().getContextClassLoader()));
        }
    
        public static ClassGenerator newInstance(ClassLoader loader) {
            return new ClassGenerator(getClassPool(loader));
        }
    
    
        public static ClassPool getClassPool(ClassLoader loader) {
            if (loader == null)
                return ClassPool.getDefault();
    
            ClassPool pool = POOL_MAP.get(loader);
            if (pool == null) {
                pool = new ClassPool(true);
                pool.appendClassPath(new LoaderClassPath(loader));
                POOL_MAP.put(loader, pool);
            }
            return pool;
        }
    
        private static String modifier(int mod) {
            if (Modifier.isPublic(mod)) return "public";
            if (Modifier.isProtected(mod)) return "protected";
            if (Modifier.isPrivate(mod)) return "private";
            return "";
        }
    
        public String getClassName() {
            return mClassName;
        }
    
        public ClassGenerator setClassName(String name) {
            mClassName = name;
            return this;
        }
    
        public ClassGenerator addInterface(String cn) {
            if (mInterfaces == null)
                mInterfaces = new HashSet<String>();
            mInterfaces.add(cn);
            return this;
        }
    
        public ClassGenerator addInterface(Class<?> cl) {
            return addInterface(cl.getName());
        }
    
        public ClassGenerator setSuperClass(String cn) {
            mSuperClass = cn;
            return this;
        }
    
        public ClassGenerator setSuperClass(Class<?> cl) {
            mSuperClass = cl.getName();
            return this;
        }
    
        public ClassGenerator addField(String code) {
            if (mFields == null)
                mFields = new ArrayList<String>();
            mFields.add(code);
            return this;
        }
    
        public ClassGenerator addField(String name, int mod, Class<?> type) {
            return addField(name, mod, type, null);
        }
    
        public ClassGenerator addField(String name, int mod, Class<?> type, String def) {
            StringBuilder sb = new StringBuilder();
            sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(type)).append(' ');
            sb.append(name);
            if (def != null && def.length() > 0) {
                sb.append('=');
                sb.append(def);
            }
            sb.append(';');
            return addField(sb.toString());
        }
    
        public ClassGenerator addMethod(String code) {
            if (mMethods == null)
                mMethods = new ArrayList<String>();
            mMethods.add(code);
            return this;
        }
    
        public ClassGenerator addMethod(String name, int mod, Class<?> rt, Class<?>[] pts, String body) {
            return addMethod(name, mod, rt, pts, null, body);
        }
    
        public ClassGenerator addMethod(String name, int mod, Class<?> rt, Class<?>[] pts, Class<?>[] ets, String body) {
            StringBuilder sb = new StringBuilder();
            sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(rt)).append(' ').append(name);
            sb.append('(');
            for (int i = 0; i < pts.length; i++) {
                if (i > 0)
                    sb.append(',');
                sb.append(ReflectUtils.getName(pts[i]));
                sb.append(" arg").append(i);
            }
            sb.append(')');
            if (ets != null && ets.length > 0) {
                sb.append(" throws ");
                for (int i = 0; i < ets.length; i++) {
                    if (i > 0)
                        sb.append(',');
                    sb.append(ReflectUtils.getName(ets[i]));
                }
            }
            sb.append('{').append(body).append('}');
            return addMethod(sb.toString());
        }
    
        public ClassGenerator addMethod(Method m) {
            addMethod(m.getName(), m);
            return this;
        }
    
        public ClassGenerator addMethod(String name, Method m) {
            String desc = name + ReflectUtils.getDescWithoutMethodName(m);
            addMethod(':' + desc);
            if (mCopyMethods == null)
                mCopyMethods = new ConcurrentHashMap<String, Method>(8);
            mCopyMethods.put(desc, m);
            return this;
        }
    
        public ClassGenerator addConstructor(String code) {
            if (mConstructors == null)
                mConstructors = new LinkedList<String>();
            mConstructors.add(code);
            return this;
        }
    
        public ClassGenerator addConstructor(int mod, Class<?>[] pts, String body) {
            return addConstructor(mod, pts, null, body);
        }
    
        public ClassGenerator addConstructor(int mod, Class<?>[] pts, Class<?>[] ets, String body) {
            StringBuilder sb = new StringBuilder();
            sb.append(modifier(mod)).append(' ').append(SIMPLE_NAME_TAG);
            sb.append('(');
            for (int i = 0; i < pts.length; i++) {
                if (i > 0)
                    sb.append(',');
                sb.append(ReflectUtils.getName(pts[i]));
                sb.append(" arg").append(i);
            }
            sb.append(')');
            if (ets != null && ets.length > 0) {
                sb.append(" throws ");
                for (int i = 0; i < ets.length; i++) {
                    if (i > 0)
                        sb.append(',');
                    sb.append(ReflectUtils.getName(ets[i]));
                }
            }
            sb.append('{').append(body).append('}');
            return addConstructor(sb.toString());
        }
    
        public ClassGenerator addConstructor(Constructor<?> c) {
            String desc = ReflectUtils.getDesc(c);
            addConstructor(":" + desc);
            if (mCopyConstructors == null)
                mCopyConstructors = new ConcurrentHashMap<String, Constructor<?>>(4);
            mCopyConstructors.put(desc, c);
            return this;
        }
    
        public ClassGenerator addDefaultConstructor() {
            mDefaultConstructor = true;
            return this;
        }
    
        public ClassPool getClassPool() {
            return mPool;
        }
    
        public Class<?> toClass() {
            return toClass(ClassHelper.getClassLoader(ClassGenerator.class), getClass().getProtectionDomain());
        }
    
        public Class<?> toClass(ClassLoader loader, ProtectionDomain pd) {
            if (mCtc != null)
                mCtc.detach();
            long id = CLASS_NAME_COUNTER.getAndIncrement();
            try {
                CtClass ctcs = mSuperClass == null ? null : mPool.get(mSuperClass);
                if (mClassName == null)
                    mClassName = (mSuperClass == null || javassist.Modifier.isPublic(ctcs.getModifiers())
                            ? ClassGenerator.class.getName() : mSuperClass + "$sc") + id;
                mCtc = mPool.makeClass(mClassName);
                if (mSuperClass != null)
                    mCtc.setSuperclass(ctcs);
                // add dynamic class tag.  去掉dubbo回声测试的DC接口
                //mCtc.addInterface(mPool.get(DC.class.getName()));
                if (mInterfaces != null)
                    for (String cl : mInterfaces) mCtc.addInterface(mPool.get(cl));
                if (mFields != null)
                    for (String code : mFields) mCtc.addField(CtField.make(code, mCtc));
                if (mMethods != null) {
                    for (String code : mMethods) {
                        if (code.charAt(0) == ':')
                            mCtc.addMethod(CtNewMethod.copy(getCtMethod(mCopyMethods.get(code.substring(1))), code.substring(1, code.indexOf('(')), mCtc, null));
                        else
                            // 这里将
                            mCtc.addMethod(CtNewMethod.make(code, mCtc));
                    }
                }
                if (mDefaultConstructor)
                    mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));
                if (mConstructors != null) {
                    for (String code : mConstructors) {
                        if (code.charAt(0) == ':') {
                            mCtc.addConstructor(CtNewConstructor.copy(getCtConstructor(mCopyConstructors.get(code.substring(1))), mCtc, null));
                        } else {
                            String[] sn = mCtc.getSimpleName().split("\$+"); // inner class name include $.
                            mCtc.addConstructor(CtNewConstructor.make(code.replaceFirst(SIMPLE_NAME_TAG, sn[sn.length - 1]), mCtc));
                        }
                    }
                }
                return mCtc.toClass(loader, pd);
            } catch (RuntimeException e) {
                throw e;
            } catch (NotFoundException e) {
                throw new RuntimeException(e.getMessage(), e);
            } catch (CannotCompileException e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
    
        public void release() {
            if (mCtc != null) mCtc.detach();
            if (mInterfaces != null) mInterfaces.clear();
            if (mFields != null) mFields.clear();
            if (mMethods != null) mMethods.clear();
            if (mConstructors != null) mConstructors.clear();
            if (mCopyMethods != null) mCopyMethods.clear();
            if (mCopyConstructors != null) mCopyConstructors.clear();
        }
    
        private CtClass getCtClass(Class<?> c) throws NotFoundException {
            return mPool.get(c.getName());
        }
    
        private CtMethod getCtMethod(Method m) throws NotFoundException {
            return getCtClass(m.getDeclaringClass()).getMethod(m.getName(), ReflectUtils.getDescWithoutMethodName(m));
        }
    
        private CtConstructor getCtConstructor(Constructor<?> c) throws NotFoundException {
            return getCtClass(c.getDeclaringClass()).getConstructor(ReflectUtils.getDesc(c));
        }
    }
    

    Proxy

    package per.qiao.util.javassistUtil;
    
    
    
    
    import sun.security.action.GetBooleanAction;
    
    import java.lang.ref.Reference;
    import java.lang.ref.WeakReference;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.security.AccessController;
    import java.util.*;
    import java.util.concurrent.atomic.AtomicLong;
    
    /**
     * Create by IntelliJ Idea 2018.2
     *
     * @author: qyp
     * Date: 2019-07-13 22:59
     */
    public abstract class Proxy {
        public static final InvocationHandler RETURN_NULL_INVOKER = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) {
                return null;
            }
        };
        public static final InvocationHandler THROW_UNSUPPORTED_INVOKER = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) {
                throw new UnsupportedOperationException("Method [" + ReflectUtils.getName(method) + "] unimplemented.");
            }
        };
        private static final AtomicLong PROXY_CLASS_COUNTER = new AtomicLong(0);
        private static final String PACKAGE_NAME = Proxy.class.getPackage().getName();
        private static final Map<ClassLoader, Map<String, Object>> ProxyCacheMap = new WeakHashMap<ClassLoader, Map<String, Object>>();
    
        private static final Object PendingGenerationMarker = new Object();
    
        private static final boolean saveGeneratedFiles = (Boolean)AccessController.doPrivileged(new GetBooleanAction("per.qiao.ProxyGenerator.saveGeneratedFiles"));
    
        protected Proxy() {
        }
    
        /**
         * Get proxy.
         *
         * @param ics interface class array.
         * @return Proxy instance.
         */
        public static Proxy getProxy(Class<?>... ics) {
            return getProxy(ClassHelper.getClassLoader(Proxy.class), ics);
        }
    
        /**
         * Get proxy.
         *
         * @param cl  class loader.
         * @param ics interface class array.
         * @return Proxy instance.
         */
        public static Proxy getProxy(ClassLoader cl, Class<?>... ics) {
            if (ics.length > 65535)
                throw new IllegalArgumentException("interface limit exceeded");
    
            StringBuilder sb = new StringBuilder();
            // 校验接口的个数
            for (int i = 0; i < ics.length; i++) {
                String itf = ics[i].getName();
                if (!ics[i].isInterface())
                    throw new RuntimeException(itf + " is not a interface.");
    
                Class<?> tmp = null;
                try {
                    tmp = Class.forName(itf, false, cl);
                } catch (ClassNotFoundException e) {
                }
    
                if (tmp != ics[i])
                    throw new IllegalArgumentException(ics[i] + " is not visible from class loader");
    
                sb.append(itf).append(';');
            }
    
            // use interface class name list as key.
            String key = sb.toString();
    
            // get cache by class loader.
            Map<String, Object> cache;
            synchronized (ProxyCacheMap) {
                cache = ProxyCacheMap.get(cl);
                if (cache == null) {
                    cache = new HashMap<String, Object>();
                    ProxyCacheMap.put(cl, cache);
                }
            }
    
            Proxy proxy = null;
            synchronized (cache) {
                do {
                    Object value = cache.get(key);
                    if (value instanceof Reference<?>) {
                        proxy = (Proxy) ((Reference<?>) value).get();
                        if (proxy != null)
                            return proxy;
                    }
    
                    if (value == PendingGenerationMarker) {
                        try {
                            cache.wait();
                        } catch (InterruptedException e) {
                        }
                    } else {
                        cache.put(key, PendingGenerationMarker);
                        break;
                    }
                }
                while (true);
            }
    
            long id = PROXY_CLASS_COUNTER.getAndIncrement();
            String pkg = null;
            ClassGenerator ccp = null, ccm = null;
            try {
                ccp = ClassGenerator.newInstance(cl);
    
                Set<String> worked = new HashSet<String>();
                List<Method> methods = new ArrayList<Method>();
    
                // 如果没有被public修饰,那么就是default级别,那么该动态类的位置只能和接口在同一个包内
                for (int i = 0; i < ics.length; i++) {
                    if (!Modifier.isPublic(ics[i].getModifiers())) {
                        String npkg = ics[i].getPackage().getName();
                        if (pkg == null) {
                            pkg = npkg;
                        } else {
                            if (!pkg.equals(npkg))
                                throw new IllegalArgumentException("non-public interfaces from different packages");
                        }
                    }
                    ccp.addInterface(ics[i]);
    
                    for (Method method : ics[i].getMethods()) {
                        String desc = ReflectUtils.getDesc(method);
                        if (worked.contains(desc))
                            continue;
                        worked.add(desc);
    
                        int ix = methods.size();
                        Class<?> rt = method.getReturnType();
                        Class<?>[] pts = method.getParameterTypes();
    
                        StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];");
                        for (int j = 0; j < pts.length; j++)
                            code.append(" args[").append(j).append("] = ($w)$").append(j + 1).append(";");
                        code.append(" Object ret = handler.invoke(this, methods[" + ix + "], args);");
                        if (!Void.TYPE.equals(rt))
                            code.append(" return ").append(asArgument(rt, "ret")).append(";");
    
                        methods.add(method);
                        ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());
                    }
                }
    
                if (pkg == null)
                    pkg = PACKAGE_NAME;
    
                // create ProxyInstance class.
                String pcn = pkg + ".proxy" + id;
                ccp.setClassName(pcn);
                ccp.addField("public static java.lang.reflect.Method[] methods;");
                ccp.addField("private " + InvocationHandler.class.getName() + " handler;");
                ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{InvocationHandler.class}, new Class<?>[0], "handler=$1;");
                ccp.addDefaultConstructor();
                Class<?> clazz = ccp.toClass();
                clazz.getField("methods").set(null, methods.toArray(new Method[0]));
    
                // create Proxy class.
                String fcn = Proxy.class.getName() + id;
                ccm = ClassGenerator.newInstance(cl);
                ccm.setClassName(fcn);
                ccm.addDefaultConstructor();
                ccm.setSuperClass(Proxy.class);
                ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
                Class<?> pc = ccm.toClass();
    
    //            if (System.getProperty("per.qiao.ProxyGenerator.saveGeneratedFiles") != null) {
                if (saveGeneratedFiles) {
                    ccp.getClassPool().get("per.qiao.util.javassistUtil.proxy0").writeFile("E:\Java4IDEA\dubboSource\src\main\java\");
                }
    
                proxy = (Proxy) pc.newInstance();
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            } finally {
                // release ClassGenerator
                if (ccp != null)
                    ccp.release();
                if (ccm != null)
                    ccm.release();
                synchronized (cache) {
                    if (proxy == null)
                        cache.remove(key);
                    else
                        cache.put(key, new WeakReference<Proxy>(proxy));
                    cache.notifyAll();
                }
            }
            return proxy;
        }
    
        private static String asArgument(Class<?> cl, String name) {
            if (cl.isPrimitive()) {
                if (Boolean.TYPE == cl)
                    return name + "==null?false:((Boolean)" + name + ").booleanValue()";
                if (Byte.TYPE == cl)
                    return name + "==null?(byte)0:((Byte)" + name + ").byteValue()";
                if (Character.TYPE == cl)
                    return name + "==null?(char)0:((Character)" + name + ").charValue()";
                if (Double.TYPE == cl)
                    return name + "==null?(double)0:((Double)" + name + ").doubleValue()";
                if (Float.TYPE == cl)
                    return name + "==null?(float)0:((Float)" + name + ").floatValue()";
                if (Integer.TYPE == cl)
                    return name + "==null?(int)0:((Integer)" + name + ").intValue()";
                if (Long.TYPE == cl)
                    return name + "==null?(long)0:((Long)" + name + ").longValue()";
                if (Short.TYPE == cl)
                    return name + "==null?(short)0:((Short)" + name + ").shortValue()";
                throw new RuntimeException(name + " is unknown primitive type.");
            }
            return "(" + ReflectUtils.getName(cl) + ")" + name;
        }
    
        /**
         * get instance with default handler.
         *
         * @return instance.
         */
        public Object newInstance() {
            return newInstance(THROW_UNSUPPORTED_INVOKER);
        }
    
        /**
         * get instance with special handler.
         *
         * @return instance.
         */
        abstract public Object newInstance(InvocationHandler handler);
    }
    
    

    测试

    public class ProxyTest {
    
        public static void main(String[] args) {
    
            Person person = new Person();
            Class<?>[] interfaces = Person.class.getInterfaces();
            System.getProperties().put("per.qiao.ProxyGenerator.saveGeneratedFiles", "true");
            BasePerson proxyperson = (BasePerson) Proxy.getProxy(interfaces).newInstance(new MyInvocationHandler(person));
    //        BasePerson proxyperson = (BasePerson) Proxy.getProxy(interfaces).newInstance(Proxy.RETURN_NULL_INVOKER);
    
            proxyperson.doSth();
    //        System.out.println(sth);
        }
    
    }
    
    class MyInvocationHandler implements InvocationHandler {
    
        Object targetObj;
    
        public MyInvocationHandler(Object obj) {
            targetObj = obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("代理前置");
            Object invoke = method.invoke(targetObj, args);
            System.out.println("代理后置");
            return invoke;
        }
    }
    
  • 相关阅读:
    C++类中使用new及delete小例子(续)
    C++类中使用new及delete小例子
    C++类中static修饰的函数的使用
    C++类使用static小例子(新手学习C++)
    C++结构体中使用函数与类中使用函数小结
    记一次简单的性能优化
    [转载]Java的内存回收机制
    写给自己的项目总结
    [转载]正则表达式30分钟入门教程
    使用JRockit进行性能优化一:环境搭建
  • 原文地址:https://www.cnblogs.com/qiaozhuangshi/p/11185460.html
Copyright © 2020-2023  润新知