---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
动态代理类是一个实现在创建类时在运行时指定的接口列表的类,
该类具有下面描述的行为。 代理接口 是代理类实现的一个接口。
代理实例 是代理类的一个实例。
每个代理实例都有一个关联的调用处理程序 对象,
它可以实现接口 InvocationHandler。
通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,
并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。
调用处理程序以适当的方式处理编码的方法调用,
并且它返回的结果将作为代理实例上方法调用的结果返回
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类
publicclass ProxyDemo1
{
publicstaticvoid main(String[] args)
{
//创建一个collection类的动态代理类
Class clazzproxy = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);
//输出这个动态代理类的名字
System.out.println(clazzproxy.getName().toString());
//获得这个动态代理类的所有构造方法
getInstances(clazzproxy);
//分界,上面是构造方法下面是方法
System.out.println("=============================================================");
//获得这个动态代理类的所有方法
getMethods(clazzproxy);
}
下面是getInstance方法,获得动态代理类的所有构造方法
publicstaticvoid getInstances(Class clazzproxy)
{
//获得构造方法的数组
Constructor[] constructors = clazzproxy.getConstructors();
//遍历构造方法数组,并输出每个构造方法的参数类型
for(Constructor c : constructors)
{
String name = c.getName();
StringBuilder sb = new StringBuilder();
sb.append(name+"(");
//获得构造方法的参数类型的Class数组
Class[] clazzparams = c.getParameterTypes();
//遍历参数类型数组,并把参数一个一个的加入sb中
for(Class param : clazzparams)
{
sb.append(param.getName().toString()+",");
}
//如果参数数组为空,就把()中加入一个逗号,便于统一删除最后一个逗号
if(clazzparams.length==0)
sb.append(",");
//删除最后一个参数后面的多余的逗号
sb.deleteCharAt(sb.length()-1);
sb.append(")");
System.out.println(sb.toString());
}
}
getMethod获得动态代理类的所有方法
根据获得动态代理类的构造方法的原理获得动态代理类的所有方法
publicstaticvoid getMethods(Class clazzproxy)
{
Method[] methods = clazzproxy.getMethods();
for(Method m : methods)
{
String name = m.getName();
StringBuilder sb = new StringBuilder();
sb.append(name+"(");
Class[] clazzparams = m.getParameterTypes();
for(Class param : clazzparams)
{
sb.append(param.getName().toString()+",");
}
if(clazzparams.length==0)
sb.append(",");
sb.deleteCharAt(sb.length()-1);
sb.append(")");
System.out.println(sb.toString());
}
}
InvocationHandler 类:
代理实例的调用处理程序 实现的接口。
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,
将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法
总结创建动态类的实例对象的步骤:
1、创建一个collection类的动态代理类
例:Class clazzproxy = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);
2、利用反射获得动态代理类的构造方法,构造方法中参数类型为InvocationHandler
Constructor constructor = clazzproxy.getConstructor(InvocationHandler.class);
3、利用反射创建实现动态代理的Collection类
Collection coll = (Collection) constructor.newInstance(new MyInvocationHandler());
简单方法创建动态类的实例对象
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class },handler);
publicclass ProxyDemo2
{
publicstaticvoid main(String[] args) throws Exception
{
//创建一个collection类的动态代理类
Class clazzproxy = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);
//输出这个动态代理类的名字
System.out.println(clazzproxy.getName().toString());
//获得动态代理类的构造方法,利用反射
Constructor constructor = clazzproxy.getConstructor(InvocationHandler.class);
class MyInvocationHandler implements InvocationHandler
{
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable
{
returnnull;
}
}
//利用反射创建实现动态代理的Collection类,使用自己的MyInvocationHandler方法
Collection proxy1 = (Collection) constructor.newInstance(new MyInvocationHandler());
System.out.println(proxy1);
//利用反射创建实现动态代理的Collection类,使用自带的InvocationHandler方法
Collection proxy2 = (Collection) constructor.newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
returnnull;
}
});
//利用反射创建实现动态代理的Collection类,直接用Proxy的构造方法
Collection proxy3 = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
new Class[]{ Collection.class},
new InvocationHandler()
{
ArrayList arr = new ArrayList();
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable
{
long begintime = System.currentTimeMillis();
Object value = method.invoke(arr, args);
long endtime = System.currentTimeMillis();
System.out.println(method.getName()+"运行时间:"+(endtime-begintime));
return value;
}
}
);
proxy3.add("111");
proxy3.add("222");
proxy3.add("333");
System.out.println(proxy3.size());
}
}
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------