设计模式学习笔记之代理模式

来源:互联网 发布:mac下载苹果铃声 编辑:程序博客网 时间:2024/05/16 08:16

定义:

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

使用代理模式创建代表对象,让代表对象控制某对象的访问,被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象。

几种代理访问方式:

远程代理控制访问远程对象。

虚拟代理控制访问创建开销大的资源。

保护代理基于权限控制对资源的访问。

java中的实现

①远程代理控制访问远程对象

在java中是通过RMI实现的。RMI提供了客户端辅助对象和服务端辅助对象,为客户辅助对象创建和服务对象相同的方法。RMI的好处在于你不必亲自写任何网络或I/O代码。客户程序调用远程方法(即真正的服务所在)就和在运行在客户自己的本地JVM上对对象正常方法调用一样。

RMI称呼:RMI将客户辅助对象称为stub(桩),服务辅助对象称为skeleton(骨架)。

步骤:

a.制作远程接口

java中是通过java.rmi.Remote接口实现,我们自己写的远程接口需要扩展(extends)Remote接口

声明所有的方法都会抛出RemoteException,客户使用远程接口调用服务,客户会调用实现远程接口的Stub上的方法,而Stub低层用到了网络和I/O,所有各种坏事情都可能发生。

确定变量和返回值是属于原语类型或者可序列化(Serializable)类型。如果传送自己定义的类,就必须保证你的类实现了Serializable。

b.制作远程实现

c.利用rmic产生的stub和skeleton(即产生中间代理)

d.执行remiregistry

e.启动服务


代码:(引用http://lavasoft.blog.51cto.com/62575/91679/)

远程接口:

public interface IHello extends Remote{
  /** 
     * 简单的返回“Hello World!"字样 
     * @return 返回“Hello World!"字样 
     * @throws java.rmi.RemoteException 
     */ 
    public String helloWorld() throws RemoteException; 


    /** 
     * 一个简单的业务方法,根据传入的人名返回相应的问候语 
     * @param someBodyName  人名 
     * @return 返回相应的问候语 
     * @throws java.rmi.RemoteException 
     */ 
    public String sayHelloToSomeBody(String someBodyName) throws RemoteException; 
}

远程实现:

public class HelloImp implements IHello {
@Override
public String helloWorld() throws RemoteException {
return "Hello World";
}


@Override
public String sayHelloToSomeBody(String someBodyName)
throws RemoteException {
// TODO Auto-generated method stub
return "你好," + someBodyName + "!"; 
}
}

服务端实现:

public class HelloServer {
public static void main(String args[]){
try{
//创建一个远程对象
IHello romoteHello = new HelloImp();
/*
* *本地主机上的远程对象注册表Registry的实例,并指定端口为8888,
* *这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上 
*/
LocateRegistry.createRegistry(8888);


            //把远程对象注册到RMI注册服务器上,并命名为RHello 
            //绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略,下面两种写法都是正确的)
Naming.bind("rmi://localhost:8888/RHello", romoteHello);
//          Naming.bind("//localhost:8888/RHello",rhello); 
System.out.println("远程对象绑定成功!");
  }catch(RemoteException e){
 
  }catch(AlreadyBoundException e){
 
  }catch(MalformedURLException e){
 
  }
}
}

客户端实现:

public class HelloClient {
public static void main(String args[]){
try{
IHello remoteHello = (IHello)Naming.lookup("rmi://localhost:8888/RHello");
System.out.println(remoteHello.helloWorld());
System.out.print(remoteHello.sayHelloToSomeBody("小张"));
}catch (NotBoundException e) { 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            e.printStackTrace(); 
        } catch (RemoteException e) { 
            e.printStackTrace();   
        } 
}
}

②虚拟代理

虚拟代理作为创建开销大的对象的代表。虚拟代理经常直到我们正在需要一个对象的时候才创建它,由虚拟代理来扮演对象的替身。对象创建后,代理就会将请求直接委托给对象。

③动态代理

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

0 0
原创粉丝点击