java代理模式 Java基础之让你彻底搞懂代理模式
猿华 人气:0想了解Java基础之让你彻底搞懂代理模式的相关内容吗,猿华在本文为您仔细讲解java代理模式的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:java代理模式,java静态代理,java动态代理,下面大家一起来学习吧。
一、代理模式
什么是代理模式?
先来生活常用例子:你想买票,你没必要去车站买;而是可以去一个代售点,代售点代理车站卖票,这就是一个简单的代理模式!
- 主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
- 总结:我们访问实例对象时是通过代理对象访问的,这样比较灵活也可以添加一些附加操作
二、静态代理
顾名思义,静态的,由程序员构写,在编译是就已经将程序接口,代理类和被代理类写定了!在程序运行前就已经生成!
来个简单实例:
设计公共接口Person:
public interface Person { public void handinWork(); }
Student:
public class Student implements Person { private String name; public Student(String name) { this.name=name; } public void setName(String name) { this.name = name; } public void handinWork() { System.out.println(name+"提交作业"); } }
代理类StudentProxy:
public class StudentProxy implements Person { //代理谁 Student student; //防止重名,确保只是代理Student这个对象 public StudentProxy(Student student) { if(student.getClass()==Student.class){ this.student = (Student) student; } } public void handinWork() { //交作业时代理(班长)想代替学生搞点事··· System.out.println("老师这个比的作业是抄的呢"); student.handinWork(); } }
测试:
public class StaticProxy { public static void main(String[] args) { //创建出两个对象,代理和被代理 Student student = new Student("张三"); StudentProxy monitor = new StudentProxy(student); //代理类去交作业!!!!! monitor.handinWork(); } }
可以发现,程序本质还是学生交作业,不过是通过一个中间层monitor(班长)去实现的,然后这个代理层还可以添加些其他的操作功能,在提交作业之前或者之后!
三、动态代理
静态代理是在程序运行前就生成了,很明显动态代理就是在程序运行期间添加代理层以达到效果。代理类动态生成!
- 需要了解两个类:Proxy 代理, InvocationHandler
- Proxy:代理类,使用的时候动态生成
- InvocationHandler:主要执行需要代理的方法,使用invoke执行
举个例子:方便理解,就上面那个实例我们将它改造成一个动态的!
第一步,创建一个类实现InvocationHandler接口,用它构建出代理类和代理方法:
public class ProxyInvocation implements InvocationHandler { //被代理的接口,真实的对象 private Person person; //生成得到的代理类 public void setPerson(Person person) { this.person = person; } //通过Proxy类的newProxyInstance方法创建代理对象,我们来看下方法中的参数 // * 第一个参数:people.getClass().getClassLoader(),使用handler对象的classloader对象来加载我们的代理对象 // * 第二个参数:people.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法 // * 第三个参数:handler,我们将代理对象关联到上面的InvocationHandler对象上 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),person.getClass().getInterfaces(),this); } //处理代理实例,返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(person, args); return result; } }
参照静态代理,需要一个代理对象,只不过静态代理中代理对象是我们手动创建的,所以动态代理中我们利用jdk自带代理类Proxy的newProxyInstance方法动态的生成了一个代理类而已,这个代理类可以根据我们传的参数动态改变,
测试:
//真实角色student Student student = new Student("张三"); //拿到InvocationHandler的继承类 ProxyInvocation pih = new ProxyInvocation(); //拿到代理的接口 pih.setPerson(student); //动态生成了proxy代理类 Person proxy = (Person) pih.getProxy(); //代理类执行方法 proxy.handinWork();
改进成工具类:将获得接口部分全部采用参数代替;
private Object target; //生成得到的代理类 public void setPerson(Object target) { this.target= target; } //通过Proxy类的newProxyInstance方法创建代理对象,我们来看下方法中的参数 // * 第一个参数:people.getClass().getClassLoader(),使用handler对象的classloader对象来加载我们的代理对象 // * 第二个参数:people.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法 // * 第三个参数:handler,我们将代理对象关联到上面的InvocationHandler对象上 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } //处理代理实例,返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(person, args); return result; }
就是把接口类型和参数改一下就可以!后续会添加代理模式在Spring上的使用,
四、总结
你不敲一遍代码你永远都不会理解,你抱着学一遍而不是彻底弄明白你也不可能学会!多查资料多理解代码,多花点时间一定会懂得!加油老铁。以解决问题的心态学编程而不是为了高薪工作。
加载全部内容