动态代理源码分析
Proxy.newProxyInstance实现
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException{//检验h不为空,h为空抛异常Objects.requireNonNull(h);//接口的类对象拷贝一份final Class<?>[] intfs = interfaces.clone();//进行一些安全性检查final SecurityManager sm = System.getSecurityManager();if (sm != null) {checkProxyAccess(Reflection.getCallerClass(), loader, intfs);}/** Look up or generate the designated proxy class.* 查询(在缓存中已经有)或生成指定的代理类的class对象。*/Class<?> cl = getProxyClass0(loader, intfs);/** Invoke its constructor with the designated invocation handler.*/try {if (sm != null) {checkNewProxyPermission(Reflection.getCallerClass(), cl);}//得到代理类对象的构造函数,这个构造函数的参数由constructorParams指定//参数constructorParames为常量值://private static final Class<?>[] constructorParams =//{ InvocationHandler.class };final Constructor<?> cons = cl.getConstructor(constructorParams);final InvocationHandler ih = h;if (!Modifier.isPublic(cl.getModifiers())) {AccessController.doPrivileged(new PrivilegedAction<Void>() {public Void run() {cons.setAccessible(true);return null;}});}//这里生成代理对象,传入的参数new Object[]{h}后面讲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);}}
getProxyClass0实现
//此方法也是Proxy类下的方法private static Class<?> getProxyClass0(ClassLoader loader,Class<?>... interfaces) {if (interfaces.length > 65535) {throw new IllegalArgumentException("interface limit exceeded");}// If the proxy class defined by the given loader implementing// the given interfaces exists, this will simply return the cached copy;// otherwise, it will create the proxy class via the ProxyClassFactory//意思是:如果代理类被指定的类加载器loader定义了,并实现了给定的接口interfaces,//那么就返回缓存的代理类对象,否则使用ProxyClassFactory创建代理类。return proxyClassCache.get(loader, interfaces);}
proxyClassCache 实现
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
WeakCache 类的成员变量和构造方法
//K代表key的类型,P代表参数的类型,V代表value的类型。// WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache//说明proxyClassCache存的值是Class<?>对象,正是我们需要的代理类对象。final class WeakCache<K, P, V> {private final ReferenceQueue<K> refQueue= new ReferenceQueue<>();// the key type is Object for supporting null keyprivate final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map= new ConcurrentHashMap<>();private final ConcurrentMap<Supplier<V>, Boolean> reverseMap= new ConcurrentHashMap<>();private final BiFunction<K, P, ?> subKeyFactory;private final BiFunction<K, P, V> valueFactory;public WeakCache(BiFunction<K, P, ?> subKeyFactory,BiFunction<K, P, V> valueFactory) {this.subKeyFactory = Objects.requireNonNull(subKeyFactory);this.valueFactory = Objects.requireNonNull(valueFactory);}
proxyClassCache.get(loader, interfaces); 源码
//K和P就是WeakCache定义中的泛型,key是类加载器,parameter是接口类数组public V get(K key, P parameter) {//检查parameter不为空Objects.requireNonNull(parameter);//清除无效的缓存expungeStaleEntries();// cacheKey就是(key, sub-key) -> value里的一级key,Object cacheKey = CacheKey.valueOf(key, refQueue);// lazily install the 2nd level valuesMap for the particular cacheKey//根据一级key得到 ConcurrentMap<Object, Supplier<V>>对象。如果之前不存在,//则新建一个ConcurrentMap<Object, Supplier<V>>和cacheKey(一级key)一起放到map中。/*** reference 懒加载*/ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);if (valuesMap == null) {ConcurrentMap<Object, Supplier<V>> oldValuesMap= map.putIfAbsent(cacheKey,valuesMap = new ConcurrentHashMap<>());if (oldValuesMap != null) {valuesMap = oldValuesMap;}}// create subKey and retrieve the possible Supplier<V> stored by that// subKey from valuesMap//这部分就是调用生成sub-key的代码,上面我们已经看过怎么生成的了Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));//通过sub-key得到supplierSupplier<V> supplier = valuesMap.get(subKey);//supplier实际上就是这个factoryFactory factory = null;while (true) {//如果缓存里有supplier ,那就直接通过get方法,得到代理类对象,返回,就结束了,//一会儿分析get方法。if (supplier != null) {// supplier might be a Factory or a CacheValue<V> instanceV 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//下面的所有代码目的就是:如果缓存中没有supplier,//则创建一个Factory对象,把factory对象在多线程的环境下安全的赋给supplier。//因为是在while(true)中,赋值成功后又回到上面去调get方法,返回才结束。if (factory == null) {factory = new Factory(key, parameter, subKey, valuesMap);}if (supplier == null) {supplier = valuesMap.putIfAbsent(subKey, factory);if (supplier == null) {// successfully installed Factorysupplier = factory;}// else retry with winning supplier} else {if (valuesMap.replace(subKey, supplier, factory)) {// successfully replaced// cleared CacheEntry / unsuccessful Factory// with our Factorysupplier = factory;} else {// retry with current suppliersupplier = valuesMap.get(subKey);}}}}
Factory类中的get方法
public synchronized V get() { // serialize access// re-checkSupplier<V> supplier = valuesMap.get(subKey);//重新检查得到的supplier是不是当前对象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 loopreturn null;}// else still us (supplier == this)// create new valueV value = null;try {//代理类就是在这个位置调用valueFactory生成的//valueFactory就是我们传入的 new ProxyClassFactory()//一会我们分析ProxyClassFactory()的apply方法value = Objects.requireNonNull(valueFactory.apply(key, parameter));} finally {if (value == null) { // remove us on failurevaluesMap.remove(subKey, this);}}// the only path to reach here is with non-null valueassert value != null;// wrap value with CacheValue (WeakReference)//把value包装成弱引用CacheValue<V> cacheValue = new CacheValue<>(value);// put into reverseMap// 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 itreturn value;}}
ProxyClassFactory
//这里的BiFunction<T, U, R>是个函数式接口,可以理解为用T,U两种类型做参数,得到R类型的返回值private static final class ProxyClassFactoryimplements BiFunction<ClassLoader, Class<?>[], Class<?>>{// prefix for all proxy class namesprivate static final String proxyClassNamePrefix = "$Proxy";// next number to use for generation of unique proxy class namesprivate static final AtomicLong nextUniqueNumber = new AtomicLong();@Overridepublic Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);for (Class<?> intf : interfaces) {/** Verify that the class loader resolves the name of this* interface to the same Class object.*/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 inint 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 packageproxyPkg = ReflectUtil.PROXY_PACKAGE + ".";}/** Choose a name for the proxy class to generate.*/long num = nextUniqueNumber.getAndIncrement();String proxyName = proxyPkg + proxyClassNamePrefix + num;/** Generate the specified proxy class.*/byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);try {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());}}}
得到动态代理字节码
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
public class DynamicProxyTest {public static void main(String[] args) {//动态代理使用代码见掘金String path = "D:/$Proxy0.class";byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", ServiceImpl.class.getInterfaces());FileOutputStream out = null;try {out = new FileOutputStream(path);out.write(classFile);out.flush();} catch (Exception e) {e.printStackTrace();} finally {try {out.close();} catch (IOException e) {e.printStackTrace();}}}}
JDK动态代理和CGLIB字节码生成的区别
- JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
- CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,对于final类或方法,是无法继承的。
CGLIB示例代码
public class CGLibProxy implements MethodInterceptor {/** CGLib需要代理的目标对象 */private Object targetObject;public Object createProxyObject(Object obj) {this.targetObject = obj;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(obj.getClass());enhancer.setCallback(this);Object proxyObj = enhancer.create();// 返回代理对象return proxyObj;}@Overridepublic Object intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {Object obj = null;// 过滤方法if ("addUser".equals(method.getName())) {// 检查权限checkPopedom();}obj = method.invoke(targetObject, args);return obj;}private void checkPopedom() {System.out.println("======检查权限checkPopedom()======");}}
客户端测试类
public class Client {public static void main(String[] args) {System.out.println("**********************CGLibProxy**********************");CGLibProxy cgLibProxy = new CGLibProxy();IUserManager userManager = (IUserManager) cgLibProxy.createProxyObject(new UserManagerImpl());//执行的是增强的add方法userManager.addUser("jpeony", "123456");}
