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开发者准备的深度学习书籍,它涵盖了Java编程语言的核心概念、高级特性以及实战应用。通过这本书,读者可以深入理解Java的内部机制,提升编程技能,实现从初级到高级的跨越。下面...
6. **反射与动态代理**:Java反射机制允许在运行时检查和修改程序的行为,动态代理则用于实现AOP(面向切面编程)等高级功能。 7. **Java内存模型**:介绍Java内存模型(JMM),它是理解和解决并发问题的关键,包括...
最后,书中的"深度历险"可能涵盖了一些高级主题,如Java反射、动态代理、JNI(Java Native Interface)和JVM优化技术。反射允许在运行时检查和修改类的结构,动态代理则可以实现动态地创建具有特定行为的代理类。JNI...
《Java深度历险》这本书是为那些希望深入了解Java平台运行机制的初学者和有经验的开发者准备的。它深入探讨了Java技术的核心概念,揭示了Java如何在幕后工作,帮助读者提升对Java语言的理解和应用能力。 1. **Java...
Java深度学习项目 这是Packt发布的的代码存储库。 使用Deeplearning4j和开源API实施10个真实世界的深度学习应用程序 这本书是关于什么的? Java是最广泛使用的编程语言之一。 随着深度学习的兴起,它已成为数据...
- **反射与动态代理**:反射允许程序在运行时检查和修改类的属性和方法,动态代理则用于创建接口的代理实现,常用于AOP(面向切面编程)和拦截器。 - **泛型**:泛型引入了类型安全,允许在编译时检查类型,减少...
7. **反射机制**:反射是Java强大的特性,能动态获取类的信息并操作类的对象。面试中可能会涉及Class类的使用,newInstance(),getMethod(),getField()等方法。 8. **JVM**:理解Java虚拟机的工作原理,包括内存...
其次,可能会深入探讨Java反射机制和动态代理,这两个特性让Java在运行时具有了强大的元数据操作能力和动态代码生成能力,广泛应用于框架开发和测试工具中。此外,书中也可能涉及Java的异常处理机制、错误与异常的...
8. **反射与动态代理**:Java的反射机制允许在运行时检查类、接口、字段和方法,而动态代理则可以用于实现AOP(面向切面编程)等高级功能。这部分内容通常对框架开发者尤其重要。 9. **Java泛型**:泛型引入了类型...
7. **反射与动态代理**:讲解如何在运行时检查和修改类的行为,以及如何实现动态代理。 8. **多线程编程**:涵盖线程同步、并发工具类和线程池的使用。 9. **I/O与NIO**:介绍Java的输入输出系统,包括传统I/O和非...
在构建基于Springboot的深度学习计算与存储服务中,整合MySQL、Redis和RabbitMQ是常见且高效的设计方案。这四个技术组件各自扮演着关键的角色,共同构建了一个强大的分布式系统。 首先,Springboot是一个轻量级的...
Java开发者应该熟悉单例、工厂、观察者、装饰器、适配器、策略、代理等经典设计模式。了解并熟练运用设计模式可以提高代码的可读性、可维护性和可扩展性。 5. **Excel技巧**:在数据分析或项目管理中,Excel往往被...
在Java的世界里,深度学习意味着不仅要掌握基本语法,还要理解其内在机制。本书可能会探讨以下几个核心主题: 1. **面向对象编程**:Java是一种典型的面向对象编程语言,书中的内容可能包括类、对象、封装、继承、...
总而言之,Java深度探索是一场不断学习和实践的过程。通过理解和掌握这些知识点,我们可以更好地驾驭这门语言,构建出高效、稳定、可维护的软件系统。无论你是初学者还是经验丰富的开发者,持续深化Java的学习都是...
《Java深度历险》是由知名Java专家王森撰写的一本高级Java学习书籍,由McGraw Hill出版社出版。这本书旨在帮助已经掌握了Java基础知识的开发者深入理解Java语言的精髓,提升编程技能,从而在实际开发中更好地应用...
《Java深度历险》是一本面向已有基础的Java程序员的高级读物,...通过深入学习和实践《Java深度历险》中的这些知识点,Java开发者可以提升自己的技术水平,更好地应对复杂项目和挑战,实现高效、稳定和可维护的代码。
- AOP(面向切面编程),动态代理等。 9. **注意事项**: - 使用反射时需处理`ClassNotFoundException`, `IllegalAccessException`, `InstantiationException`等异常。 - 反射可能导致代码难以理解和维护,应...
以上是Java常见笔试面试题目所涵盖的主要知识点,通过深入学习和实践,可以提高Java程序员的专业技能和面试竞争力。在面试中,不仅要能够准确回答问题,还要能结合实际项目经验进行案例分析,展现自己的问题解决能力...