1.什么是代理模式?
代理模式就是为其他对象提供一种代理,以控制对这个对象的访问。例如我们在购买火车票的时候,在有些地方有火车票的代售点,这些代售点可以帮助火车站来实行购票的功能,像这种模式就是代理模式。在Java中,代理模式启动中介的作用,可以去掉功能服务或者增加额外的服务。
2.代码模式的分类
A、远程代理:为不同地理的对象提供局域网代表对象,相似于客户端和服务器一样的模式。
B、虚拟代理:根据需要将资源消耗很大的对象进行延迟,真正需要的时候进行创建。例如,在我们浏览网页的时候,有时候需要加载很大的图片,在图片为加载成功之前,我们可以使用一张临时的图片来暂时的显示。
C、保护代理:就是控制一个对象的访问权限。例如,我们在浏览帖子的时候的时候,当我们还没有注册时候,只能进行浏览的功能,当我们注册过后就可以进行发帖的功能。
D、智能引用代理:就是给目标对象提供额外的服务。相当于就是给代理增加了一些功能或者服务。
3.代理模式的实现方式
主要有两种实现方式:一是静态代理,二是动态代理
A、静态代理:
代理和被代理对象在代理之前是确定的。他们都实现了相同的接口或者继承了相同的抽象类。
通过继承来实现代理模式:
public interface MoveAble {
public void move();
}
package com.example.DesignPattern.ProxyPattern;
import java.util.Random;
public class Car implements MoveAble{
@Override
public void move() {
try {
System.out.println("汽车行驶中...");
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.DesignPattern.ProxyPattern;
public class Car1 extends Car {
@Override
public void move() {
long startTime = System.currentTimeMillis();
System.out.println("汽车开始行驶...");
super.move();
long endTime = System.currentTimeMillis();
System.out.println("汽车结束行驶..行驶时间:" + (endTime - startTime) + "毫秒");
}
}
通过聚合的方式来实现代理模式:
package com.example.DesignPattern.ProxyPattern;
public class Car2 implements MoveAble{
private Car mCar = null;
public Car2(Car car)
{
mCar = car;
}
@Override
public void move() {
long startTime = System.currentTimeMillis();
System.out.println("汽车开始行驶...");
mCar.move();
long endTime = System.currentTimeMillis();
System.out.println("汽车结束行驶..行驶时间:" + (endTime - startTime) + "毫秒");
}
}
B.使用JDK动态代理:
package com.example.DesignPattern.AgentPattern;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TimeHandler implements InvocationHandler{
private Object target = null;
public TimeHandler(Object target)
{
this.target = target;
}
/**
* proxy:被代理的对象
* method:被代理对象的方法
* args:代理方法的对象
*
* 返回值:代理的方法的返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(target);
return null;
}
}
package com.example.DesignPattern.AgentPattern;
import java.lang.reflect.Proxy;
import com.example.DesignPattern.ProxyPattern.Car;
import com.example.DesignPattern.ProxyPattern.MoveAble;
public class Test {
public static void main(String[] args) {
Car car = new Car();
TimeHandler handler = new TimeHandler(car);
Class<?> cls = car.getClass();
/**
* 第一个参数:被代理类的类加载器
* 第二个参数:被代理类实现接口
* 第三个参数:InvocationHandler对象,需要我们手动创建一个子类,来实现功能
*/
MoveAble m = (MoveAble) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), handler);
m.move();
}
}
JDK动态代理的实现步骤:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
2.创建被代理的类以及接口
3.调用Proxy的静态方法,创建一个代理类:newProxyInstance(ClassLoader load, Class []intefeaces, InvolcationHandler h);
4.通过代理调用方法