Java动态代理类使用
Java动态代理类使用
Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
一、Interface InvocationHandler:该接口中仅定义了一个方法
Object invoke(Object obj,Method method,Object[] args)
。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。二、Proxy:该类即为动态代理类,其中主要包含以下内容:
Protected Proxy(InvocationHandler h)
:构造函数,用于给内部的h赋值。
static Class getProxyClass (ClassLoader loader,Class[] interfaces)
:获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
:返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。在使用动态代理类时,我们必须实现InvocationHandler接口.
代理机制及特点
通过实现 InvocationHandler 接口创建自己的调用处理器;
通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
——参考《百度百科》
Proxy类
一般使用Proxy.newProxylnstance(ClassLoader loader,Class[] interfaces,InvocationHandler invocationHandler)
来创建代理对象
- 参数1:
loader
, 类加载器, 动态代理类运行时创建, 任何类都需要类加载器将其加载到内存。- 一般情况:
被代理类.class.getClassLoader()
或者被代理类实例.getClass().getClassLoader()
- 一般情况:
- 参数2:
interfaces
代理类需要实现的所有接口。- 方式1:
被代理类实例.getClass().getInterfaces()
- 注意: 只能获得自己接口, 不能获得父元素接口
- 方式2:
new Class[]{ 被代理类.class }
- 例如:jdbc驱动 –> DriverManager 获得接口 Connection
- 方式1:
- 参数3:
invocationHandler
处理接口, 一般采用匿名内部类实现。- 提供
invoke
方法,代理类的每一个方法执行时, 都将调用一次invoke
方法 Object invoke(Object obj,Method method,Object[] args)
- 参数1:
proxy
: 代理对象 - 参数2:
method
: 代理对象当前执行的方法的描述对象(反射)- 获取方法名:
method.getName()
- 执行方法:
method.invoke(对象, 实际参数)
- 获取方法名:
- 参数3:
args
: 方法实际参数
- 参数1:
- 提供
使用步骤
- 创建 被增强对象【被代理对象】
- 创建 增强对象 【代理对象】
- 通过被代理对象获取类加载器
被代理对象.getClass().getClassLoader()
- 通过被代理对象获取其所有的接口
被代理对象.getClass().getInterfaces()
- 创建一个处理类 【专门用来增强方法】
- 通过被代理对象获取类加载器
PS:动态代理技术实现的是接口中方法的代理,如果接口中没有的方法,动态代理是没法增强的!
案例:编码问题动态代理解决
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>首页</title></head><body><h1>get请求</h1><form action="${pageContext.request.contextPath}/EncodingServlet" method="get"><input type="text" name="username" /><br/><input type="submit" value="提交"/></form><br/><h1>post请求</h1><form action="${pageContext.request.contextPath}/EncodingServlet" method="post"><input type="text" name="username" /><br/><input type="submit" value="提交"/></form></body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
EncodingFilter.java
package com.pc.web.filter;import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;import javax.servlet.Filter;
import javax.servlet.FilterChain;import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 编码过滤器,使用动态代理解决编码问题* * @author Switch* @data 2016年10月25日* @version V1.0*/
public class EncodingFilter implements Filter {public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {final HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse res = (HttpServletResponse) response;// 处理POST乱码问题req.setCharacterEncoding("utf-8");// 处理GET乱码问题// 创建HttpServletRequest代理对象// 参数1:ClassLoader loader 该代理类的类加载器// 参数2:Class<?>[] interfaces 该代理类的接口// 参数3:InvocationHandler h 代理实例的调用处理程序 实现的接口HttpServletRequest reqProxyInstance = (HttpServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {// 参数1:Object proxy 代理实例// 参数2:Method method 某一方法// 参数3:Object[] args 参数列表@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 当当前方法是"getParameter"时,增强该方法if ("getParameter".equals(method.getName())) {// 反射获取"getParameter"方法的返回值String value = (String) method.invoke(req, args);// GET请求方式则处理乱码问题if ("GET".equalsIgnoreCase(req.getMethod())) {value = new String(value.getBytes("iso8859-1"), "utf-8");}// 返回该值return value;}// 返回其他方法的值,并没有进行处理(增强)return method.invoke(req, args);}});// 放行,使用动态代理对象chain.doFilter(reqProxyInstance, res);}public void init(FilterConfig fConfig) throws ServletException {}public void destroy() {}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
EncodingServlet.java
package com.pc.web.servlet;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 编码测试Servlet* * @author Switch* @data 2016年10月25日* @version V1.0*/
public class EncodingServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");String username = request.getParameter("username");System.out.println(username);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");String username = request.getParameter("username");System.out.println(username);}}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
PS:编码问题的装饰者解决:过滤器Filter
from: http://blog.csdn.net/q547550831/article/details/52924724
Java动态代理类使用相关推荐
- 初看Mybatis 源码 (二) Java动态代理类
先抛出一个问题,用过Mybatis的都知道,我们只需要定义一个Dao的接口,在里面写上一些CRUD相关操作,然后配置一下sql映射文件,就可以达到调用接口中的方法,然后执行sql语句的效果,为什么呢? ...
- Java之动态代理类实现日志简单实例
开心一笑 上课呢,同桌撕了一片纸放嘴里了咬了咬,又吐回了手里. 揉了揉,揉成个球状,然后又把这东西给放嘴里,咽下去了. 我问:你干嘛呢? 这二货幽幽地说:这两天有点感冒,捏个药丸吃. 视频教程 大家好 ...
- java动态代理上是否能再进行一层代理
CGLIB动态代理类 import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.p ...
- Java 动态代理机制分析及扩展--转
http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...
- Java 动态代理机制分析及扩展,第 1 部分
引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...
- Java 动态代理机制分析及扩展
简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java 动态代理运作过程,希望能帮助读者加深对 Java 动 ...
- 【转】浅析动态代理类实现过程
代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 代理模式一般涉及到 ...
- java动态代理模式初解
第一部分 1.代理模式的作用和定义: 为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 2.代 ...
- Java动态代理实现(转载\整理)
在深入解析MapReduce架构设计与实现原理一书中读到动态代理这个东东. 代理是一种常用的设计模式,其目的是为其他对象提供一种代理一控制对这个对象的访问.代理类负责为委托类进行预处理(如安全检查.权 ...
最新文章
- DB2更改数据文件路径
- 计算机硬件:内存条的基础知识笔记
- 《面向对象的思考过程(原书第4版)》一 导读
- 中国经济蓝皮书发布 该死的房价下降成定局
- 麒麟810怎么样_麒麟810+6G+128G+大电池,千元价格的手机上手体验
- MySQL心得1--数据库的基本概念
- Geodetector软件下载、地理探测器的应用实践与结果解读
- ps随机排列_[PS]圆点随机不重叠排列脚本
- Freeswitch的Proxy(代理转发)模式和Bypass(旁路)模式的正确配置
- 拼多多新店扶持期是多久?
- Hutool进行DES加解密
- Aria2 ,下载神器
- redis缓存穿透和缓存雪崩的浅析以及解决方案
- prometheus启动报错Unit prometheus.service entered failed state.
- 大数据——Redshift通过UDF函数实现金融业XIRR函数
- Windows 10下无法安装 CAD 2013/2014的解决方法
- ALS冰桶挑战案例详解
- 干选机的工作原理与维护
- (转)CSS3之pointer-events(屏蔽鼠标事件)属性说明
- 网页分段视频下载并将多个ts文件合并