我自己的总结:
1.jdk动态代理要解决的问题是什么呢?说白了就是在调用我们的方法前后做些其它处理,如日志,性能监测,事务管理等。而这些操作一般都是批量,所有的service,所有的方法。因此Spring的AOP将它应用地非常好。
2.那jdk如何实现动态代理呢?它主要有两个东西,
一个是InvocationHandler接口,它就一个方法invoke,我们实现这个接口这个方法,在这个方法加上业务之外的操作如日志等,并且根据传入的参数调用我们本身的业务实现,然后它会被proxy生成的代理类来调用。
第二个是Proxy类,它提供了静态的方法newProxyInstance帮我们生成代理类,我们传入要代理的接口,及被代理执行的InvocationHandler实现类。
3.jdk动态代理只能代理接口,而Spring可以代理普通类,它用的cglib来实现的。
4.Spring的AOP实现原理其实就是jdk的动态代理,所以理解了动态代码,AOP就好理解了。
没事的时候翻看lang.reflect包下的代码,发现有两部分内容:涉及反射和动态代理。
很多地方都可以看到动态代理的影子,只是一直没仔细看下。
在学习之前,先提出几个问题,带着问题来看代码:
1.什么是动态代理?
2.为什么使用动态代理?
3.使用它有哪些好处?
4.哪些地方需要动态代理?
--------------------分隔线-----------------------------
和动态代理有关的有两个类
1.interface InvocationHandler
Object invoke(Object proxy, Method method, Object[] args)
只这一个方法,后面再说
2.class Proxy
真正表示动态代理的类,提供两个静态方法:
Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface)
用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,
用来冒充真实的对象。
Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),
它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法,
invoke方法就是我们用来做N多事情的地方 -_-。
--------------------分隔线-----------------------------
看完上面的代码,大致明白动态代理的含义:
A接口有c方法,类B实现A接口,原本应该是执行B类中的c方法,可现在不这样做;
我声明产生B类的代理类B',由它来冒充B类的“兄弟”并“实现”A接口,
对外界来说B'应该也有c方法,可当真正调用它的时候,
它会去执行与它关联InvocationHandler的invoke()方法,
在这个方法里面你可以做很多事情。这样,这个请求就被“代理”到其它地方去了。
下面是根据我的理解画的一个说明图
--------------------分隔线-----------------------------
引用网上的一个例子来说明问题(有部分改动,转载自:http://callan.iteye.com/blog/161806)
真实的接口:
- public interface Hello {
- void sayHello(String to);
- void print(String p);
- }
它的真实实现类:
- public class HelloImpl implements Hello {
- public void sayHello(String to) {
- System.out.println("Say hello to " + to);
- }
- public void print(String s) {
- System.out.println("print : " + s);
- }
- }
在这里生成与代理类相关联的InvocationHandler对象
- public class LogHandler implements InvocationHandler {
- private Object dele;
- public LogHandler(Object obj) {
- this.dele = obj;
- }
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- doBefore();
- //在这里完全可以把下面这句注释掉,而做一些其它的事情
- Object result = method.invoke(dele, args);
- after();
- return result;
- }
- private void doBefore() {
- System.out.println("before....");
- }
- private void after() {
- System.out.println("after....");
- }
- }
最后是测试类:
- public class ProxyTest {
- public static void main(String[] args) {
- HelloImpl impl = new HelloImpl();
- LogHandler handler = new LogHandler(impl);
- //这里把handler与impl新生成的代理类相关联
- Hello hello = (Hello) Proxy.newProxyInstance(impl.getClass().getClassLoader(), impl.getClass().getInterfaces(), handler);
- //这里无论访问哪个方法,都是会把请求转发到handler.invoke
- hello.print("All the test");
- hello.sayHello("Denny");
- }
- }
这里是输出结果:
- before....
- print : All the test
- after....
- before....
- Say hello to Denny
- after....
--------------------分隔线-----------------------------
最后试着来回答之前提出的问题:
1.什么是动态代理?
一种用于转发请求,进行特殊处理的机制,“动态”应该指的是“运行期”。
2.为什么使用动态代理?
可以对请求进行任何处理(如事务,日志等,这都是网上说的,我当然可以做任何处理)
3.使用它有哪些好处?
如上
4.哪些地方需要动态代理?
不允许直接访问某些类;对访问要做特殊处理等,我只能想到这些。
--------------------分隔线-----------------------------
其它一些想法:
1.如果想声明产生B类的代理类,那个B类必须要实现接口,如果没有接口,
代理类就不能伪装成B类的“兄弟”,也就没有存在的意思,
其实也可以伪装成B类的“孩子”,对外他们有共同的接口,可以这样做吧?
2.当请求代理类的方法时,这个请求会被转到执行与代理类关联InvocationHandler
的invoke方法。那InvocationHandler到底是什么?对它的理解可以是这样:
它用来处理方法的调用,实现类也有同样的意义;与代理类对象相关联则表示,
它就是负责处理代理类应该有的动作,把所有的方法请求分发到invoke这个方法上。
--------------------分隔线-----------------------------
学习后总结,既可以全面地观察分析,又能加深印象。
如果我的理解有误,别人的指证会对我产生积极影响。
如果我的理解正确,帮助其它人理解是我的荣幸。
初学者,请多多指教。
相关推荐
JDK动态代理是一种在运行时动态创建代理类和代理对象的技术,主要用来实现对目标对象的方法调用进行增强,例如添加日志、事务控制等通用功能,而无需修改目标对象的代码。动态代理可以帮助我们达到更好的解耦合效果...
Java JDK6学习笔记是针对Java编程语言初学者和进阶者的一份宝贵资源,它涵盖了Java的基础语法,并通过经典且易于理解的实例进行讲解。在本文中,我们将深入探讨Java JDK6中的关键概念和特性,以帮助你更好地理解和...
4. **动态代理改进**:JDK1.6增强了动态代理的实现,允许在运行时创建接口的代理类,这对于AOP(面向切面编程)和其他设计模式的应用有重大意义。 5. **并发编程支持**:引入了`java.util.concurrent`包,包含各种...
Java JDK 6学习笔记是为Java初学者量身定制的一份宝贵资料,它涵盖了Java编程的基础概念、语法以及核心特性。这份PPT简体版旨在帮助读者快速掌握Java开发的基本技能,逐步成为一名合格的Java程序员。 Java JDK...
**Java JDK学习笔记** 在Java开发领域,JDK(Java Development Kit)是不可或缺的基础工具,它包含了Java编译器、Java运行环境以及一系列用于开发和调试Java应用的工具。林信良是一位知名的Java专家,他的JDK学习...
4. **动态代理增强**:Java动态代理在JDK 6中得到增强,允许开发者创建接口的代理类,动态实现这些接口并在运行时添加方法调用处理。 5. **脚本支持**:JDK 6引入了JSR 223,即脚本引擎接口,支持JavaScript和其他...
Java JDK 6学习笔记是Java开发者入门和进阶的重要参考资料,由知名作者林信良编著。本笔记主要涵盖了JDK 6版本的核心特性和关键概念,为读者提供了全面而深入的学习路径。以下是对其中重要知识点的详细阐述: 1. **...
Java JDK 6学习笔记课件是由知名讲师林学良教授的一套系统性的Java编程教程,主要针对初学者和有一定基础的开发者,旨在帮助他们深入理解Java语言和JDK 6的相关特性。本教程覆盖了Java语言的基础语法、面向对象编程...
以上只是部分JDK 6中的重要知识点,实际的学习笔记可能还包括更多的内容,如垃圾收集的优化、编译器的改进、JVM的调整选项等。通过深入学习这些知识点,开发者可以更好地利用JDK 6进行高效的Java程序开发。
**4.1 JDK动态代理**:基于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。`Proxy.newProxyInstance()`方法用于创建代理对象,而`InvocationHandler`则定义了代理对象的行为。 **...
通过阅读《Java JDK 1.60学习笔记.chm》这样的资源,开发者可以深入学习这些主题,进一步提升自己的Java编程能力。这份文档可能涵盖了所有这些知识点的详细讲解,以及实例代码和最佳实践,对于初学者和经验丰富的...
在本篇Spring学习笔记中,我们将深入探讨动态代理模式,并结合Spring框架的实现进行分析演示。动态代理模式是Java编程中一种重要的设计模式,它允许我们在不修改原对象代码的情况下,为对象添加额外的功能或行为。...
《Java JDK 7学习笔记》详细介绍了JVM、JRE、Java SE API、JDK与IDE之间的对应关系。必须要时从Java SE API的源代码分析,了解各种语法在Java SE API中如何应用。 《Java JDK 7学习笔记》将IDE操作纳为教学内容...
**JDK 6学习笔记——PPT简体版** Java Development Kit(JDK)是Java编程语言的核心组件,它提供了开发和运行Java应用程序所需的工具和环境。JDK 6是Oracle公司发布的一个重要版本,为开发者带来了许多改进和新特性...
3. **动态代理**:JDK6增加了对动态代理的支持,使得在运行时创建接口代理类变得更加简单,这对于实现AOP(面向切面编程)或者事件监听等场景非常有用。 4. **NIO.2**:新I/O API(NIO.2)引入了对文件系统操作的...
这为反射和动态代理提供了基础。 8. **枚举常量的比较(Enum Constants Comparison)** 在Java 5.0中,可以直接使用`==`来比较两个枚举常量是否相等,无需调用`equals()`方法,这增强了枚举的使用体验。 9. **可...