动态代理模式

来源:互联网 发布:新加坡 知乎 编辑:程序博客网 时间:2024/06/06 20:18

1.概念

代理模式:为另一个对象提供一个替身或占位符以访问对象。

2.分析过程

1.RMI

RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建和服务对象相同的方法。RMI的好处在于你不必亲自写网络或i/o代码。客户程序调用远程方法就和在运行在客户自己的本地jvm对象进行正常方法调用一样。

2.制作远程服务

制作远程接口。定义出让客户远程调用的方法。stub和实际的服务都实现此接口。

制作远程的实现。做实际工作的,客户端真正想要调用的方法的对象。

利用rmic产生额stubskeleton。这就是客户和服务的辅助类,不需要自己创建这些类。

启动RMIregistry。客户可以从中查到代理的位置。

开始远程服务。你的服务实现类会去实例化一个服务的实例。

3.代理有好多,着重讲动态代理

javajava.lang.reflect包有自己的代理支持,利用这个包你可以运行时动态地创建一个代理类,实现一个或多个接口,并将方法的调用转发到你所指定的类。因为实际的代理类是在运行时创建的,我们称为这个java技术为:动态代理。

java已经为你创建了Proxy类,所以你需要有办法来告诉Proxy类你要做什么。你不能像以前一样把代码放在Proxy类中,因为Proxy不是你直接 实现的。既然这样的代码不能放在Proxy类中,那么要放在那里?放在InvocationHandler中。InvocationHandle的工作是相应代理的如何调用。你可以把InvocationHandler想成是代理收到的方法调用后,请求做实际工作的需要。

4.动态调用的过程:

不管代理被调用的是何种方法,处理器被调用的一定是invoke()方法。

如何工作:

 1.假设proxysetHotOrNotRating()方法被调用

  proxy.setsetHotOrNotRating(9);

  2.proxy会接着调用InvocationHandlerinvoke()方法。

 invoke(Objec proxy,Method method , Object[]args)

3.hadler决定要如何处置这个请求,可能会转发给RealSubjectHandler到底是如何决定的呢?

--->return   method.invoke(person, args);

3.举例源码

//对象村的配对/*PersonBean ,允许设置或取得一个人的信息。*/public interface PersonBean{String getName();String getGender();String getIntertest();int getHotOrNotRating();void setName(String name);void setGender(String gender);void setInterests(String interests);void setHotOrNotRating(int rating);}/*PersonBean实现*/public class PersonBeanImpl implements PersonBean{String name;String gender;String interests;int rating;int ratingCount = 0;public String getName(){return name;}public String getGender(){return interests;}public int getHotOrNotRating(){if(ratingCount == 0 ) return 0;return (rating/ratingCount);}}//为PersonBean创建代理/*我们有一些问题要修正:顾客不可以改变自己的HotOrNot评分,也不可以改变其顾客的个人信息。要修正这些问题,你必须创建两个代理:一个访问你自己的PersonBean对象,另一个访问另一个顾客的PersonBean对象。这样,代理就可以控制在每一种情况下允许哪一种请求。*//*创建步骤:1.创建两个InvocationHandler,这个实现了代理的行为。2.写代码创建动态代理。3.利用适当的代理包装任何PersonBean对象什么是InvocationHandler呢?-->当代理的方法被调用时,代理就会把这个调用转发给InvocationHandler,但是这并不是通过调用InvocationHandler的相应方法做到的。*/public class OwnerInvocationHandler implements InvocationHandler{PersonBean person;public OwnerInvocationHandler(PersonBean person){this.person = person;}public Object invoke(Object proxy ,Method method , Object [] args){try{if(method.getName().startWith("get")){return method.invoke(person,args);}else if (method.getName().equals("setHotOrNotRating")){throw new IllegalAccessException();}else if(method.getName().startWith("set")){return method.invoke(person,args);}catch(InvocationTargetException e){e.printStackTrace();}}return null;//如果调用其它的方法,一律不理,返回null}}//创建proxy类并实例化proxy对象PersonBean getOwnerProxy(PersonBean person){return (PersonBean) proxy.newProxyInstance(person.getClass().getClassLoader(),person.getClass().getInterfaces(),new OwnerInvocationHandler(person));}//测试配对对象public class MatchMakingTestDrive{//这里有实例变量public static void main(String[] args){MatchMakingTestDrive test = new MatchMakingTestDrive();test.drive();}public MatchMakingTestDrive(){initializeDatabase();}public void drive(){PersonBean joe = getPersonFromDatabase("joe javabean");//从数据库取出一个人PersonBean ownerProxy = getOwnerProxy(joe);//然后创建一个拥有者代理System.out.println("name is" +ownerProxy.getName());//调用getownerProxy.setInterests("bowling");//调用settry{ownerProxy.setHotOrNotRating(10);//试着改变评分,行不通}catch(Exception e){....}PersonBean nonOwnerProxy = getNonOwerProxy(joe);//创建一个非拥有代理//set方法行不通}}


0 0
原创粉丝点击