代理模式-动态代理
程序员文章站
2024-01-01 11:38:58
...
最近在学习代理模式,看了风中叶老师的视频后,有进一步的了解。
下面,我也来说说这个代理模式,也不不明白的地方。欢迎指教:
首先要了解java设计模式中,代理模式是怎样一个概念。代理模式就是为其他对象提供一种代理以达到控制对这个对象的访问。
代理模式中,有三种角色:
抽象角色:声明真实对象和代理对象的共同接口
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
举个例子:你有一套二手房想出手,但是你不会亲自找买房人,所以你会选择一间中介,于是中介就会代替你卖出二手房。于是,买家找到中介买房,中介手上没房子的,他只是代替卖家把房子卖给买家。
下面的代码,详细说明了代理过程的实现。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Vector;
/**
* 抽象角色:声明真实对象和代理对象的共同接口
* 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。
同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
* 真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
*
* 代理类一定要实现了InvocationHandler接口
*/
@SuppressWarnings("unchecked")
public class ProxyObject implements InvocationHandler {
//对真实角色的引用
private Object proxy_obj;
ProxyObject(Object obj){
this.proxy_obj = obj;
}
public static Object factory(Object obj){
//返回对象的类型
Class cls = obj.getClass();
/**
* newProxyInstance(...)方法返回代理类的一个实例,返回后的代理类可以当作被代理类使用
* 在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。
* 这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作
*/
return Proxy.newProxyInstance(cls.getClassLoader()/*类加载器?具体作用是?*/, cls.getInterfaces(),new ProxyObject(obj));
}
public void pre () {
System.out.println("函数调用前需要做的事情");
}
public void post () {
System.out.println("函数调用后需要做的事情");
}
/**
*实现InvocationHandler接口的invoke
*第一个参数obj是指代理类(一般用不上),method是被代理的方法,args为该方法的参数数组。 这个抽象方法在代理类中动态实现
*/
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
pre();
if(args != null){
System.out.println("方法有 " + args.length + " 个参数");
for(int i = 0; i < args.length; i ++){
System.out.println(args[i]);
}
}
//利用反射机制动态调用原对象的方法
Object mo = method.invoke(proxy_obj, args);
post ();
return mo;
}
/**
* 抽象主题角色 抽象主题角色的实例 = (抽象主题角色)factory(new 真实主题角色());
* @param agr
*/
public static void main(String agr[]){
List<String> list = (List<String>) factory(new Vector<String>(10));
list.add("mysupa.com");
list.add("超级经纪人网");
System.out.println(list);
}
}
动态代理步骤:(风中叶老师整理)
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
2.创建被代理的类以及接口
3.通过Proxy的静态方法
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个代理
4.通过代理调用方法
欢迎讨论!!