Proxy实现java动态代理
在java设计模式中代理模式的应用比较广泛, 比如我在编写一写web程序时在filter修改request或response时, 而request中并没有相应的set方法, 这样要做到修改就需要使用一个新的类来实现HttpServletRequest接口,将原始的request放入新的类中在新的类中对相应的方法调用原始的方法并由服务器传递给Servlet使得到的不是原始的request而是我做了手脚的request,这样就可以做到在调用处理后的request取值时从中就可以将原始的类的值做修改后再返回。
但是在HttpServletRequest中有很多方法实现起来也很麻烦这样我们就可以使用动态代理。
下面列出动态生成代理要用的类或接口。
公共接口:
代理类和处理程序都需要实现的接口, 使用动态代理定义代理类时不需要实现,可在程序运行时指定.
PublicInterface //自定义公共接口
1 package com.lw.proxy; 2 3 public interface PublicInterface { 4 5 public void defaultMethod(); 6 }
处理程序:
处理程序是实现业务处理的类, 代理类通过调用处理程序的方法来完成相应的业务(如果处理程序有返回值则返回该值),从而在处理程序方法调用之前或之后做出更改.
处理程序需实现InvocationHandler接口, 和 PublicInterface (公共接口),
注意: invoke方法的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package com.lw.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class HandlerClass implements PublicInterface , InvocationHandler{ @Override public void defaultMethod() { // TODO Auto-generated method stub System.out.println( "处理程序方法处理业务" ); } /** * 实现此方法, 在调用这个方法时使用method参数在处理程序对象上调用. */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke( this , args); } } |
代理类:
代理类是现实一系列接口的实现类, 因为是动态的代理类所以在定义时不现实任何接口。
注意:必需要有一个接收实现Invocationhandler接口的构造方法.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package com.lw.proxy; import java.lang.reflect.InvocationHandler; public class ProxyClass { private InvocationHandler handler; public ProxyClass(InvocationHandler handler) { super (); this .handler = handler; } } |
java.lang.reflect.Proxy 此类将生成动态代理类。
Proxy静态方法:
//指定代理类的类加载器, 和代理类需要实现的接口,该方法将返回实现所有指定接口的Class
public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)
//使用这个方法, 将生成代理类的实例。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
主程序 :
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 | package com.lw.proxy; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class TestProxy { public static void main(String[] args) throws Exception { /** * 生成动态代理的class * * 指定动态代理类的类加载器, 和需要实现的接口。 * 返回实现所有指定接口的class。 */ Class<?> cl = Proxy.getProxyClass(ProxyClass. class .getClassLoader(), PublicInterface. class ); //取得接收InvocationHandler参数的构造方法. Constructor<?> con = cl.getConstructor(InvocationHandler. class ); //使用con构建实例,这个实现将实现所有指定的接口 PublicInterface proxyClass = (PublicInterface) con.newInstance( new HandlerClass()); //调用代理方法 proxyClass.defaultMethod(); /** * 构建动态代理类的第二种方法 */ Class[] cls = new Class[]{PublicInterface. class }; ClassLoader loader = ProxyClass. class .getClassLoader(); InvocationHandler h = new HandlerClass(); proxyClass = (PublicInterface) Proxy.newProxyInstance(loader, cls, h ); //调用 proxyClass.defaultMethod(); } } |
以上就构建了一个动态代理程序, 以上程序运行如下图。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端