动态代理的一点理解

代理的作用主要是某个方法在执行前后做一定的特殊处理;

静态代理:

package com.thinkgem.jeesite.proxy.handler;

import com.thinkgem.jeesite.proxy.UserOneService;
import com.thinkgem.jeesite.proxy.entity.User;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.lang.Nullable;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Description:
 *
 * @Author: leo.xiong
 * @CreateDate: 2020/08/11 09:57
 * @Email: [email protected]
 * @Since:
 */
public class MyInvocationHandler {

    private UserOneService userOneService;
    //传入需要代理的对象
    public MyInvocationHandler(UserOneService userOneService) {
        this.userOneService = userOneService;
    }
    //增强代理属性   
    public void staticProxy(String userId) {
        System.out.println("开始静态代理");
        userOneService.getUserName(userId);
        System.out.println("静态代理结束");
    }
}
package com.thinkgem.jeesite.proxy;

import com.thinkgem.jeesite.proxy.handler.MyInvocationHandler;
import com.thinkgem.jeesite.proxy.impl.UserOneOneServiceImpl;
import com.thinkgem.jeesite.proxy.impl.UserTwoServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * Description:
 *
 * @Author: leo.xiong
 * @CreateDate: 2020/08/11 10:03
 * @Email: [email protected]
 * @Since:
 */
public class MainTest {
    public static void main(String[] args) {
        UserOneService userOneService = new UserOneOneServiceImpl();
        MyInvocationHandler invocationOneHandler = new MyInvocationHandler(userOneService);
        invocationOneHandler.staticProxy("1");
    }
}

静态代理只能对某个类进行增强,一个类有多个方法,增强类也得写多个方法,多个类需要些多个增强类,效率极低。

动态代理:

java反射可以使用Method方法点invoke调用当前方法,动态代理就是基于 method.invoke(obj,args)实现的;

package com.thinkgem.jeesite.proxy.handler;

import com.thinkgem.jeesite.proxy.entity.User;
import org.springframework.lang.Nullable;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Description:
 *
 * @Author: leo.xiong
 * @CreateDate: 2020/08/11 09:57
 * @Email: [email protected]
 * @Since:
 */
public class MyInvocationHandler implements InvocationHandler {

    private Object object;

    public MyInvocationHandler(Object object) {
        this.object = object;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        /**
         * public final User getUserName(String var1) throws  {
         *         try {
         *             return (User)super.h.invoke(this, m3, new Object[]{var1});
         *         } catch (RuntimeException | Error var3) {
         *             throw var3;
         *         } catch (Throwable var4) {
         *             throw new UndeclaredThrowableException(var4);
         *         }
         *     }
         *     super.h就是当前的InvocationHandler对象
         *     如果method.invoke(object, args);使用proxy代理对象,则调用(User)super.h.invoke(this, m3, new Object[]{var1});
         *     之后invocationHandler.invoke(this, m3, new Object[]{var1})又调用当前方法,死循环,所有需要使用原始对象
         */
        //method是动态代理的方法名,object实现类,args参数,执行object的,方法为method的方法,实质就是原始为增强的方法。
        User user = (User) method.invoke(object, args);
        if (user != null) {
            System.out.println(user);
        }
        return user;
    }

    /**
     * 生成代理对象
     * @param classLoader
     * @param clazzs
     * @return
     */
    public Object getProxy(@Nullable ClassLoader classLoader, Class[] clazzs) {
        return Proxy.newProxyInstance(classLoader, clazzs, this);
    }
}
package com.thinkgem.jeesite.proxy;

import com.thinkgem.jeesite.proxy.handler.MyInvocationHandler;
import com.thinkgem.jeesite.proxy.impl.UserOneOneServiceImpl;
import com.thinkgem.jeesite.proxy.impl.UserTwoServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * Description:
 *
 * @Author: leo.xiong
 * @CreateDate: 2020/08/11 10:03
 * @Email: [email protected]
 * @Since:
 */
public class MainTest {
    public static void main(String[] args) {
        //是否生成代理文件,文件路径当前项目/com/sun/proxy路径下,默认不生成
        System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        //需要代理的对象,包含它实现的所有接口的实现方法
        UserOneService userOneService = new UserOneOneServiceImpl();
        //自定义的代理增强类,传入代理对象,相当于静态代理的传入的代理对象
        MyInvocationHandler invocationOneHandler = new MyInvocationHandler(userOneService);
        try {
            //获取代理对象
            UserThreeService userThreeService = (UserThreeService) invocationOneHandler.getProxy(UserOneService.class.getClassLoader(), new Class[]{UserOneService.class, UserThreeService.class});
            //执行方法
            userThreeService.getId("7");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

生成的代理类 

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.sun.proxy;

import com.thinkgem.jeesite.proxy.UserOneService;
import com.thinkgem.jeesite.proxy.UserThreeService;
import com.thinkgem.jeesite.proxy.entity.User;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements UserOneService, UserThreeService {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m4;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final User getUserName(String var1) throws  {
        try {
            return (User)super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }
    //代理类调用某方法super.h是InvocationHandler对象,调用invoke方法
    public final User getId(String var1) throws  {
        try {
            return (User)super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.thinkgem.jeesite.proxy.UserOneService").getMethod("getUserName", Class.forName("java.lang.String"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m4 = Class.forName("com.thinkgem.jeesite.proxy.UserThreeService").getMethod("getId", Class.forName("java.lang.String"));
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

生成代理类:

@CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

        final Class[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }

        /*
         * 生成并获取代理类Class 
         */
        Class cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
            //根据参数获取构造方法
            final Constructor cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            //判断构造方法修饰符是否public,如果不是设置为可操作
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            //根据构造方法获取对象
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }
private static Class getProxyClass0(ClassLoader loader,
                                           Class... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }
        //通过loader去缓存中获取是否存在class对象,不存在生成(弱引用),当内存不足时,GC自动回收
        return proxyClassCache.get(loader, interfaces);
    }
public V get(K key, P parameter) {
        Objects.requireNonNull(parameter);

        expungeStaleEntries();

        Object cacheKey = CacheKey.valueOf(key, refQueue);

        // lazily install the 2nd level valuesMap for the particular cacheKey
        ConcurrentMap> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            ConcurrentMap> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }

        // 生成key
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier might be a Factory or a CacheValue instance
                V value = supplier.get();
                if (value != null) {
                    return value;
                }
            }
            // else no supplier in cache
            // or a supplier that returned null (could be a cleared CacheValue
            // or a Factory that wasn't successful in installing the CacheValue)

            // lazily construct a Factory
            if (factory == null) {
                factory = new Factory(key, parameter, subKey, valuesMap);
            }

            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    // successfully installed Factory
                    supplier = factory;
                }
                // else retry with winning supplier
            } else {
                if (valuesMap.replace(subKey, supplier, factory)) {
                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    supplier = factory;
                } else {
                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }

返回Supplier对象,之后调用get方法

@Override
        public synchronized V get() { // serialize access
            // re-check
            Supplier supplier = valuesMap.get(subKey);
            if (supplier != this) {
                // something changed while we were waiting:
                // might be that we were replaced by a CacheValue
                // or were removed because of failure ->
                // return null to signal WeakCache.get() to retry
                // the loop
                return null;
            }
            // else still us (supplier == this)

            // create new value
            V value = null;
            try {
                //生成class对象
                value = Objects.requireNonNull(valueFactory.apply(key, parameter));
            } finally {
                if (value == null) { // remove us on failure
                    valuesMap.remove(subKey, this);
                }
            }
            // the only path to reach here is with non-null value
            assert value != null;

            // wrap value with CacheValue (WeakReference)
            CacheValue cacheValue = new CacheValue<>(value);

            // put into reverseMap
            reverseMap.put(cacheValue, Boolean.TRUE);

            // try replacing us with CacheValue (this should always succeed)
            if (!valuesMap.replace(subKey, this, cacheValue)) {
                throw new AssertionError("Should not reach here");
            }

            // successfully replaced us with new CacheValue -> return the value
            // wrapped by it
            return value;
        }
    }
private static final class ProxyClassFactory
        implements BiFunction[], Class>
    {
        // prefix for all proxy class names
        private static final String proxyClassNamePrefix = "$Proxy";

        // next number to use for generation of unique proxy class names
        private static final AtomicLong nextUniqueNumber = new AtomicLong();

        @Override
        public Class apply(ClassLoader loader, Class[] interfaces) {

            Map, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            for (Class intf : interfaces) {
                /*
                 * 获取接口类
                 */
                Class interfaceClass = null;
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
                /*
                 * Verify that the Class object actually represents an
                 * interface.
                 */
                if (!interfaceClass.isInterface()) {
                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }
                /*
                 * Verify that this interface is not a duplicate.
                 */
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                    throw new IllegalArgumentException(
                        "repeated interface: " + interfaceClass.getName());
                }
            }

            String proxyPkg = null;     // package to define proxy class in
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

            /*
             * Record the package of a non-public proxy interface so that the
             * proxy class will be defined in the same package.  Verify that
             * all non-public proxy interfaces are in the same package.
             */
            for (Class intf : interfaces) {
                int flags = intf.getModifiers();
                if (!Modifier.isPublic(flags)) {
                    accessFlags = Modifier.FINAL;
                    String name = intf.getName();
                    int n = name.lastIndexOf('.');
                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
                    if (proxyPkg == null) {
                        proxyPkg = pkg;
                    } else if (!pkg.equals(proxyPkg)) {
                        throw new IllegalArgumentException(
                            "non-public interfaces from different packages");
                    }
                }
            }

            if (proxyPkg == null) {
                // if no non-public proxy interfaces, use com.sun.proxy package
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }

            /*
             * Choose a name for the proxy class to generate.
             */
            long num = nextUniqueNumber.getAndIncrement();
            String proxyName = proxyPkg + proxyClassNamePrefix + num;

            /*
             * 生成代理类字节码
             */
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                //加载字节码为class对象
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                /*
                 * A ClassFormatError here means that (barring bugs in the
                 * proxy class generation code) there was some other
                 * invalid aspect of the arguments supplied to the proxy
                 * class creation (such as virtual machine limitations
                 * exceeded).
                 */
                throw new IllegalArgumentException(e.toString());
            }
        }
    }
public static byte[] generateProxyClass(final String var0, Class[] var1, int var2) {
        ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
        final byte[] var4 = var3.generateClassFile();
        //是否生成代理类class,默认不生成,可以通过设置 System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");修改
        if (saveGeneratedFiles) {
            //默认路径ReflectUtil.PROXY_PACKAGE + "."+ proxyPkg + proxyClassNamePrefix + nextUniqueNumber.getAndIncrement();
            //com.sun.proxy+"."+""+$proxy+自增数
            AccessController.doPrivileged(new PrivilegedAction() {
                public Void run() {
                    try {
                        int var1 = var0.lastIndexOf(46);
                        Path var2;
                        if (var1 > 0) {
                            Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
                            Files.createDirectories(var3);
                            var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                        } else {
                            var2 = Paths.get(var0 + ".class");
                        }

                        Files.write(var2, var4, new OpenOption[0]);
                        return null;
                    } catch (IOException var4x) {
                        throw new InternalError("I/O exception saving generated file: " + var4x);
                    }
                }
            });
        }

        return var4;
    }

JDK动态代理

/**
* 获取代理对象,this表示JdkDynamicAopProxy的实现类
**/
@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
		}
        //查找需要增强的接口类
		Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        //过滤equals和hashCode方法
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        //创建代理类
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}
@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		Object oldProxy = null;
		boolean setProxyContext = false;
        //获取需要增强的对象信息,包装于advise的TargetSouce中
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
            //如果是equals方法,直接执行
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
             //如果是hashCode方法,直接执行
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
        
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// 委派给代理执行
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;
            //是否需要开放内部代理功能,内部this.method是不会增强的,可以开启此处,之后通过AopContext.currentProxy()获取增强类,之后this.调用本类方法也可以进行增强    
			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}
            //获取需要增强的类
			target = targetSource.getTarget();
			Class targetClass = (target != null ? target.getClass() : null);

			// 获取增强调用链
			List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// 如果调用链为空,直接反射调用原始类方法
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// 创建爱你调用链增强类
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// 执行增强方法,获取返回值
				retVal = invocation.proceed();
			}
			Class returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
					returnType != Object.class && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}
			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
				throw new AopInvocationException(
						"Null return value from advice does not match primitive return type for: " + method);
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

 

你可能感兴趣的:(java项目技术所遇问题总结)