动态代理 (JDK 动态代理) 小咪咪 2022-02-02 14:09 361阅读 0赞 **动态代理**:** **代理类在程序运行时被创建,这种代理方式称为动态代理 动态代理实现有两种方式,JDK 动态代理和 CGlib 动态代理,本文介绍JDK 动态代理 **JDK 动态代理**:创建动态代理类,实现 InvocationHandler 接口,重写 invoke 方法,在 invoke 方法中通过反射调用被代理类的方法,实现代理。jdk 动态代理只能代理接口,即只能代理接口的实现类 JDK 动态代理示例代码 定义一个接口 package com.jdkdynamicproxy.service; public interface Subject { void proxyMethod(); } 被代理类,实现接口 package com.jdkdynamicproxy.service.impl; import com.jdkdynamicproxy.service.Subject; /** * 被代理类 * @author Administrator */ public class AgentTarget implements Subject { @Override public void proxyMethod() { System.out.println("被代理的方法执行了"); } } 动态代理类,实现 InvocationHandler 接口 package com.jdkdynamicproxy.jdkproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import com.jdkdynamicproxy.service.impl.AgentTarget; /** * 动态代理类,实现 InvocationHandler接口 * @author Administrator */ public class JdkDynamicProxySubject implements InvocationHandler { private AgentTarget agentTarget; public JdkDynamicProxySubject(AgentTarget agentTarget) { this.agentTarget = agentTarget; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //动态代理逻辑 System.out.println("before"); Object res = null; try { //用反射调用被代理类的方法 res = method.invoke(agentTarget, args); }catch (Exception ex){ System.out.println("ex:" + ex.getMessage()); throw ex; }finally { System.out.println("after"); } return res; } } 测试类 package com.jdkdynamicproxy; import java.lang.reflect.Proxy; import com.jdkdynamicproxy.jdkproxy.JdkDynamicProxySubject; import com.jdkdynamicproxy.service.Subject; import com.jdkdynamicproxy.service.impl.AgentTarget; public class JdkDynamicProxyMain { public static void main(String[] args) { //配置系统属性sun.misc.ProxyGenerator.saveGeneratedFile为true,代理类生成时会自动将生成的代理类写入硬盘 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); Subject subject = (Subject) Proxy.newProxyInstance( JdkDynamicProxyMain.class.getClassLoader(), //类加载器 new Class[]{Subject.class} , //代理接口 new JdkDynamicProxySubject(new AgentTarget()) //InvocationHandler对象 ); subject.proxyMethod(); } } 运行如下 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzanp6Y2Jx_size_16_color_FFFFFF_t_70][] 程序运行后,在项目目录下生成了代理类的 class 文件 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzanp6Y2Jx_size_16_color_FFFFFF_t_70 1][] 对生成的 $Proxy0.class 文件进行反编译 package com.sun.proxy; import com.jdkdynamicproxy.service.Subject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class $Proxy0 extends Proxy implements Subject { private static Method m1; private static Method m2; private static Method m3; private static Method m0; public $Proxy0(InvocationHandler var1) throws { super(var1); } public final boolean equals(Object var1) throws { try { return (Boolean)super.h.invoke(this, m1, new Object[]{var1}); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final String toString() throws { try { return (String)super.h.invoke(this, m2, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final void proxyMethod() throws { try { super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final int hashCode() throws { try { return (Integer)super.h.invoke(this, m0, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object")); m2 = Class.forName("java.lang.Object").getMethod("toString"); m3 = Class.forName("com.jdkdynamicproxy.service.Subject").getMethod("proxyMethod"); m0 = Class.forName("java.lang.Object").getMethod("hashCode"); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } } } 可以看到生成的 $Proxy0.class 实现了 Subject 接口,重写 proxyMethod 方法。在重写的 proxyMethod 方法中,去调用 JdkDynamicProxySubject 的 invoke(Object proxy, Method method, Object\[\] args) 方法,实现代理 **整个程序的运行流程**:Proxy.newProxyInstance(JdkDynamicProxyMain.class.getClassLoader(), new Class\[\]\{Subject.class\} , new JdkDynamicProxySubject(new AgentTarget()) ) 创建对象 subject 时,生成了代理类 $Proxy0.class;subject 对象调用proxyMethod 方法时,proxyMethod 方法调用 JdkDynamicProxySubject 的 invoke 方法,invoke 方法中通过反射调用被代理方法,实现动态代理 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzanp6Y2Jx_size_16_color_FFFFFF_t_70]: /images/20220202/127d52e838344700a856c343773d017e.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dzanp6Y2Jx_size_16_color_FFFFFF_t_70 1]: /images/20220202/f45d6e88f53d4742bdce55a9312cdb96.png
还没有评论,来说两句吧...