jdk动态代理的实现原理

深碍√TFBOYSˉ_ 2022-10-14 05:26 296阅读 0赞
  1. 先写一个jdk动态代理的例子
  2. 1.先定义一个接口
  3. public interface MyService {
  4. void print();
  5. }
  6. 2.定义一个实现类
  7. public class MyServiceImpl implements MyService{
  8. @Override
  9. public void print() {
  10. System.out.println("原始方法");
  11. }
  12. }
  13. 3.实现InvocationHandler接口,实现增强逻辑
  14. public class JdkInvocation implements InvocationHandler {
  15. private Object object;
  16. public JdkInvocation(Object object) {
  17. this.object = object;
  18. }
  19. @Override
  20. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  21. System.out.println("处理前");
  22. Object value = method.invoke(object, args);
  23. System.out.println("处理后");
  24. return value;
  25. }
  26. }
  27. 4.测试
  28. public class TestProxy {
  29. public static void main(String[] args) {
  30. System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
  31. MyService myService = new MyServiceImpl();
  32. MyService proxy = (MyService) Proxy.newProxyInstance(myService.getClass().getClassLoader(), new Class[] {MyService.class}
  33. , new JdkInvocation(myService));
  34. proxy.print();
  35. }
  36. }
  37. 5.查看生成的代理类
  38. public final class $Proxy0 extends Proxy implements MyService {
  39. private static Method m1;
  40. private static Method m3;
  41. private static Method m2;
  42. private static Method m0;
  43. public $Proxy0(InvocationHandler var1) throws {
  44. super(var1);
  45. }
  46. public final boolean equals(Object var1) throws {
  47. try {
  48. return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
  49. } catch (RuntimeException | Error var3) {
  50. throw var3;
  51. } catch (Throwable var4) {
  52. throw new UndeclaredThrowableException(var4);
  53. }
  54. }
  55. public final void print() throws {
  56. try {
  57. super.h.invoke(this, m3, (Object[])null);
  58. } catch (RuntimeException | Error var2) {
  59. throw var2;
  60. } catch (Throwable var3) {
  61. throw new UndeclaredThrowableException(var3);
  62. }
  63. }
  64. public final String toString() throws {
  65. try {
  66. return (String)super.h.invoke(this, m2, (Object[])null);
  67. } catch (RuntimeException | Error var2) {
  68. throw var2;
  69. } catch (Throwable var3) {
  70. throw new UndeclaredThrowableException(var3);
  71. }
  72. }
  73. public final int hashCode() throws {
  74. try {
  75. return (Integer)super.h.invoke(this, m0, (Object[])null);
  76. } catch (RuntimeException | Error var2) {
  77. throw var2;
  78. } catch (Throwable var3) {
  79. throw new UndeclaredThrowableException(var3);
  80. }
  81. }
  82. static {
  83. try {
  84. m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
  85. m3 = Class.forName("com.example.demo.proxy.MyService").getMethod("print");
  86. m2 = Class.forName("java.lang.Object").getMethod("toString");
  87. m0 = Class.forName("java.lang.Object").getMethod("hashCode");
  88. } catch (NoSuchMethodException var2) {
  89. throw new NoSuchMethodError(var2.getMessage());
  90. } catch (ClassNotFoundException var3) {
  91. throw new NoClassDefFoundError(var3.getMessage());
  92. }
  93. }
  94. }

从生成的代理类的实现可以看到,代理类继承了Proxy类,并实现了我们定义的接口,其中通过构造方法将我们实现InvocationHandler接口的增强类注入进去。

1.因为java是单继承的,所以jdk动态代理只能适用于实现了接口的类。

2.spring中是如何实现通知的

  1. public class JdkInvocation implements InvocationHandler {
  2. private Object object;
  3. public JdkInvocation(Object object) {
  4. this.object = object;
  5. }
  6. @Override
  7. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  8. Object value = null;
  9. //beforeAdvise(前置通知)
  10. try {
  11. //aroundAdvise(环绕通知)
  12. value = method.invoke(object, args);
  13. //aroundAdvise(环绕通知)
  14. System.out.println("处理后");
  15. }catch (Throwable t) {
  16. //afterThrowingAdvise(异常通知)
  17. }finally {
  18. //afterReturningAdvise(返回值通知)
  19. }
  20. return value;
  21. }
  22. }

发表评论

表情:
评论列表 (有 0 条评论,296人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JDK动态代理实现原理

    之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白。比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的,直到前几个星期才把

    相关 jdk动态代理实现原理

    jdk动态代理实际上是jvm帮我们建成的类实现我们传入的接口,加载字节码到jvm。实际上就是帮我们拼接的字符串和我们传进去的接口进行拼接,然后生成字节码加载进虚拟机。代理类持有

    相关 jdk动态代理实现原理总结

    运行时创建一个代理对象的步骤为 1. 生成代理类的字节码 2. 加载字节码,创建代理对象 首先,代理对象的目的是在被调用方法的时候既能实现被代理对象的方法,又能够增加自