`
Junjiejkl
  • 浏览: 61862 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java 动态代理深度学习

阅读更多
java 动态代理深度学习,

一.相关类及其方法:

java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序
(详见api文档)

java.lang.reflect.InvocationHandler,
InvocationHandler 是代理实例的调用处理程序 实现的接口。
invoke()
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
(详见api文档)

二.源代码:

被代理对象的接口及实现类:
package com.ml.test;

public interface Manager {
public void modify();
}

package com.ml.test;

public class ManagerImpl implements Manager {

@Override
public void modify() {
   System.out.println("*******modify()方法被调用");
}
}

业务代理类:
package com.ml.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class BusinessHandler implements InvocationHandler {

private Object object = null;

public BusinessHandler(Object object) {
   this.object = object;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
   System.out.println("do something before method");
   Object ret = method.invoke(this.object, args);
   System.out.println("do something after method");
   return ret;

}
}



客户端类:
package com.ml.test;
import java.lang.reflect.Proxy;
public class Client {

public static void main(String[] args) {
   // 元对象(被代理对象)
   ManagerImpl managerImpl = new ManagerImpl();

   // 业务代理类
   BusinessHandler securityHandler = new BusinessHandler(managerImpl);

   // 获得代理类($Proxy0 extends Proxy implements Manager)的实例.
   Manager managerProxy = (Manager) Proxy.newProxyInstance(managerImpl
     .getClass().getClassLoader(), managerImpl.getClass()
     .getInterfaces(), securityHandler);

   managerProxy.modify();
}
}

三.执行结果:
do something before method
*******modify()方法被调用
do something after method

四.机制分析:

Proxy.(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy.
$Proxy0类实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把BusinessHandler传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
class Proxy{
   InvocationHandler h=null;
   protected Proxy(InvocationHandler h) {
    this.h = h;
   }
   ...
}



下面是本例的$Proxy0类的源码(好不容易才把它提出来):


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 Manager {

private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;

static {
   try {
    m1 = Class.forName("java.lang.Object").getMethod("equals",
      new Class[] { Class.forName("java.lang.Object") });
    m0 = Class.forName("java.lang.Object").getMethod("hashCode",
      new Class[0]);
    m3 = Class.forName("com.ml.test.Manager").getMethod("modify",
      new Class[0]);
    m2 = Class.forName("java.lang.Object").getMethod("toString",
      new Class[0]);
   } catch (NoSuchMethodException nosuchmethodexception) {
    throw new NoSuchMethodError(nosuchmethodexception.getMessage());
   } catch (ClassNotFoundException classnotfoundexception) {
    throw new NoClassDefFoundError(classnotfoundexception.getMessage());
   }
}

public $Proxy0(InvocationHandler invocationhandler) {
   super(invocationhandler);
}

@Override
public final boolean equals(Object obj) {
   try {
    return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))
      .booleanValue();
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

@Override
public final int hashCode() {
   try {
    return ((Integer) super.h.invoke(this, m0, null)).intValue();
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

public final void modify() {
   try {
    super.h.invoke(this, m3, null);
    return;
   } catch (Error e) {
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}

@Override
public final String toString() {
   try {
    return (String) super.h.invoke(this, m2, null);
   } catch (Throwable throwable) {
    throw new UndeclaredThrowableException(throwable);
   }
}
}

接着把得到的$Proxy0实例强制转换成Manager.
当执行managerProxy.modify()方法时,就调用了$Proxy0类中的modify()方法.
在modify方法中,调用父类Proxy中的h的invoke()方法.
即InvocationHandler.invoke();

注意:
代理类在调用hashCode、equals 或 toString 这三个方法的时候是直接调用自己从Object类身上继承的方法,而不是调用InvocationHandler身上的方法。除了这三个方法之外,其他的方法都是调用InvocationHandler身上的invoke方法。
分享到:
评论

相关推荐

    java语言反射与动态代理学习笔记

    ### Java语言反射与动态代理深度解析 #### 一、Java反射机制详解 Java反射机制是Java编程语言的一个强大特性,允许程序在运行时检查和修改自身结构与行为。这一机制为开发人员提供了高度的灵活性,尤其是在框架...

    Java 深度历险.pdf

    《Java 深度历险》是一本专为Java开发者准备的深度学习书籍,它涵盖了Java编程语言的核心概念、高级特性以及实战应用。通过这本书,读者可以深入理解Java的内部机制,提升编程技能,实现从初级到高级的跨越。下面...

    java深度历险+深入java虚拟机

    6. **反射与动态代理**:Java反射机制允许在运行时检查和修改程序的行为,动态代理则用于实现AOP(面向切面编程)等高级功能。 7. **Java内存模型**:介绍Java内存模型(JMM),它是理解和解决并发问题的关键,包括...

    Java深度历险-完整版

    最后,书中的"深度历险"可能涵盖了一些高级主题,如Java反射、动态代理、JNI(Java Native Interface)和JVM优化技术。反射允许在运行时检查和修改类的结构,动态代理则可以实现动态地创建具有特定行为的代理类。JNI...

    Java深度历险

    《Java深度历险》这本书是为那些希望深入了解Java平台运行机制的初学者和有经验的开发者准备的。它深入探讨了Java技术的核心概念,揭示了Java如何在幕后工作,帮助读者提升对Java语言的理解和应用能力。 1. **Java...

    Java-Deep-Learning-Projects:Packt发布的Java深度学习项目

    Java深度学习项目 这是Packt发布的的代码存储库。 使用Deeplearning4j和开源API实施10个真实世界的深度学习应用程序 这本书是关于什么的? Java是最广泛使用的编程语言之一。 随着深度学习的兴起,它已成为数据...

    java 深度历险

    - **反射与动态代理**:反射允许程序在运行时检查和修改类的属性和方法,动态代理则用于创建接口的代理实现,常用于AOP(面向切面编程)和拦截器。 - **泛型**:泛型引入了类型安全,允许在编译时检查类型,减少...

    Java常见笔试、面试题目深度剖析

    7. **反射机制**:反射是Java强大的特性,能动态获取类的信息并操作类的对象。面试中可能会涉及Class类的使用,newInstance(),getMethod(),getField()等方法。 8. **JVM**:理解Java虚拟机的工作原理,包括内存...

    JAVA2深度历险.pdf

    其次,可能会深入探讨Java反射机制和动态代理,这两个特性让Java在运行时具有了强大的元数据操作能力和动态代码生成能力,广泛应用于框架开发和测试工具中。此外,书中也可能涉及Java的异常处理机制、错误与异常的...

    JAVA2深度历险(王森)

    8. **反射与动态代理**:Java的反射机制允许在运行时检查类、接口、字段和方法,而动态代理则可以用于实现AOP(面向切面编程)等高级功能。这部分内容通常对框架开发者尤其重要。 9. **Java泛型**:泛型引入了类型...

    java深度历险1

    7. **反射与动态代理**:讲解如何在运行时检查和修改类的行为,以及如何实现动态代理。 8. **多线程编程**:涵盖线程同步、并发工具类和线程池的使用。 9. **I/O与NIO**:介绍Java的输入输出系统,包括传统I/O和非...

    基于Springboot+MySQL+Redis+RabbitMQ的深度学习计算&amp;存储服务.zip

    在构建基于Springboot的深度学习计算与存储服务中,整合MySQL、Redis和RabbitMQ是常见且高效的设计方案。这四个技术组件各自扮演着关键的角色,共同构建了一个强大的分布式系统。 首先,Springboot是一个轻量级的...

    Java最全学习资料+面试题+DOS命令+设计模式+Excel技巧+java学习笔记

    Java开发者应该熟悉单例、工厂、观察者、装饰器、适配器、策略、代理等经典设计模式。了解并熟练运用设计模式可以提高代码的可读性、可维护性和可扩展性。 5. **Excel技巧**:在数据分析或项目管理中,Excel往往被...

    java深度历险

    在Java的世界里,深度学习意味着不仅要掌握基本语法,还要理解其内在机制。本书可能会探讨以下几个核心主题: 1. **面向对象编程**:Java是一种典型的面向对象编程语言,书中的内容可能包括类、对象、封装、继承、...

    java深度入险

    总而言之,Java深度探索是一场不断学习和实践的过程。通过理解和掌握这些知识点,我们可以更好地驾驭这门语言,构建出高效、稳定、可维护的软件系统。无论你是初学者还是经验丰富的开发者,持续深化Java的学习都是...

    java深度历险.rar

    《Java深度历险》是由知名Java专家王森撰写的一本高级Java学习书籍,由McGraw Hill出版社出版。这本书旨在帮助已经掌握了Java基础知识的开发者深入理解Java语言的精髓,提升编程技能,从而在实际开发中更好地应用...

    java深度历险-深入讨论java

    《Java深度历险》是一本面向已有基础的Java程序员的高级读物,...通过深入学习和实践《Java深度历险》中的这些知识点,Java开发者可以提升自己的技术水平,更好地应对复杂项目和挑战,实现高效、稳定和可维护的代码。

    Java常见笔试、面试系列深度剖析第三讲

    - AOP(面向切面编程),动态代理等。 9. **注意事项**: - 使用反射时需处理`ClassNotFoundException`, `IllegalAccessException`, `InstantiationException`等异常。 - 反射可能导致代码难以理解和维护,应...

    Java常见笔试面试题目深度剖析

    以上是Java常见笔试面试题目所涵盖的主要知识点,通过深入学习和实践,可以提高Java程序员的专业技能和面试竞争力。在面试中,不仅要能够准确回答问题,还要能结合实际项目经验进行案例分析,展现自己的问题解决能力...

Global site tag (gtag.js) - Google Analytics