代理介绍

代理(Proxy)是一种设计模式, 提供了对目标对象另外的访问方式;即通过代理访问目标对象。 这样好处: 可以在目标对象实现的基础上,增强额外的功能操作。(扩展目标对象的功能)。

可以做到在不修改目标对象的功能前提下,对目标对象功能扩展。

简单理解代理

很简单举个例子:

  • 现在我是一个明星,拥有很多粉丝。粉丝希望我唱歌给他们听,但是如果都是我来接应他们,我岂不是很忙….于是乎,我就去找了个经纪人。这个经纪人就代表了我。当粉丝想要我唱歌的时候,应该是找经纪人,告诉经纪人想让我唱歌。

  • 现在我越来越红了,不是粉丝想要我唱歌,我就唱了。我要收费了。但是呢,作为一个公众人物,不可能是我自己说:我要收10000万,我才会去唱歌。于是这就让经纪人对粉丝说:只有10000万,我才会唱歌。

  • 无论外界是想要我干什么,都要经过我的经纪人。我的经纪人也会在其中考虑收费、推脱它们的请求。

经纪人就是代理,实际上台唱歌、表演的还是我

静态代理

直接使用例子来说明吧…现在我有一个IUserDao的接口,拥有save方法()


// 接口
public interface IUserDao {void save();
}
  • UserDao实现该接口,重写save()方法
public class UserDao implements IUserDao{@Overridepublic void save() {System.out.println("-----已经保存数据!!!------");}}

现在,我想要在save()方法保存数据前开启事务、保存数据之后关闭事务…(当然啦,直接再上面写不就行了吗…业务方法少的时候,确实没毛病…)

public void save() {System.out.println("开启事务");System.out.println("-----已经保存数据!!!------");System.out.println("关闭事务");}

但是呢,现在如果我有好多好多个业务方法都需要开启事务、关闭事务呢?

    public void save() {System.out.println("开启事务");System.out.println("-----已经保存数据!!!------");System.out.println("关闭事务");}public void delete() {System.out.println("开启事务");System.out.println("-----已经保存数据!!!------");System.out.println("关闭事务");}public void update() {System.out.println("开启事务");System.out.println("-----已经保存数据!!!------");System.out.println("关闭事务");}public void login() {System.out.println("开启事务");System.out.println("-----已经保存数据!!!------");System.out.println("关闭事务");}

…..我们发现就有了很多很多的重复代码了…我们要做的就是:当用户调用UserDao方法的时候,找的是代理对象、而代理帮我在解决这么繁琐的代码

于是呢,我们就请了一个代理了

  • 这个代理要和userDao有相同的方法…没有相同的方法的话,用户怎么调用啊??
  • 代理只是对userDao进行增强,真正做事的还是userDao..

因此,我们的代理就要实现IUserDao接口,这样的话,代理就跟userDao有相同的方法了。


public class UserDaoProxy implements IUserDao{// 接收保存目标对象【真正做事的还是UserDao】,因此需要维护userDao的引用private IUserDao target;public UserDaoProxy(IUserDao target) {this.target = target;}@Overridepublic void save() {System.out.println("开始事务...");target.save();          // 执行目标对象的方法System.out.println("提交事务...");}
}

外界并不是直接去找UserDao,而是要通过代理才能找到userDao

public static void main(String[] args) {// 目标对象IUserDao target = new UserDao();// 代理IUserDao proxy = new UserDaoProxy(target);proxy.save();  // 执行的是,代理的方法}

这样一来,我们在UserDao中就不用写那么傻逼的代码了…傻逼的事情都交给代理去干了…

为什么要用动态代理?

我们首先来看一下静态代理的不足

  • 如果接口改了,代理的也要跟着改,很烦!
  • 因为代理对象,需要与目标对象实现一样的接口。所以会有很多代理类,类太多。

动态代理比静态代理好的地方:

  • 代理对象,不需要实现接口【就不会有太多的代理类了】
  • 代理对象的生成,是利用JDKAPI, 动态地在内存中构建代理对象(需要我们指定创建 代理对象/目标对象 实现的接口的类型;)

动态代理快速入门

Java提供了一个Proxy类,调用它的newInstance方法可以生成某个对象的代理对象,该方法需要三个参数:

  • 参数一:生成代理对象使用哪个类装载器【一般我们使用的是代理类的装载器】
  • 参数二:生成哪个对象的代理对象,通过接口指定【指定要代理类的接口】
  • 参数三:生成的代理对象的方法里干什么事【实现handler接口,我们想怎么实现就怎么实现】

在编写动态代理之前,要明确两个概念:

  • 代理对象拥有目标对象相同的方法【因为参数二指定了对象的接口】
  • 用户调用代理对象的什么方法,都是在调用处理器的invoke方法。
  • 使用JDK动态代理必须要有接口【参数二需要接口】

对象

小明是一个明星,拥有唱歌和跳舞的方法。实现了人的接口


public class XiaoMing implements Person {@Overridepublic void sing(String name) {System.out.println("小明唱" + name);}@Overridepublic void dance(String name) {System.out.println("小明跳" + name);}
}

接口

public interface Person {void sing(String name);void dance(String name);
}

代理类


public class XiaoMingProxy {//代理只是一个中介,实际干活的还是小明,于是需要在代理类上维护小明这个变量XiaoMing xiaoMing = new XiaoMing();//返回代理对象public Person getProxy() {/*** 参数一:代理类的类加载器* 参数二:被代理对象的接口* 参数三:InvocationHandler实现类*/return (Person)Proxy.newProxyInstance(XiaoMingProxy.class.getClassLoader(), xiaoMing.getClass().getInterfaces(), new InvocationHandler() {/*** proxy : 把代理对象自己传递进来* method:把代理对象当前调用的方法传递进来* args:把方法参数传递进来*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//如果别人想要让小明唱歌if (method.getName().equals("sing")) {System.out.println("给1000万来再唱");//实际上唱歌的还是小明method.invoke(xiaoMing, args);}return null;}});}
}

测试类

public static void main(String[] args) {//外界通过代理才能让小明唱歌XiaoMingProxy xiaoMingProxy = new XiaoMingProxy();Person proxy = xiaoMingProxy.getProxy();proxy.sing("我爱你");}


动态代理应用

我们之前写中文过滤器的时候,需要使用包装设计模式来设计一个request类。如果不是Servlet提供了实现类给我们,我们使用包装设计模式会出现麻烦

现在我们学习了动态代理了,动态代理就是拦截直接访问对象,可以给对象进行增强的一项技能

中文过滤器

public void doFilter(final ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {final HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;response.setContentType("text/html;charset=UTF-8");request.setCharacterEncoding("UTF-8");//放出去的是代理对象chain.doFilter((ServletRequest) Proxy.newProxyInstance(CharacterEncodingFilter.class.getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//判断是不是getParameter方法if (!method.getName().equals("getParameter")) {//不是就使用request调用return method.invoke(request, args);}//判断是否是get类型的if (!request.getMethod().equalsIgnoreCase("get")) {return method.invoke(request, args);}//执行到这里,只能是get类型的getParameter方法了。String value = (String) method.invoke(request, args);if (value == null) {return null;}return new String(value.getBytes("ISO8859-1"), "UTF-8");}}), response);}

转载于:https://www.cnblogs.com/zhong-fucheng/p/7202998.html

代理模式【介绍、静态代理、动态代理、入门、应用】相关推荐

  1. 代理模式(静态、动态)

    文章目录 一.代理模式 1.什么是代理模式 2.为什么使用代理模式 3.代理模式应用场景 4..代理模式实现原理 5.代理模式创建的方式 6.静态代理 6.1基于接口方式 6.1基于继承方式 7.动态 ...

  2. 代理模式及Java实现动态代理

    代理模式 定义:给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象. 代理模式UML图 在上图中: RealSubject 是原对象 ...

  3. 谈谈java代理模式的认识二——动态代理(JDK)

    让我们就接着上篇博客的静态代理来开始今天的动态代理. 一.动态代理 静态代理需要在运行之前就写好代理类,这样就造成了代码的大量重复,所以我们通过动态代理在运行时期动态生成业务类的代理类,那么动态代理类 ...

  4. 设计模式总结——代理模式以及java的动态代理

    定义 给目标对象一个代理对象,并由代理对象控制对目标对象的引用.联想到生活中就像是海外代购 既然是代理,就说明他要做的事情要比你直接去做要做的多,这就联系到了方法的增强,也就联系到了AOP,面向切面. ...

  5. 代理模式(Proxy) 静态

    代理模式分为静态和动态代理 由程序员创建或工具生成代理类的源码,再编译代理类.所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了. 所以说静态代理,主要是自己 ...

  6. 设计模式之代理模式(静态代理动态代理)

    目录 1.什么是代理模式 2.代理模式的结构 3.代理模式的实现 3.1 静态代理和动态代理概念 3.2 静态代理 3.3 动态搭理 3.3.1 代码实现 3.3.2 Proxy类讲解 4.动态代理V ...

  7. 动态代理的分析以及利用动态代理模式进行敏感词汇过滤

    动态代理 增强对象的功能: 设计模式:一些通用的解决固定问题的方式 代理模式 概念: (1). 真实对象:被代理的对象 (2). 代理对象: (3). 代理模式:代理对象代理真实对象,达到增强真实对象 ...

  8. 【Java】代理模式(静态代理动态代理)

    CONTENT 代理模式 静态代理 动态代理 JDK 动态代理(基于接口) CGLIB 动态代理(基于类继承) JDK 动态代理 v.s. CGLIB 动态代理 JDK 动态代理为什么必须基于接口 R ...

  9. 什么是代理模式?代理模式有什么用?通过一个小程序分析静态代理和动态代理。自己简单实现动态代理。JDK动态代理和CGLIB动态代理的区别。

    1. 代理模式有什么用 ①功能增强,在实现目标功能的基础上,又增加了额外功能.就像生活中的中介一样,他跟两边客户会有私下的交流. ②控制访问,代理不让用户直接和目标接触.就像中间商一样,他们不会让我们 ...

  10. Java的代理模式之静态代理和动态代理

    文章目录 静态代理 动态代理 jdk生成代理对象 cglib代理 代理模式简介: 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目 ...

最新文章

  1. Python测试框架pytest(03)setup和teardown
  2. 从命令行运行 MyBatis Generator
  3. 你应该如何正确健壮后端服务?
  4. WGAN的提出背景以及解决方案
  5. 摄像头poe供电原理_弱电知识之六:跟我学做监控,认识POE交换机与POE监控摄像头...
  6. mysql中ifnull和hive中if函数的转换
  7. 袋鼠云大数据面试题回忆
  8. 网络监控系统安装的4种方式,安防必备
  9. surface php老是用不了,surface pro7触摸屏没反应怎么办
  10. 云数据库mysql 慢查询_Mysql慢查询
  11. css 设置input输入内缩进
  12. Struts2基本的执行过程
  13. 干掉visio,这个画图神器太香了
  14. 算法基础:NP完全问题
  15. 摄像头-MIPI接口、DVP接口和CSI接口
  16. 银行业务模拟系统(C/C++实现内含详细注释)
  17. ODM、JDM、OBM 、OEM概念的区别与理解
  18. 泰坦尼克号各种因素对存活率的影响
  19. 彻底卸载360画报(流氓屏保软件)---亲测有效
  20. js网页进度条等待特效

热门文章

  1. Windows 注册表开机启动总结
  2. 贪心 - Dota2 参议院
  3. CF-1207 F. Remainder Problem(分块)
  4. forward_list的insert操作
  5. 概率论-1.3 概率的性质(重点:可列与极限之间的互相转换)
  6. 21.3 共享受限的资源
  7. context:component-scan/和mvc:annotation-driven/的区别
  8. JAVA操作HDFS API(hadoop)
  9. java中堆栈(stack)和堆(heap)
  10. aop-xml-环绕增强