代理
比如
structs2里面的拦截器,网络代理,翻墙等等。
这里就不多叙述其它高级的代理模式了。学的非常肤浅。没有实际应用到项目中去。这个暑假,仅仅是拓宽一下眼界而已。让自己有个印象。
普通代理(静态代理)
public abstract class IGamePlayer { public abstract void fightBoss(); public abstract void login(String uname,String pwd); public abstract void upgrade(); }
public class GamePlayer extends IGamePlayer { private String name=""; public GamePlayer(String name){ this.name=name; } @Override public void fightBoss() { System.out.println(this.name+"在打怪"); } @Override public void upgrade() { System.out.println(this.name+"升级了"); } @Override public void login(String uname, String pwd) { System.out.println(uname+"登录,时间"+new Date()); } }
public class GamePlayerProxy extends IGamePlayer { private IGamePlayer gamePlayer=null; public GamePlayerProxy(GamePlayer gamePlayer){ this.gamePlayer=gamePlayer; } @Override public void fightBoss() { this.gamePlayer.fightBoss(); } @Override public void login(String uname, String pwd) { this.before(); this.gamePlayer.login(uname, pwd); } @Override public void upgrade() { this.gamePlayer.upgrade(); this.after(); } public void before(){ System.out.println("開始代理"); } public void after(){ System.out.println("结束代理"); } }
public class Client { public static void main(String[] args) { GamePlayer player=new GamePlayer("大宝"); GamePlayerProxy proxy=new GamePlayerProxy(player); proxy.login("大宝","a"); proxy.fightBoss(); proxy.upgrade(); } }
上面的样例很easy,权当入门看看。有点感觉。
以下来一个有意思的代理,叫做强制代理。意思就是仅仅能通过真实类来找到代理。而上面的静态代理是通过代理来找到真实类,从而达到訪问目的。
强制代理
//强制代理 必须通过真实类找到代理 //普通代理 通过代理找到真实类 public abstract class IGamePlayer { public abstract void fightBoss(); public abstract void login(String uname,String pwd); public abstract void upgrade(); public abstract IGamePlayer getProxy(); }
public class GamePlayerProxy extends IGamePlayer { private IGamePlayer gamePlayer=null; public GamePlayerProxy(IGamePlayer gamePlayer){ this.gamePlayer=gamePlayer; } @Override public void fightBoss() { this.gamePlayer.fightBoss(); } @Override public void login(String uname, String pwd) { this.before(); this.gamePlayer.login(uname, pwd); } @Override public void upgrade() { this.gamePlayer.upgrade(); this.after(); } public void before(){ System.out.println("開始代理"); } public void after(){ System.out.println("结束代理"); } //临时没有,就是自己 @Override public IGamePlayer getProxy() { return this; } }
public class GamePlayer extends IGamePlayer { private String name=""; private IGamePlayer proxy=null; @Override public IGamePlayer getProxy() { this.proxy=new GamePlayerProxy(this); return this.proxy; } public GamePlayer(String name){ this.name=name; } @Override public void fightBoss() { if(this.isProxy()){ System.out.println(this.name+"在打怪"); }else{ System.out.println("请使用指定的代理訪问"); } } @Override public void upgrade() { if(this.isProxy()){ System.out.println(this.name+"升级了"); }else{ System.out.println("请使用指定的代理訪问"); } } @Override public void login(String uname, String pwd) { if(this.isProxy()){ System.out.println(uname+"登录,时间"+new Date()); }else{ System.out.println("请使用指定的代理訪问"); } } private boolean isProxy(){ if(this.proxy==null){ return false; }else{ return true; } } }
public class Client { public static void main(String[] args) { /* GamePlayer player=new GamePlayer("大宝"); player.login("大宝","a"); player.fightBoss(); player.upgrade();*/ /*IGamePlayer player=new GamePlayer("大宝"); IGamePlayer proxy=new GamePlayerProxy(player); proxy.login("大宝","a"); proxy.fightBoss(); proxy.upgrade();*/ IGamePlayer player=new GamePlayer("大宝"); IGamePlayer proxy=player.getProxy(); proxy.login("大宝", "a"); proxy.fightBoss(); proxy.upgrade(); } }
分析測试
第一个直接使用真实类訪问,自然无法訪问。
由于在其业务方法中指定须要代理。
另外一种通过真实类得到一个代理对象。这种话是通过代理来訪问真实类。和静态代理一样。
第三种通过真实类得到一个代理对象。再实现訪问。
动态代理
大致分为四步,当中具体的就不多说了。能够參照博客。 http://www.cnblogs.com/flyoung2008/archive/2013/08/11/3251148.html
1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);
2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});
3、通过反射机制获取动态代理类的构造函数,其參数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4、通过构造函数创建代理类实例,此时需将调用处理器对象作为參数被传入
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
为了简化对象创建过程。Proxy类中的newInstance方法封装了2~4,仅仅需两步就可以完毕代理对象的创建。
生成的ProxySubject继承Proxy类实现Subject接口。实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))
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); if(method.getName().equalsIgnoreCase("login")){ System.out.println("有人用我的账号登陆"); } return result; } }
public static void main(String[] args) { GamePlayer player = new GamePlayer("大宝"); InvocationHandler handler = new GamePlayIH(player); ClassLoader cl = player.getClass().getClassLoader(); IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, new Class[] { IGamePlayer.class }, handler); proxy.login("大宝", "a"); proxy.fightBoss(); proxy.upgrade(); }
这里有个地方须要说明,Proxy只支持interface代理,也就是说。IGamePlayer只能是接口,而不能是抽象类,细心的可能发现上面写的都是使用了抽象类。再细心的能够发现我在实例化GamePlayer("大宝")时没有使用多态。失误失误。 这样看来,动态代理全然是面向接口编程,抽象层面的底层编程。
public interface IGamePlayer { public void fightBoss(); public void login(String uname, String pwd); public void upgrade(); }
public class GamePlayer implements IGamePlayer { private String name=""; public GamePlayer(String name){ this.name=name; } public void fightBoss() { System.out.println(this.name+"在打怪"); } public void login(String uname, String pwd) { System.out.println(uname+"登录。时间"+new Date()); } public void upgrade() { System.out.println(this.name+"升级"); } }
将上述的多个流程整合成一起
public class DynamicProxy<T> { public static <T> T newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h){ //寻找JoinPoint连接点,AOP框架使用元数据定义 if(true){ //XXX运行 System.out.println("运行到这里来了"); } return (T) Proxy.newProxyInstance(loader, interfaces, h); } }
再进一步的整理
public class SubjectDynamicProxy extends DynamicProxy { public static <T> T newProxyInstance(IGamePlayer gamePlayer){ ClassLoader loader=gamePlayer.getClass().getClassLoader(); Class<?>[] interfaces=gamePlayer.getClass().getInterfaces(); InvocationHandler handler=new GamePlayIH(gamePlayer); return newProxyInstance(loader, interfaces, handler); } }
调用
public static void main(String[] args) { GamePlayer player = new GamePlayer("大宝"); InvocationHandler handler = new GamePlayIH(player); IGamePlayer proxy =DynamicProxy.newProxyInstance(player.getClass().getClassLoader(), player.getClass().getInterfaces(), handler); proxy.login("大宝", "a"); proxy.fightBoss(); proxy.upgrade(); }
public static void main(String[] args) { GamePlayer player = new GamePlayer("大宝"); IGamePlayer proxy =SubjectDynamicProxy.newProxyInstance(player); proxy.login("大宝", "a"); proxy.fightBoss(); proxy.upgrade(); }
我是菜鸟,我在路上。