一,什么是代理
利用代理可以在运行时创建一个实现了一组给定接口的新类,这种只有编译时无法确定需要实现那个接口时才有必要使用
二,何时使用代理
有一个表示接口Class对象,它的准确类型编译时候无法知道,想要构造一个实现这些接口的类,想要构建一个实现这些接口的类,需要使用NewInstance或反射出这个类的构造器,但是,不能实例化一个接口,需要在程序处于运行时定义一个新类
代理类可以解决这个问题:运行的时候创建全新的类,能实现指定的接口,具有下列的方法
①指定接口锁需要的全部方法
②Object类中的全部方法
注:不能在运行的时候定义这些方法的代码,需要提供一个调用处理器,调用处理器实现了IncocationHandler接口的类对象,这个接口只有一个方法
Object Invoke(objetct proxy,Method method,Object[] args),无论何时调用代理器对象的方法,都会调用invoke方法,并向其传递method对象和原始的调用参数
三,创建代理对象和运用场景
创建一个代理对象,需要使用proxy类的newProxyInstance方法
①ClassLoader loader:指定当前目标对象使用类加载器,获取加载器的方法是固定的
②Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方式确认类型,获取接口类型的方法是固定的
③InvocationHandler h;事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
例子
public interface Hello {
void doSomething();
}
public class HelloImpl implements Hello {
@Override
public void doSomething() {
System.out.println("HelloImpl doSomething");
}
}
/**
* 代理类
*/
public class ProxyHandler implements InvocationHandler {
private Object proxyed;
public ProxyHandler(Object proxy) {
proxyed = proxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
System.out.println("proxy working");
return method.invoke(proxyed, args);
}
}
public static void main(String[] args) {
Hello hello = new HelloImpl();
Hello proxy = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(),
new Class[]{Hello.class}, new ProxyHandler(hello));
proxy.doSomething();
}
输出结果
proxy working
HelloImpl doSomething
运用1.
路由对远程方法的调用
运用2.
在程序运行区间,将用户接口事件与动作关联起来
运用3.
为调试,跟踪方法调用
运用4. spring aop