1、定义:为其他对象提供一种代理,以控制对这个对象的访问,代理对象相当于一个中介,可去掉功能服务或增加额外服务。就像火车票代售点一样,可以代替火车站买票,用户可以通过代理店访问火车站的窗口的卖票功能,可能还会提供一些电话购票的额外功能,但是也去掉了退票服务。
2、常见的几种代理模式:
(1)远程代理:为不同地理的对象提供局域网代表对象;(也就是通过网络实现远程控制)
(2)虚拟代理:根据需要将资源消耗很大的对象进行延迟,在真正需要的时候进行创建;(对照浏览器的无图模式)
(3)保护代理:控制对一个对象的访问权限;
(4)智能引用代理:提供对目标对象额外服务。
3、常用的代理模式原理:
(1)用两种方式实现智能引用代理:
<1>静态代理:代理和被代理对象在代理之前是确定的,他们都实现相同的接口或者继承相同的抽象类。可以通过继承和聚合两种方式来实现静态代理:继承简而言之就是通过类的叠加继承来实现多个功能,一个类实现部分功能,如果类有新的功能,就把新类继承原有的类,在心累中添加功能,但是在功能多的情况下继承不好用;聚合就是根据不同的功能分配不同的类,每个类都是接口的对等实例,然后各自负责各自的功能,在其构造方法中,提供了含参构造,传入的是实例,这样可以把多种功能联系起来。比如接口I,有三个功能ab,如果用继承的方式,就是新建一个类A用于实现a功能,再新建一个B继承A,在B中添加b方法;聚合的方式就是建两个类都实现自接口I,分别实现ab两个功能,先实例化一个A类的对象,再把这个对象作为参数传给B的对象,这样就实现了ab。可以看到聚合虽然也是两个类但是却很灵活,不用建立那么多继承关系。
继承:
public class Car2 extends Car {
@Override
public void move() {
long startTime = System.currentTimeMillis();
System.out.println("汽车开始行使");
super.move();
long endTime = System.currentTimeMillis();
System.out.println("汽车结束行使 ,共行驶" + (endTime - startTime) + "毫秒");
}
}
聚合:
public class Car3 implements Moveable {
public Car3(Car car) {
super();
this.car = car;
}
private Car car;
@Override
public void move() {
long startTime = System.currentTimeMillis();
System.out.println("汽车开始行使");
car.move();
long endTime = System.currentTimeMillis();
System.out.println("汽车结束行使 ,共行驶" + (endTime - startTime) + "毫秒");
}
}
在类的个数过多的时候,静态代理是不适用的,这时候引入了动态代理:
<2>动态代理:动态产生代理,实现对不同类,不同方法的代理。
要求被代理对象首先要实现某些接口;
所谓Dynamic Proxy是这样一种class:
1)它是在运行时生成的class
2)该class需要实现一组interface
3)使用动态代理类时,必须实现InvocationHandler接口
java动态代理类,位于java.lang.reflect包下,一般涉及两个类:
(1)Interface InvocationHandler:该接口中仅定义了一个方法public object invoke(Object obj,Method method,Object[] args):实际使用中,obj指被代理类的对象,method指被代理的方法,args为该方法参数数组。这个抽象方法在代理类中动态实现。实现该接口即为代理的事务处理器。
(2)Proxy:该类即为动态代理类:
static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h):返回代理类的一个实例,返回后的代理类可以被当作代理类使用(可使用被代理类的在接口中声明过的方法)。第一个参数loader为被代理类的加载器,通过被代理类.getClass().getClassLoader()得到
· 第二个参数interfaces为被代理类实现的所有接口,同样通过getClass().getInterfaces()得到
· 第三个参数handler就是自己实现的InvocationHandler的实现类的对象
动态代理实现步骤:
1)创建一个实现接口InvocationHandler的类(即事物处理器),它必须实现invoke方法(在该方法中添加具体的业务逻辑)
2)创建被代理的类以及接口(比如Car、Moveable)
3)调用Proxy的静态方法,创建一个代理类newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
4)通过代理调用方法