动态代理

增强对象的功能:

  • 设计模式:一些通用的解决固定问题的方式
  • 代理模式
  • 概念:
    (1). 真实对象:被代理的对象
    (2). 代理对象:
    (3). 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
  • 实现方式:
    (1). 静态代理:有一个类文件描述代理模式
    (2). 动态代理:在内存中形成代理类
  • 动态代理实现步骤:
    ①. 代理对象和真实对象实现相同的接口
    ②. 代理对象 = Proxy.newProxyInstance();
    ③. 使用代理对象调用方法。
    ④. 增强方法

对于代理模式,我们可以举一个简单的例子,例如我们要买一台联想的电脑,之前我们是需要向联想厂家购买的,那么现在有代理商,我们可以通过代理商来购买联想电脑。

首先创建一个接口SaleComputer,定义sale和show方法。

package cn.itcast.proxy;public interface SaleComputer {public String sale(double money);public void show();
}

其次,我们创建一个真实类Lenovo。

package cn.itcast.proxy;
/*** 真实类*/
public class Lenovo implements SaleComputer {@Overridepublic String sale(double money) {System.out.println("花了"+money+"元买了一台联想电脑...");return "联想电脑";}@Overridepublic void show() {System.out.println("展示电脑...");}
}

接下来,我们通过创建ProxyTest类来演示,

package cn.itcast.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class ProxyTest {public static void main(String[] args) {//1.创建真实对象Lenovo lenovo = new Lenovo();//2.动态代理增强lenovo对象/*三个参数:1. 类加载器:真实对象.getClass().getClassLoader()2. 接口数组:真实对象.getClass().getInterfaces()3. 处理器:new InvocationHandler()代理对象proxy_lenovo为Object对象,因为代理对象和真实对象实现相同的接口,所以将其强行转换为SaleComputer接口类型*/SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {/*代理逻辑编写的方法:代理对象调用所有方法都会触发该方法执行。参数:1.proxy:代理对象2.method:代理对象调用的方法,被封装为的对象 -->sale3.args:代理对象调用的方法时,传递实际参数 -->8000.0*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("该方法执行了...");return null;}});//3.调用方法,用代理对象调用String computer = proxy_lenovo.sale(8000);System.out.println(computer);}
}

控制台输出一内容,表明代理对象调用方法会触发invoke方法的执行。

该方法执行了...
null

我们在ProxyTest再调用show类,同样也是可以触发invoke方法执行。

proxy_lenovo.show();

通过上面控制台的输出的null,可以看出调用的sale方法,并没有被调用;也就是说明代理商并没有卖电脑的功能,只是增强联想厂家卖电脑的功能
因此我们要想让其调用,我们可以在invoke方法里面使用真实对象调用

//使用真实对象调用该方法
Object obj = method.invoke(lenovo, args);
return obj;//obj会传递到proxy_lenovo.sale方法执行完后的返回值computer

我们再次运行,我可以通过控制台的输出内容,了解到sale方法被调用了

该方法执行了...
花了8000.0元买了一台联想电脑...
联想电脑

在现实生活中,我们作为买家要花8000元买电脑+鼠标垫(赠品),那么代理商需要抽取一部分费用,假如代理上抽取15%的费用,用85%的费用向厂家购买电脑。
对于上面的这种情况,我们可以通过增强方式在invoke方法中实现,
增强方式:
①. 增强参数列表
②. 增强返回值类型
③. 增强方法体执行逻辑

         @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("该方法执行了...");//判断是否是sale方法if (method.getName().equals("sale")){//1.增强参数double money = (double) args[0];money = money * 0.85;System.out.println("专车接...");//使用真实对象调用该方法String obj = (String) method.invoke(lenovo, money);System.out.println("送货到家...");//2. 增强返回值return obj+"_鼠标垫 ";}else {Object obj = method.invoke(lenovo, args);return obj;}}});

控制台输出为:(其中6800元只是代理商向厂家付的费用)

该方法执行了...
花了6800.0元买了一台联想电脑...
送货到家...
联想电脑_鼠标垫

利用动态代理模式进行敏感词汇过滤

一、需求:

  1. 敏感词汇参考《敏感词汇.txt》,其内容如下:
笨蛋
坏蛋
  1. 如果是敏感词汇,替换为 ***

二、分析:
1. 对request对象进行增强。增强获取参数相关方法
2. 放行。传递代理对象

创建SensitiveWordsFilter将request请求对象中的敏感词汇替换,然后封装到新的request对象中,选择使用增强返回值类型方法的代理模式来实现;需要注意《敏感词汇.txt》文件导入的路径要配置正确。

package cn.itcast.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;/*** 敏感词汇过滤器*/
@WebFilter("/*")
public class SensitiveWordsFilter implements Filter {public void destroy() {}public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {// 1.创建代理对象,增强request的getParameter方法ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 增强getParameter方法if (method.getName().equals("getParameter")){// 增强返回值String value = (String) method.invoke(req, args);if (value != null){for(String str : list){if(value.contains(str)){value = value.replaceAll(str, "***");}}}return value;}return method.invoke(req, args);}});chain.doFilter(proxy_req, resp);}private List<String> list = new ArrayList<String>();    //敏感词汇集合public void init(FilterConfig config) throws ServletException {try {// 获取文件的真实路径ServletContext servletContext = config.getServletContext();String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");// 读取文件BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(realPath),"utf-8"));// 将文件的每一行添加到list集合中String line = null;while((line = br.readLine()) != null){list.add(line);}br.close();System.out.println(list);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

创建一个TestServlet类

package cn.itcast.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String name = request.getParameter("name");String msg = request.getParameter("msg");System.out.println(name + ":" + msg);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}

在浏览器输入以下内容,进行访问

http://localhost:8080/demo_filter_listener/TestServlet?name=张三&msg=你个笨蛋,你个大坏蛋

同时控制台输出以下内容,就会将敏感词汇替换掉

张三:你个***,你个大***

动态代理的分析以及利用动态代理模式进行敏感词汇过滤相关推荐

  1. Filter - 通过拦截器与动态代理实现敏感词汇过滤

    需求:将敏感词汇.txt文件中的词语过滤为 -> "***" 分析: 首先加载文档,将文档中的词汇纳入集合中备用,方便后期比对使用. 使用Proxy动态代理将request对 ...

  2. ligertoolbar 动态加载按钮_Axure利用动态面板实现环形加载进度条

    先来看下效果. 基本原理 上面是组合效果,主要包含三个部分,左半圆.右半圆和中间的百分加载部分.左.右半圆的实现原理很简单,就是利用动态面板的遮挡功能,将一个完整的圆遮挡一半,然后在显示的那一半上面添 ...

  3. oracle动态排序是什么意思,利用动态SQL解决排序问题-数据库专栏,SQL Server

    我们常遇到一个存储过程要做都种排序的情况.通常order by 的条件只有一个固定的,这是远远不够的.需要用一个变量来替换它,而oracle有不能识别order by后面的字符串.该怎么办呢?先看看我 ...

  4. axure内联框架和动态面板_【Axure】动态面板的理解与下拉列表的联动

    刚开始学axure,发现入门还是蛮简单的,所以从现在开始写一些自己体会的内容,以后忘记了也可以来翻阅一下. 因为是入门,所以内容肯定是很简单的,但是本文也不会致力于写教程一样那么详细,还是侧重于自己的 ...

  5. java静态代理与动态代理简单分析

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5860749.html 1.动态代理(Dynamic Proxy) 代理分为静态代理和动态代理 ...

  6. Java 动态代理机制分析及扩展,第 1 部分

    引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...

  7. Java 动态代理机制分析及扩展

    简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java 动态代理运作过程,希望能帮助读者加深对 Java 动 ...

  8. Android 动态代理以及利用动态代理实现 ServiceHook

    这篇博客主要介绍使用 InvocationHandler 这个接口来达到 hook 系统 service ,从而实现一些很有意思特殊功能的详细步骤. 转载请注明出处:http://blog.csdn. ...

  9. Java动态代理原理分析

    JDK动态代理原理分析 interface Foo {void foo(); }class Target implements Foo {@Overridepublic void foo() {Sys ...

最新文章

  1. 聊聊新零售概念与其技术
  2. 不只是华为/阿里/百度/小米/京东,AIoT已然成为资本与新兴企业都认可的赚钱方向...
  3. 第二步:关于布局文件中的大小设置使用问题
  4. 开机logo切换逻辑深入研究
  5. 介绍一下画图小能手matplotlib。
  6. 跑来跑去:假人与AWS Lambda的第一次接触
  7. python随机数模块_python 随机数模块 -- random
  8. Linux查看系统glibc版本号
  9. mysql优化概述2
  10. 【非原创】codeforces 1070C Cloud Computing 【线段树树状数组】
  11. linux下od命令的使用教程,Linux od命令
  12. Python3 Scrapy + Selenium + 阿布云爬取拉钩网学习笔记
  13. layui laydate设置最小时间为当前时间
  14. c++ 头歌实训 第四关 日历打印
  15. 计算机网络时代纪录片,中国首部自媒体纪录片《生机》揭秘新世相
  16. [SWF Investigator] Adobe官方开源 swf解析/编辑工具
  17. Unity教程 | 手把手教你拼一个3D“魔方”
  18. 前端架构--从入门到微前端
  19. 关于阴影映射的那些事,shadow acne(阴影失真)和peter panning(阴影悬浮)
  20. android如何切换主题背景图片,安卓怎么更换主题 安卓手机更换壁纸与主题教程...

热门文章

  1. 林大5.1训练赛补题
  2. ProcessOn一款非常不错在线绘图工具
  3. 【C】【Linux】利用C curses函数库进行终端彩色显示
  4. 微信小程序开发之向组件传值的三种方式
  5. 51单片机流水灯LED
  6. 【Spring Cloud 基础设施搭建系列】Spring Cloud Demo项目 使用Docker Compose编排Spring Cloud微服务
  7. 1117. 单词接龙
  8. 计算机网络操作试题2级,计算机网络管理员操作模拟试题-二级.pdf
  9. android 学生模式,(续上篇)多亲AI助手——学生模式体验小记
  10. JavaScript设计模式----单例模式