主要是解决直接访问对象的问题,如果直接访问对象可能会给系统结构带来很多问题
开放封闭原则(OCP,Open Closed Principle)软件实体应该是可扩展,而不可修改的。也就是说,一个软件实体应当对扩展是开放的,而对修改是封闭的。
1.静态代理
定义接口
public interface Animal {
void eat();
}
定义两个类被代理的类
public class Panda implements Animal {
@Override
public void eat() {
System.out.println("吃竹子");
}
}
public class Tiger implements Animal {
@Override
public void eat() {
System.out.println("吃肉");
}
}
调用代理类
public class Demo {
public static void main(String[] args) {
Animal animal = new Tiger();
animal.eat();
}
}
这样接口就可以按照使用场景进行划分,问题也出现了,这个代理只能为一个类服务,多个就要写很多代理类
这里有点像java中的多态 多态存在的三个必要条件1继承2重写3父类引用指向子类对象。3父类引用指向子类,忙猜多态是针对对象的,而代理是针对接口的
2.动态代理
对象的执行方法,交给代理来负责。比如user.get() 方法,是User对象亲自去执行。而使用代理则是由proxy去执行get方法。
InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口每一个proxy代理实例都有一个关联的调用处理程序,成对出现
public class DynamicHandler implements InvocationHandler {
Object animal;
public DynamicHandler(Object animal) {
this.animal = animal;
}
/**
* proxy:代理类代理的真实代理对象
* method:我们所要调用某个对象真实的方法的Method对象
* args:指代代理对象方法传递的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(animal, args);
return null;
}
}
Proxy类就是用来创建一个代理对象的类
public class Demo {
public static void main(String[] args) {
Animal animal = new Panda();
InvocationHandler handler = new DynamicHandler(animal);
Animal proxyHello = (Animal) Proxy.newProxyInstance(animal.getClass().getClassLoader(), animal.getClass().getInterfaces(), handler);
//Animal proxyHello = (Animal) Proxy.newProxyInstance(animal.getClass().getClassLoader(), new Class<?>[]{Animal.class}, handler);
proxyHello.eat();
}
}
loader:一个classloader对象,定义了由哪个classloader对象对生成的代理类进行加载
interfaces:一个interface对象数组,表示我们要提供给代理对象 一组 接口, 代理类就可以调用接口中声明的所有方法。
h: 一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个InvocationHandler对象上,并最终由其调用
可以在method.invoke(animal, args); 方法前后做一些控制。
有名的Retorfit 就是由动态代理做的点开 retrofit.create 就能看到 Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },new InvocationHandler() {});
如果内容有错误请及时联系我
网友评论