《Java设计模式之代理模式》

《代理模式》

  代理模式:为对象提供一种代理以控制这种对象的访问。在Java中有静态代理和动态代理两种实现方式。

  静态代理:

  拿日本动漫《棋魂》举例,佐为只是灵魂,它要下棋必须通过阿光这个“代理”,我们用代码实现一下:
//Subject
public interface WeiQi {
	void playWeiQi();
}
//RealSubject
public class ZuoWei implements WeiQi {
	@Override
	public void playWeiQi() {
		System.out.println("佐为下围棋");
	}
}
//Proxy
public class Guang implements WeiQi {
	private WeiQi zuoWei;
	
	public Guang() {
		zuoWei = new ZuoWei();
	}
	@Override
	public void playWeiQi() {
                System.out.println("阿光才是真正操作棋子的");
		zuoWei.playWeiQi();
	}
}
//测试
public static void main(String[] args) {
	//客户端调用代理类
	WeiQi guang = new Guang();
	guang.playWeiQi();
}
  再使用动态代理实现上面的例子:
//RealSubject
public class ZuoWei implements WeiQi {
	@Override
	public void playWeiQi() {
		System.out.println("佐为下围棋");
	}
	public static void main(String[] args) {
		WeiQi zuoWei = new ZuoWei();
		WeiQi weiQi = (WeiQi) Proxy.newProxyInstance(zuoWei.getClass().getClassLoader(), new Class[]{WeiQi.class}, new WeiQiInvocationHandler(zuoWei));
		weiQi.playWeiQi();
	}
}
class WeiQiInvocationHandler implements InvocationHandler{
	private WeiQi weiQi;
	public WeiQiInvocationHandler(WeiQi weiQi) {
		this.weiQi = weiQi;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("阿光才是真正操作棋子的");
		method.invoke(weiQi);
		return null;
	}
}
  动态代理之所以被称为动态,就是因为运行时才将它的类创建出来。代码开始执行时,还没有proxy类,它时根据传入的接口而创建的。

  代理模式的应用场景

  1.远程代理:可以作为另一台虚拟机上的本地代表,调用代理的方法,会被代理利用网络和IO转换成远程调用服务,并将结果再通过网络返回给客户端。
//服务接口
public interface Hello extends Remote {
	String sayHello()throws RemoteException;
}
//服务实现类
public class SayHello extends UnicastRemoteObject implements Hello {
	protected SayHello() throws RemoteException {
		//该构造器只是为了抛出异常
		super();
	}
	@Override
	public String sayHello() throws RemoteException {
		return "hello brother";
	}
}
//启动服务
public class MyServer {
	//用于启动服务
	public static void main(String[] args) {
		try {
			Hello hello = new SayHello();
			//设置端口
			LocateRegistry.createRegistry(6601);
			Context namingContext = new InitialContext();
			//向rmi注册服务
			namingContext.rebind("rmi://127.0.0.1:6601/hello", hello);
			System.out.println("服务器已经启动");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
//客户端
public class MyClient {
	public static void main(String[] args) {
		try {
			//从rmi中获取服务
			Hello hello = (Hello) Naming.lookup("rmi://127.0.0.1:6600/hello");
			String str = hello.sayHello();
			System.out.println(str);
		} catch (MalformedURLException | RemoteException | NotBoundException e) {
			e.printStackTrace();
		}
	}
}
  2.虚拟代理:在创建开销比较大的对象时,使用虚拟代理替代该对象,只有当该对象被真正调用的时候才会被创建,提高了程序的启动速度。比如加载HTML页面时,图片是要一个一个下的,此时哪些未打开的图片框就是通过虚拟代理代替了图片。
  3.安全代理:一般是通过动态代理来控制真实对象的访问权限。比如用动态代理作权限验证。
  .....还有很多代理模式,这里就不列举了




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
web报表工具 请移步:http://download.csdn.net/source/2881508 不多说,除了RMI的学习外,gui对新手入门也是个不错的学习 /* *此类适合在本地注册的RMI服务器,避免了使用了多个DOS的写法,只需要简单的给使用 *本类提供的方法即可。 */ package common.rmiserver; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.Remote; import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; //import java.rmi.RMISecurityManager; import java.rmi.RemoteException; import java.net.MalformedURLException; import java.rmi.server.UnicastRemoteObject; import common.zip.ZipClientSocketFactory; import common.zip.ZipServerSocketFactory; public final class RMIServer { private Registry registry = null; // @jve:decl-index=0: private String serverName = "RMIServer"; private String serverPath = "localhost"; private int port = 1099; private Remote serverInterface = null; private Boolean isStart = false; private AllFace dataAllFace = null; private int dataPort = 0;// 数据端口,0表示端口由RMI服务器动态生成. private Remote stub; public RMIServer() { } /* * 使用默认端口,默认服务器名称,服务路径构造函数 use the default port,server name and the url */ public RMIServer(Remote obj) { this.serverInterface = obj; } /* * 使用默认端口,服务路径构造函数 use the default port and server url */ public RMIServer(String servername, Remote obj) { this.serverName = servername; this.serverInterface = obj; } /* * 服务器为默认值的构造函数 use the default url */ public RMIServer(String servername, int port, Remote obj) { this.port = port; this.serverName = servername; this.serverInterface = obj; } /* * 适合1.4范围的版本,当然也适合5.0的版本 */ public Boolean setStart() throws RemoteException, MalformedURLException, NotImplementInterfaceException { if (registry == null) registry = LocateRegistry.createRegistry(port); if (serverInterface == null) { throw new NotImplementInterfaceException( "not found the reote interface method!!"); } Naming.rebind("rmi://"+serverPath + ":" + port + "/" + serverName, serverInterface); isStart = true; return isStart; } /* * jdk5.0以后的写法,在使用之前使用setXxx方法给对象赋值 */ public Boolean start() throws RemoteException, MalformedURLException, NotImplementInterfaceException { if(stub==null) stub = (Remote) UnicastRemoteObject.exportObject(dataAllFace, dataPort);// 0表示端口随机生成. if (registry == null) registry = LocateRegistry.createRegistry(port, new ZipClientSocketFactory(), new ZipServerSocketFactory()); setProperty(serverPath); //绑定IP registry.rebind(serverName, stub); isStart = true; return isStart; } /* * 如果有多个ip,则使用这个方法绑定指定的IP */ public void setProperty(String ip) { System.setProperty("java.rmi.server.hostname", ip); } /* * close the server */ public void close() throws RemoteException, MalformedURLException, NotBoundException { //UnicastRemoteObject.unexportObject(dataAllFace, true); Naming.unbind("rmi://"+serverPath + ":" + port + "/" + serverName); isStart = false; } /* * set server name,if not set the name,the service will use the default name * "RMIServer" */ public void setServerName(String serverName) { this.serverName = serverName; } /* * set the server URL,default localhost "rmi://localhost" */ public void setServerPath(String serverPath) { this.serverPath = serverPath; } /* * set the server port default port is 1099. */ public void setPort(int port) { this.port = port; } /* * set then remote implement method */ public void setServerInterface(Remote serverInterface) { this.serverInterface = serverInterface; } /* * set the server Security */ public void setSecurityManager() { /* if (System.getSecurityManager() == null) { try { // java -Djava.security.policy=policy.txt // common.rmiserver.RMIServer System.setSecurityManager(new RMISecurityManager());// 暂时不要安全设置, } catch (java.rmi.RMISecurityException exc) { throw exc; } }*/ } /* * set the remote method */ public void setDataAllFace(AllFace dataAllFace) { this.dataAllFace = dataAllFace; } /* * set the remote dataport */ public void setDataPort(int dataPort) { this.dataPort = dataPort; } // ----------------------------------------------- /* * return the server URL */ public String getServerPatth() { return serverPath; } /* * return remote method */ public Remote getserverInterface() { return serverInterface; } /* * return the server name */ public String getServerName() { return serverName; } /* * return the server use port */ public int getPort() { return port; } /* * return the server then action state */ public Boolean isStart() { return isStart; } /* * return remote method */ public AllFace getDataAllFace() { return dataAllFace; } /* * return remote dataport */ public int getDataPort() { return dataPort; } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值