代理模式,属于结构型模式。通俗点的说是在访问一个类的时候添加控制。
代理模式由2种:1.静态代理 2.动态代理
静态代理实现有可以通过 继承 和组合 的方式实现:
继承方式:
//场景:需要在汽车移动开始时候记录时间,移动结束时候记录时间
class Car {
public void move(){
System.out.println("the car: move");
}
}
//添加记录时间的代理
class CarProxy extends Car{
@Override
public void move(){
System.out.println("开始记录时间。。。");
super.move();
System.out.println("记录时间结束。。。");
}
}
//测试
public class Mytest {
public static void main(String[] args) {
CarProxy car=new CarProxy();
car.move();
}
}
组合的方式:
class Car {
public void move(){
System.out.println("the car: move");
}
}
class CarProxy{
private Car car;
public CarProxy(Car car){
this.car=car;
}
public void move(){
System.out.println("开始记录时间。。。");
car.move();
System.out.println("记录时间结束。。。");
}
}
public class Mytest {
public static void main(String[] args) {
Car car=new Car();
CarProxy c=new CarProxy(car);
c.move();
}
}
当然静态代理对简单的场景可以有较好的实现,但是对于稍微复杂,考虑到更多扩展性的时候,就需要动态代理。
实现动态代理创建代理类需要实现InvocationHandler接口。
public interface Vehicle {
public void move();
}
public class Car implements Vehicle{
public void move(){
System.out.println("车开了");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object targetObject;
public MyInvocationHandler(Object targetObject){
this.targetObject = targetObject;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("记录日志。。。。start");
Object result = method.invoke(this.targetObject, args);
System.out.println("记录日志。。。。end");
return result;
}
}
import java.lang.reflect.Proxy;
public class Test {
/**
* @param args
* @throws Throwable
*/
public static void main(String[] args) throws Throwable {
Vehicle car=new Car();
MyInvocationHandler mih=new MyInvocationHandler(car);
//通过Proxy的newProxyInstance方法来创建代理对象
//第一个参数,使用handler这个类的ClassLoader对象来加载代理对象
//第二个参数,为代理对象提供的接口是真实对象所实现的接口
//第三个参数,将这个代理对象关联到了实现 InvocationHandler接口的对象上
Vehicle vi=(Vehicle)Proxy.newProxyInstance(car.getClass().getClassLoader(),car.getClass().getInterfaces(),mih);
vi.move();
}
}