一旦这样绑定后,那么在进入代理对象方法调用的时候就会到HelloServiceProxy的invoke方法上,invoke方法有三个参数:第一个proxy是代理对象,第二个是当前调用那个方法,第三个是方法的参数。

2、JDK动态代理

这个动态代理还是不好理解的,我们先用一张图来表达它:

好,它的意义是在我们访问一个对象的时候,动态代理可以给我们生成一个代理对象【占位】,它的作用是可以控制【真实对象】的访问。

比方说,你是未成年人,我可能是是去访问你父母,由你父母来代替你访问你,那么你父母就是这个占位,而你就是真实对象。

在JDK动态代理的要求是对象存在接口,所以真正的服务对象必须存在接口。

假设我们现在有这样的一个服务,我给名字它会说: “hello ”+名字。

那么我们先看看这个接口:

  1. public interface HelloService {
  2. public void sayHello(String name);
  3. }

非常简单的接口,然后我们给出实现类:

  1. public class HelloServiceImpl implements HelloService{
  2. @Override
  3. public void sayHello(String name) {
  4. System.err.println("hello " + name);
  5. }
  6. }

好,它实现了这个接口,并且实现了接口的方法。

现在我们要变变,我希望

在说:hello+name前打印:我准备说hello。

之后打印:我说过hello了

如果采用我们的代理对象【占位】显然实现起来非常容易,于是我们首先来生成这个【占位】

  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Proxy;
  4. public class HelloServiceProxy implements InvocationHandler {
  5. private Object target;
  6. /**
  7. * 绑定委托对象并返回一个【代理占位】
  8. * @param target 真实对象
  9. * @return  代理对象【占位】
  10. */
  11. public  Object bind(Object target, Class[] interfaces) {
  12. this.target = target;
  13. //取得代理对象
  14. <span style="color:#FF0000;"> return Proxy.newProxyInstance(target.getClass().getClassLoader(),
  15. target.getClass().getInterfaces(), this);  </span>
  16. }
  17. @Override
  18. /**
  19. * 同过代理对象调用方法首先进入这个方法.
  20. * @param proxy --代理对象
  21. * @param method -- 方法,被调用方法.
  22. * @param args -- 方法的参数
  23. */
  24. public Object invoke(Object proxy , Method method, Object[] args) throws Throwable {
  25. System.err.println("############我是JDK动态代理################");
  26. Object result = null;
  27. //反射方法前调用
  28. System.err.println("我准备说hello。");
  29. //反射执行方法  相当于调用target.sayHelllo;
  30. result=method.invoke(target, args);
  31. //反射方法后调用.
  32. System.err.println("我说过hello了");
  33. return result;
  34. }
  35. }

这里的bind方法里面有句:

  1. Proxy.newProxyInstance(target.getClass().getClassLoader(),
  2. target.getClass().getInterfaces(), this);

它的意义就是生成一个代理对象,这里有三个参数:第一个参数是类加载器,第二个参数是或者对象的接口(代理对象挂在那个接口下),第三个参数this代表当前HelloServiceProxy类,换句话说是使用HelloServiceProxy作为对象的代理。

一旦这样绑定后,那么在进入代理对象方法调用的时候就会到HelloServiceProxy的invoke方法上,invoke方法有三个参数:第一个proxy是代理对象,第二个是当前调用那个方法,第三个是方法的参数。

比方说,现在HelloServiceImpl对象(obj)用bind方法绑定后,返回其【占位】(proxy),我们在调用proxy.sa6yHello("张三"),那么它就会进入到HelloServiceProxy的invoke()方法。而invoke参数中第一个便是代理对象proxy,方法便是sayHello,参数是"张三"。那么我们就可以通过反射技术调度真实对象的方法。

现在让我们看看测试代码:

  1. public class ProxyTest {
  2. public static void main(String[] args) {
  3. HelloServiceProxy proxy = new HelloServiceProxy();
  4. HelloService service = new HelloServiceImpl();
  5. //绑定代理对象。
  6. service = (HelloService) proxy.bind(service, new Class[] {HelloService.class});
  7. //这里service经过绑定,就会进入invoke方法里面了。
  8. service.sayHello("张三");
  9. }
  10. }

好,我们运行一下,看一下结果。

  1. ############我是JDK动态代理################
  2. 我准备说hello。
  3. hello 张三
  4. 我说过hello了

好了,我们这样就可以看到动态代理。

正确的理解反射和动态代理是我们进行MyBATIS底层的基础,尤其是动态代理,如果还不了解务必要多做上面的例子,切实理解好。

本文转自:http://blog.csdn.net/ykzhen2015/article/details/50312651

jdk动态代理(转)的更多相关文章

  1. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  2. 静态代理和利用反射形成的动态代理(JDK动态代理)

    代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...

  3. Spring中的JDK动态代理

    Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...

  4. AOP学习心得&jdk动态代理与cglib比较

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  5. JDK动态代理的实现原理

    学习JDK动态代理,从源码层次来理解其实现原理参考:http://blog.csdn.net/jiankunking/article/details/52143504

  6. Java中的JDK动态代理

    所谓代理,其实就是相当于一个中间人,当客户端需要服务端的服务时,不是客户直接去找服务,而是客户先去找代理,告诉代理需要什么服务,然后代理再去服务端找服务,最后将结果返回给客户. 在日常生活中,就拿买火 ...

  7. JDK动态代理与CGLib动态代理

    1.JDK动态代理 JDK1.3以后java提供了动态代理技术,允许开发者在运行期创建接口的代理实例,动态代理是实现AOP的绝好底层技术. JDK的动态代理主要涉及到java.lang.reflect ...

  8. jdk动态代理实现

    1.jdk动态代理的简单实现类 package com.proxy; import java.lang.reflect.InvocationHandler; import java.lang.refl ...

  9. java jdk动态代理

    在面试的时候面试题里有一道jdk的动态代理是原理,并给一个事例直接写代码出来,现在再整理一下 jdk动态代理主要是想动态在代码中增加一些功能,不影响现有代码,实现动态代理需要做如下几个操作 1.首先必 ...

  10. JDK动态代理的实现及原理

    Proxy.newProxyInstance(classloader,Class,invocationHandler) 调用getProxyClass0(loader, interfaces)生成代理 ...

随机推荐

  1. Redis,Memcache的区别和具体应用场景

    1. Memcached简介 Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric为首开发的高性能分布式内存缓存服务器.其本质上就是一个 ...

  2. Android开发之使用BroadcastReceiver实现开机自己主动启动(源码分享)

    上一节已经介绍过BroadcastReceiver实现实时监听电量的功能,这节就来介绍一下假设实现开机自己主动启动的功能.这个比监听电量还简单不少 (1)在清单文件注冊权限 <uses-perm ...

  3. UML基本架构建模--获取类

     Getting Started 開始 Modeling a system involves identifying the things that are important to your p ...

  4. Unity3D - 图形性能优化:优化着色器载入时间

    Unity官方文档之"图形性能优化-优化着色器载入时间"的翻译,E文链接. Optimizing Shader Load Time 优化着色器载入时间 Shaders are sm ...

  5. Threejs 官网 - 怎样执行本地的东西(How to run things locally)

    Threejs 官网 - 怎样执行本地的东西(How to run things locally) 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循&qu ...

  6. 又一次发现Oracle太美之glogin.sql

    又一次发现Oracle太美之glogin.sql 刚開始接触Oracle的时候,有时候一登陆一个生产环境.常常会出现以下的情况: [oracle@rh64 app]$ sqlplus / as sys ...

  7. Android 中View的绘制机制源代码分析 二

    尊重原创:http://blog.csdn.net/yuanzeyao/article/details/46842891 本篇文章接着上篇文章的内容来继续讨论View的绘制机制,上篇文章中我们主要解说 ...

  8. Fuzzy C Means 算法及其 Python 实现——写得很清楚,见原文

    Fuzzy C Means 算法及其 Python 实现 转自:http://note4code.com/2015/04/14/fuzzy-c-means-%E7%AE%97%E6%B3%95%E5% ...

  9. 38.Qt模型/视图结构

    1.模型/视图类 2.模型 3.视图 4.代理 1 模型/视图类 InterView框架提供了一些可以直接使用的模型类和视图类,如QStandardModel类,QDirModel类,QStringL ...

  10. Flask上下文管理机制

    前引 在了解flask上下文管理机制之前,先来一波必知必会的知识点. 面向对象双下方法 首先,先来聊一聊面向对象中的一些特殊的双下划线方法,比如__call__.__getattr__系列.__get ...