代理是java中的一种设计模式,主要用于提供对目标对象另外的访问方式,即通过代理对象访问目标对象。这样,就可以在目标对象实现的基础上,加强额外的功能操作,实现扩展目标对象的功能。
代理模式的关键点在于代理对象和目标对象,代理对象是对目标对象的扩展,并且代理对象会调用目标对象。
java的代理方式有3种:静态代理,动态代理,CGlib搭理。
静态搭理:
在静态代理中,代理类和被代理类实现同意的接口,代理类同时持有代理类的引用。当我们需要调用被代理类的方法时,可以通过代理类的方法实现。
public interface Person {
//租房
public void rentHouse();
}
public class Renter implements Person{
@Override
public void rentHouse() {
System.out.println("租客租房成功!");
}
}
public class StaticProxyTest {
public static void main(String[] args) {
Person renter = new Renter();
RenterProxy proxy = new RenterProxy(renter);
proxy.rentHouse();
}
}
动态代理:
java中的动态意味着使用了反射,因此动态代理其实是基于反射的一种代理模式。
动态代理可以实现多个需求。动态代理其实是通过实现接口的方式来实现代理,具体来说,动态代理是通过Proxy类创建代理对象,然后将接口方法“代理”给InvocationHandler接口完成的。
Proxy类:
java提供了java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类,这个两个类相互配合,其中Proxy类是入口。Proxy类用来创建一个代理类,提供了很多方法:
public static InvocationHandler getInvocationHandler(Object proxy);该方法主要用于获取指定代理对象所关联的调用程序。
static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces);主要用来返回指定接口的代理类。
static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);返回主要返回一个指定接口的代理实例,该接口可以将方法调用指派到指定的调用处理程序。
static boolean isProxyClass(Class<?> cl);当指定的类通过getProxyClass方法或newProxyInstance方法动态生成为代理类时,返回true。该方法的可靠性对于使用它做出安全决策而言非常重要,所以他的实现不应因测试相关类是否可以扩展Proxy.
static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);
loader:指定类加载器
interfaces:代理类需要实现的接口列表表示用户将要给代理对象提供的接口信息。如果提供了这样一个接口数组,就是声明代理类实现了这些接口,代理类接口调用接口中声明的所有方法;
h:指派方法调用的调用处理程序,是一个InvocationHandler对象,表示当动态代理对象调用方法时会关联哪一个InvocationHandler对上,并最终由其调用。
InvocationHandler接口的invoke(Object proxy, Method method, Object[] args);
proxy:调用方法的代理实例