代理模式(Proxy Pattern)是java中一个使用率很高的模式。通用类图如图
代理模式的本质就是控制对象的访问。
首先来介绍下在学习代理中遇到的几个定义:
Subject抽象主题角色
抽象主题类可以是抽象类也可以是接口,是一个普通的业务类型定义,无特殊要求。
RealSubject具体主题角色
也叫被委托角色,被代理角色。 它才是冤大头,是业务逻辑的具体执行者。
Proxy代理主题角色
也叫委托类,代理类。它负责对真是角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
代理主要分为静态代理和动态代理
代理一个典型的特点就是代理类和具体主题类都要实现抽象主题角色接口。
代码如下
//抽象主题接口类 public interface IGamePlayer { public void login(String name, String password); public void killBoss(); public void upgrade(); } //--------------------------------------------------------- //具体主题实现类, 进行主要的业务逻辑 public class GamePlayer implements IGamePlayer{ private String name = ""; public GamePlayer(String name){ this.name = name; } public void killBoss(){ System.out.println(this.name + " is fighting"); } public void login(String user, String password){ System.out.println("login user is " + user + " name is " + this.name + " login susses" ); } public void upgrade(){ System.out.println( this.name + " is upgrade"); } }
下面是代理类的代码
public class GamePlayerProxy implements IGamePlayer{ //真实主题角色的引用 private IGamePlayer gamePlayer = null; public GamePlayerProxy(IGamePlayer gamePlayer){ this.gamePlayer = gamePlayer; } public void killBoss(){ //业务执行前后加上代理的业务逻辑 this.gamePlayer.killBoss(); } public void login(String user, String password){ this.gamePlayer.login(user, password); } public void upgrade(){ this.gamePlayer.upgrade(); } }
客户端类
public class Client { public static void main(String[] args){ IGamePlayer player = new GamePlayerProxy(new GamePlayer("张三")); System.out.println("start play"); player.login("zhangsan", "123456"); player.killBoss(); player.upgrade(); System.out.println("end play"); } }
上面的代码中,代理类和具体的主题实现类都实现了IGamePlayer接口,通过代理去访问具体实现类。
这里主要记录下动态代理
动态代理主要是实现java.lang.reflect包下的InvocationHandler接口和使用Proxy类实例化一个代理对象。
接口类和具体实现类和上面的代码一样,只是添加了一个InvocationHandler的实现类,具体代码如下
public class GamePlayIH implements InvocationHandler{ Class cls = null; Object obj = null; public GamePlayIH(Object obj){ this.obj = obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ Object result = method.invoke(this.obj, args);//方法的调用,在此也可以添加额外的业务逻辑 return result; } }
客户端类
public class Client { public static void main(String[] args){ IGamePlayer player = new GamePlayer("张三"); InvocationHandler handler = new GamePlayIH(player); System.out.println("start play"); IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(player.getClass().getClassLoader(), player.getClass().getInterfaces(), handler); proxy.login("zhangsan", "123456"); proxy.killBoss(); proxy.upgrade(); System.out.println("end play"); } }