标签:父类 void 别人 loader 总结 equals char size private
代理模式定义:为其它对象提供一种代理以控制对这个对象的访问。代理的目的是在目标对象方法的基础上做增强,这种增强的本质是对目标方法做过滤和拦截。比如租房者找房子这件事,租房者给中介1000元中介费,然后中介通过各种方法最终为租房者找到了房子,最后租房者签合同入住。对这个流程进行分析:角色有中介(目标对象),租房者(代理对象);动作有给中介1000元中介费,签合同入住 (这两个属于增强处理),中介通过各种方法找到了房子(目标对象的目标方法,具体的业务逻辑就在这)。再比如游戏代练者用玩家的账号帮他们打怪升级,然后收取费用这件事:角色有玩家或者说玩家账号(目标对象),代练者(代理对象);动作有打怪升级(目标对象的目标方法),收费(增强处理)。
1.静态代理
在静态代理中,目标对象和代理对象需要实现的共同接口,定义IGamePlayer接口
public interface IGamePlayer { //登录 void login(); //打怪升级 void hunt(); }
定义玩家(目标对象)
public class GamePlayer implements IGamePlayer{ String userName = ""; public GamePlayer(String userName){ this.userName = userName; } public void login() { System.out.println(userName + "登录游戏"); } public void hunt() { System.out.println(userName + "正在打怪升级"); } }
定义代练者(代理对象)
public class ProxyGamePlayer implements IGamePlayer{ //玩家(目标对象) IGamePlayer gamePlayer = null; public ProxyGamePlayer(IGamePlayer gamePlayer){ this.gamePlayer = gamePlayer; } //登录账号 public void login() { this.gamePlayer.login(); } //打怪升级 public void hunt() { this.gamePlayer.hunt(); this.charge(); //增强处理 } //收费 public void charge(){ System.out.println("收费5元"); } }
定义场景类:
public class Client { public static void main(String[] args) { IGamePlayer gamePlayer = new GamePlayer("张三");//目标对象 IGamePlayer proxyGamePlayer = new ProxyGamePlayer(gamePlayer);//代理对象 proxyGamePlayer.login(); proxyGamePlayer.hunt(); } }
静态代理由于目标对象和代理对象需要实现共同的接口,所有会有很多代理对象,并且当接口中增加方法时,也要进行相应的维护,所以这一点不太好。有问题就有解决办法的,接下来我们就介绍动态代理。
2.JDK动态代理
我们先定义GamePlayer,IGamePlayer,同静态代理中的一样。然后定义一个InvocationHandler接口的实现类,用于代理对象的生成。
public class GamePlayerIH implements InvocationHandler{ //被代理的对象 Object obj = null; //我要代理谁 public GamePlayerIH(Object _obj){ this.obj = _obj; } //调用被代理的方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(obj, args); //调用目标对象的目标方法 if(method.getName().equals("login")){ System.out.println("我的账号被别人登录了");//增强处理 } return result; } }
然后定义一个场景类:
public class Client { public static void main(String[] args) { //目标对象 IGamePlayer gamePlayer = new GamePlayer("张三"); InvocationHandler invocationHandler = new GamePlayerIH(gamePlayer); //代理对象 IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(gamePlayer.getClass().getClassLoader(), gamePlayer.getClass().getInterfaces(), invocationHandler); proxy.login(); } }
jdk动态代理的前提条件是被代理者需要实现一个接口。那么如果一个目标对象没有实现任何接口,该如何实现代理呢?Cblib代理可以解决这个问题。
3.Cglib代理
cglib代理不需要目标对象实现任何接口,它是以目标对象子类的方式来实现代理的,也就是说目标对象的代理类就是它的子类。
定义GamePlayer类,不需要实现任何接口,注意,这个类一定要有一个默认的构造器。
public class GamePlayer{ String userName = ""; public GamePlayer(String userName){ this.userName = userName; } public GamePlayer(){ } public void login() { System.out.println(userName + "登录游戏"); } public void hunt() { System.out.println(userName + "正在打怪升级"); } }
定义Cglib子类代理工厂,用于生成目标对象的代理对象(子类对象)
public class ProxyFactory implements MethodInterceptor{ //目标对象 private Object obj = null; //要代理的是目标对象 public ProxyFactory(Object _obj){ this.obj = _obj; } //给目标对象创建一个代理对象 public Object getProxyInstance(){ Enhancer enhancer = new Enhancer();//工具类 enhancer.setSuperclass(obj.getClass());//设置父类 enhancer.setCallback(this);//设置回调函数 return enhancer.create();//创建子类(代理对象) } //调用目标对象的目标方法 public Object intercept(Object arg, Method method, Object[] args, MethodProxy arg3) throws Throwable { Object returnObject = method.invoke(obj, args);//调用目标对象的目标方法 if(method.getName().equals("login")){ System.out.println("我的账号被别人登录了");//增强处理 } return returnObject; } }
定义场景类
public class Client { public static void main(String[] args) { //目标对象 GamePlayer gamePlayer = new GamePlayer("张三"); //代理对象 GamePlayer proxy = (GamePlayer) new ProxyFactory(gamePlayer).getProxyInstance(); proxy.login(); } }
总结:静态代理中,目标对象和代理对象需要实现相同的接口;JDK动态代理中,目标对象至少需要实现一个接口,而代理对象不必实现接口;Cglib代理中,目标对象和代理对象都不需要实现接口,代理对象是根据目标对象的子类来生成的。
标签:父类 void 别人 loader 总结 equals char size private
原文地址:https://www.cnblogs.com/51life/p/9224555.html