(菜鸟理解,大牛勿喷啊~)通俗地说就是,程序运行时被构造出来的代理对象,用一次(无论是实现接口的还是继承自Object的)方法,就要调用一次处理器的invoke方法,然后再然后使用另外invoke方法使用被代理的类的方法(这里使用到了反射的invoke方法),个人觉得invoke为代理类要使用方法的调用器。
说起来太tm抽象了,下面用关键词详细说下。
作用:可以在程序运行时创建一个以一组接口为条件的类,有时在代码中有一个表示接口的class类,要想得到一个实现了这个类的 接口要嘛反射构造函数或者使用newinstance,但是对于接口是不可以实例化的啊!所以就用代理类实现这个接口!
代理涉及的新类/接口:
1.InvocationHandler接口:因为我们知道类实现接口的方法需要写出实际的代码,但是代理不行,这里就要用到InvocationHandler接口,实现了这个接口的类叫做调用处理器,处理器有个构造函数相当于就是在创建实现接口的代理类之前初始化一些值,接口中只有一个方法,Object invoke(Object proxy, Method method, Object[] args),将来代理类无论使用任何自己的方法,都会使用这个接口的方法来调用想要使用的代理类的方法,当然这个处理器的处理调用方式自己定义(根据你要使用代理的目的而定),下面例子中,InvocationHandler接口的方法invoke中有反射的invoke方法,其中接口的invoke方法有三个(proxy为代理的对象,m为代理对象运行时需要使用的方法,args【】。
2.Proxy类:这个类的作用是就是创建代理类了,它有个方法叫newProxyInstance方法用于创建代理类,需要三个参数创建代理类,一。类加载器,使用null表示默认,二。需要实现的接口的class对象数组,其中每个元素就是一个需要实现的接口,三。之前准备好的处理器(事项InvocationHandler接口)。
贴一段java核心技术代码为例作为读书笔记:
public class ProxyTest
{
public static void main(String[] args)
{
Object[] elements = new Object[1000];//用于存放1000个Comparable接口的Integer代理对象
// 填充进去
for (int i = 0; i < elements.length; i++)
{
Integer value = i + 1;
InvocationHandler handler = new TraceHandler(value);
Object proxy = Proxy.newProxyInstance(null, new Class[] { Comparable.class } , handler);
elements[i] = proxy;
}
// construct a random integer
Integer key = new Random().nextInt(elements.length) + 1;
// 会用上compareTo方法
int result = Arrays.binarySearch(elements, key);
//会用上toString方法
if (result >= 0) System.out.println(elements[result]);
}
}
/**
* An invocation handler that prints out the method name and parameters, then
* invokes the original method
*/
class TraceHandler implements InvocationHandler
{
/**
* Constructs a TraceHandler
* @param t the implicit parameter of the method call
*/
public TraceHandler(Object t)
{
target = t;//目标对象,还没有实现接口,没有代理完成
}
</pre><pre name="code" class="java">//这个方法要在使用代理对象的方法的时候才会调用它,再用它调用想要使用的代理对象的方法
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
{
// print implicit argument
System.out.print(target);
// print method name
System.out.print("." + m.getName() + "(");
// print explicit arguments
if (args != null)
{
for (int i = 0; i < args.length; i++)
{
System.out.print(args[i]);
if (i < args.length - 1) System.out.print(", ");
}
}
System.out.println(")");
// invoke actual method
return m.invoke(target, args);
}
private Object target;
}