为了账号安全,请及时绑定邮箱和手机立即绑定

设计模式之代理模式

标签:
Java 设计

代理模式(静态代理和动态代理)

代理模式:我觉得就是类似于Spring AOP,在不改变原有类的情况下,给某个方法的调用加一些条件。

一、静态代理(租房子):

  gerry需要租房子,中介帮他找房子,双方都得实现一个协议-IRent接口

  中介类中找到需要租房子的人,IRent rent;通过构造函数把传进来的租房人给rent,再用rent调用方法

1 package deep.staticc.demo;2 3 public interface IRent {4 5     public void rentHouse(String name);6 }

复制代码

 1 package deep.staticc.demo; 2  3  4  5 /** 6  * 场景:gerry工作非常忙,没有时间找房子,需要找一个中介帮忙 7  * @author DeepSleeping 8  * 9  */10 public class Gerry implements IRent{11     12     @Override13     public void rentHouse(String name){14         System.out.println(name + "需要租房子");15     }16 }

复制代码

复制代码

 1 package deep.staticc.demo; 2  3 public class Medium implements IRent { 4  5     //持有目标代理类的引用 6     private IRent rent; 7      8     public Medium(IRent rent){ 9         this.rent = rent;10     }11 12     13     @Override14     public void rentHouse(String name) {15         rent.rentHouse(name);16     }17 18 }

复制代码

复制代码

 1 package deep.staticc.demo; 2  3 public class TestProxy { 4     public static void main(String[] args) { 5         //创建目标对象 6         IRent target = new Gerry(); 7         //创建一个代理对象 8         IRent proxy = new Medium(target); 9         //通过代理调用方法10         proxy.rentHouse("gerry");11     }12 }

复制代码

https://img1.sycdn.imooc.com//5b5c4414000113bd07150108.jpg

静态代理总结:局限性太大,只有共同实现了某一个接口才能够代理,即都实现了IRent接口通过多态来运转。

二、动态代理(添加信息前进行权限认证)

复制代码

1 package deep.dynamic.demo;2 3 public interface IUserDao {4 5     void add();6     7     void deletd();8 9 }

复制代码

复制代码

 1 package deep.dynamic.demo; 2  3 /** 4  * 实现认证操作功能: 5  * 项目中每一个方法的调用都需要进行4个认证 6  * 1、是否合法 7  * 2、是否有新增权限 8  * 3、开启事务 9  * 4、关闭事务10  * @author DeepSleeping11  *12  */13 public class UserDaoImpl implements IUserDao {14     15     @Override16     public void add(){17         System.out.println("新增信息");18     }19 20     @Override21     public void deletd() {22         System.out.println("删除信息");23         24     }25 }

复制代码

复制代码

 1 package deep.dynamic.demo.proxy; 2  3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6  7 /** 8  * 动态代理类 9  * @author DeepSleeping10  *11  */12 public class ProxyClass {13     //目标对象14     private Object target;15     16     public ProxyClass(Object target){17         this.target = target;18     }19     20     /**21      * 创建当前目标对象代理对象22      * @return23      */24     public Object createProxy(){25         /**26          * loader:目标对象的类加载器27          * interfaces:目标对象实现的所有接口组成的数组28          * handler:定义一个调用目标类中方法的回调类29          */30         return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),31                 new InvocationHandler() {32                     33                     @Override34                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {35                         //进行调用前的认证36                         System.out.println("1、是否合法");37                         System.out.println("2、是否有权限");    
38                         System.out.println("3、开启事务");39                         Object obj = null;40                         41                         42                         try {43                             method.invoke(target, args);44                             45                         } catch (Exception e) {46                             System.out.println("4、关闭事务");47                         }    
48                         System.out.println("--业务执行正常--");49                         50                         return obj;51                     }52                 });53     }54 }

复制代码

复制代码

 1 package deep.dynamic.demo; 2  3 import deep.dynamic.demo.proxy.ProxyClass; 4  5 public class TestDynamicProxy { 6  7     public static void main(String[] args) { 8         //创建目标对象 9         IUserDao target = new UserDaoImpl();10         //创建代理类的实例11         ProxyClass proxy = new ProxyClass(target);12         //生成对应的代理对象13         IUserDao userDao = (IUserDao) proxy.createProxy();14         userDao.add();15         userDao.deletd();16     }17 }

复制代码

https://img1.sycdn.imooc.com//5b5c441d0001084d05810264.jpg

 附加:为什么可以强转IUserDao userDao = (IUserDao) proxy.createProxy();

  是因为Proxy.newProxyInstance方法的第二个参数取得了目标对象的所有实现的接口的数组,代理对象就会实现这组接口,所以我们就可以将代理对象任意强转成这组接口的任意一个。

静态代理:共同实现一个接口,通过多态调用

动态代理:动态地实现同一个接口(通过方法传目标对象实现过的接口,然后底层自动实现它们,这样就像静态代理那样,目标和代理对象都实现了同一个接口)然后又可以利用多态强转后调用

原文出处:http://www.cnblogs.com/deepSleeping/p/9381965.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消