java动态代理:
java动态代理类位于java.lang.reflect包下,一般主要涉及两个类: 1.Interface InvocationHandler
该接口中仅定义了一个方法:Object invoke(Object proxy,Method method,Object[] args)
第一个参数obj一般是代理类,method是被代理的方法,如上例中的request(), args是该方法中的参数数组,无参是为null
这个抽象方法在代理类中动态实现。
2.Proxy
protected Proxy(InvocationHandler h): 构造函数,用于给内部的invocation handler赋值。
static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) : loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) :
返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类在Subject接口中声明过的方法)。
实例1:
定义一个接口
/*
* 抽象角色类
* 定义一个接口
*/
public interface Subject {
public void request();
}
定义真实角色类,实现接口
/*
* 真实角色类
*/
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("From real subject");
} }
定义动态代理类,实现InvocationHandler接口,重写invoke方法
/*
* 动态代理类,实现InvocationHandler接口,重写invoke方法
*/
public class DynamicSubject implements InvocationHandler { //对真实类的对象的引用
private Object sub;
public DynamicSubject(Object obj){
this.sub = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("Before calling " + method); //通过反射来调用方法
method.invoke(sub, args);
System.out.println("After calling " + method);
return null;
}
}
测试
public class Client { public static void main(String[] args) { //真实类对象
RealSubject realSubject = new RealSubject(); //通过 动态类对象 获取类型
InvocationHandler handle = new DynamicSubject(realSubject);
Class<?> classType = handle.getClass(); //生成代理
//动态生成一个类 实现了指定的接口 生成类的对象 转换成接口类型 handle是动态代理类的一个对象
Subject subject = (Subject)Proxy.newProxyInstance(classType.getClassLoader(),
realSubject.getClass().getInterfaces(), handle); subject.request(); System.out.println(subject.getClass());
}
}
通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。