https://www.jianshu.com/p/cbd58642fc08
代理模式分为静态代理和动态代理。
静态代理:
1、作用:通过代理对象间接访问目标对象。
2、解决的问题:(1)、不想直接访问目标对象
(2)、无法直接访问目标对象
3、三个角色:(1)、抽象对象接口;(2)、真实对象(委托类、被代理对象); (3)、代理对象(内部含有真实对象的引用)
4、Demo:
public interface Sell {
void sell();
}
public class Sellor implements Sell {
@Override
public void sell() {
Log.d("TAG","十元一个");
}
}
public class Agent implements Sell {
private Sellor sellor;
private int sellNum;
public Agent(Sellor sellor) {
this.sellor = sellor;
}
@Override
public void sell() {
if (sellNum > 1000) {// 如果卖出1000个后,再按照10元1个的单价卖
sellor.sell();
}
}
}
这样就可以只改变代理类就能够控制想要的结果了,而不需要每次都改动真实类。
动态代理:和静态代理相比,动态代理是在程序运行时创建的代理方式。相比于静态代理,动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。
1、解决的问题:统一的处理代理类的函数,而不是修改每一个代理类。
2、四个角色:(1)、抽象的对象接口;(1)、抽象对象接口;(2)、真实对象(委 托类、被代理对象); (3)、代理对象;(4)、中介对象(实现InvocationHandler)
3、API:
InvocationHandler
public interface InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args);
}
当我们调用代理类对象的方法时,这个“调用”会转送到invoke方法中,代理类对象作为proxy参数传入,参数method标识了我们具体调用的是代理类的哪个方法,args为这个方法的参数。这样一来,我们对代理类中的所有方法的调用都会变为对invoke的调用,这样我们可以在invoke方法中添加统一的处理逻辑(也可以根据method参数对不同的代理类方法做不同的处理)。
newProxyInstance
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
方法的三个参数含义分别如下:
loader:定义了代理类的ClassLoder;
interfaces:代理类实现的接口列表
h:调用处理器,也就是实现了InvocationHandler接口的类实例
4、Demo:
public interface Sell { void sell(); void ad();}
public class Vendor implements Sell {
public void sell() {
System.out.println("In sell method");
}
public void ad() {
System.out.println("In ad method")
}
}
public class DynamicProxy implements InvocationHandler {
private Object obj; //obj为委托类对象
public DynamicProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = method.invoke(obj, args);
System.out.println("after");
return result;
}
}
public class Main { public static void main(String[] args) {
DynamicProxy inter = new DynamicProxy(new Vendor());
//加上这句将会产生一个$Proxy0.class文件,这个文件即为动态生成的代理类文件
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
//获取代理类实例sell
Sell sell = (Sell)(Proxy.newProxyInstance(Sell.class.getClassLoader(), new Class[] {Sell.class}, inter));
sell.sell();
sell.ad();
}
}
网友评论