dubbo Proxy类

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>();

			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();
			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;
	}

 

(1)遍历所有入参接口,以;作为分隔符连接起来,以这个串作为key,从缓存中查找,如果有,说明代理对象已创建成功。

(2)利用AtomicLong对象自动获取一个long数组来作为生产类的后缀,防止冲突。

(3)遍历接口获取所有定义的方法,获取方法的参数类型和返回类型,构建方法体return ret=handler.invoke(this.methods[ix],args);这里的方法调用其实是委托给InvokerInvocationHandler实例对象的,去调用真正的实例。

(4)创建代理实现对象ProxyInstance

类名为:pkg+".proxy"+id=包名+”.proxy“+自增数值。

添加静态字段,添加实例对象,添加无参构造函数。

(5)利用ClassGenerator生成对应的字节码。

 

最后欢迎大家访问我的个人网站:1024s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值