一、什么是动态代理?
代理类在程序运行时创建的代理方式被成为动态代理。动态代理的代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。

Java动态代理有两种:jdk动态代理和Cglib动态代理

二、JDK动态代理
在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现动态代理所必须用到的东西。

1.InvocationHandler:
每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。我们来看看InvocationHandler这个接口唯一的一个方法 invoke 方法:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable

其接受三个参数,那么这三个参数分别代表什么呢?

  • proxy:  指代我们所代理的那个真实对象
  • method:  指代的是我们所要调用真实对象的某个方法的Method对象
  • args:  指代的是调用真实对象某个方法时接受的参数

2.Proxy:
Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

其接收三个参数,我们来看看这三个参数所代表的含义:

  • loader:  一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
  • interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
  • h:  一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上。

3.用上一篇的Person例子来进一步运用
(1)定义一个IPerson接口

public interface IPerson {
public String getName(); public Integer getAge();
}

(2)定义一个真实的对象类来实现这个接口 

public class PersonImp implements IPerson {
private String name;
private Integer age; public PersonImp() {
super();
} public PersonImp(String name, Integer age) {
super();
this.name = name;
this.age = age;
} @Override
public String getName() {
// TODO Auto-generated method stub
return name;
} @Override
public Integer getAge() {
// TODO Auto-generated method stub
return age;
}
}

(3)定义一个动态代理类,实现InvocationHandler接口

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler {
private Object target; public MyInvocationHandler() {
super();
} public MyInvocationHandler(Object target) {
super();
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("getName".equals(method.getName())) {
System.out.println("**********before*********");
System.out.println("method:" + method);
Object res = method.invoke(target, args);
System.out.println("***********after*********");
return res;
} else {
Object res = method.invoke(target, args);
return res;
}
}
}

(4)测试一下

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; public class PersonProxyTest {
public static void main(String[] args) {
IPerson person = new PersonImp("jack", 20);//我们要代理的真实对象(被代理对象)
InvocationHandler handler = new MyInvocationHandler(person);//代理对象,代理哪个对象,就把哪个对象传进去 IPerson personProxy = (IPerson) Proxy.newProxyInstance(person.getClass().getClassLoader(),
person.getClass().getInterfaces(), handler);
System.out.println(personProxy.getClass().getName());
System.out.println(personProxy.getName());
System.out.println(personProxy.getAge());
}
}

(5)看一下输出结果:

我们看看 com.sun.proxy.$Proxy0 这个东西,这个东西是由 System.out.println(personProxy.getClass().getName()); 这条语句打印出来的,那么为什么我们返回的这个代理对象的类名是这样的呢?
原因是:通过 Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号。

Java动态代理(二)——jdk动态代理的更多相关文章

  1. Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)

    一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法. ...

  2. java的静态代理、jdk动态代理和cglib动态代理

    Java的代理就是客户端不再直接和委托类打交道,而是通过一个中间层来访问,这个中间层就是代理.使用代理有两个好处,一是可以隐藏委托类的实现:二是可以实现客户与委托类之间的解耦,在不修改委托类代码的情况 ...

  3. Java代理(静态代理、JDK动态代理、CGLIB动态代理)

    Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...

  4. 静态代理与JDK动态代理

    demo地址: https://github.com/ZbLeaning/leaning 代理: 为其他对象提供一种代理以控制对这个对象的访问.分为静态代理和动态代理.代理模式的目的就是为真实业务对象 ...

  5. 从静态代理,jdk动态代理到cglib动态代理-一文搞懂代理模式

    从代理模式到动态代理 代理模式是一种理论上非常简单,但是各种地方的实现往往却非常复杂.本文将从代理模式的基本概念出发,探讨代理模式在java领域的应用与实现.读完本文你将get到以下几点: 为什么需要 ...

  6. 代理模式之静态代理,JDK动态代理和cglib动态代理

    代理模式,顾名思义,就是通过代理去完成某些功能.比如,你需要购买火车票,不想跑那么远到火车站售票窗口买,可以去附近的火车票代售点买,或者到携程等第三方网站买.这个时候,我们就把火车站叫做目标对象或者委 ...

  7. 代理模式详解:静态代理、JDK动态代理与Cglib动态代理

    代理模式简介分类 概念 ​ 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. ​ 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...

  8. 017 Java中的静态代理、JDK动态代理、cglib动态代理

    一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...

  9. Java代理:静态代理、JDK动态代理和CGLIB动态代理

    代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式.所谓的代理者是指一个类别可以作为其它东西的接口.代理者可以作任何东西的接口:网络连接.存储器中的大对象.文件或其它昂贵或无法复制 ...

  10. java静态代理和JDK动态代理

    静态代理 编译阶段就生产了对应的代理类 public interface IBussiness { void execute(); } public class BussinessImpl imple ...

随机推荐

  1. 21天速成python电子书pdf|超级厉害的书内附百度云链接可直接下载|

    python的学习书籍小编看过很多,但是这本<21天学通python>真的是堪称极品!本书的作者团队成员为一线开发工程师.资深编程专家或专业培训师,在编程开发方面有着丰富的经验,并已出版过 ...

  2. PHP 超级全局变量讲解

    PHP 超级全局变量 超级全局变量在PHP 4.1.0之后被启用, 是PHP系统中自带的变量,在一个脚本的全部作用域中都可用. PHP 超级全局变量 PHP中预定义了几个超级全局变量(superglo ...

  3. Skill 扫描list中是否含有某元素

    https://www.cnblogs.com/yeungchie/ code procedure(ycInListp(scan keylist) prog((times) times = 0 for ...

  4. luogu P4562 [JXOI2018]游戏 组合数学

    LINK:游戏 当L==1的时候 容易想到 答案和1的位置有关. 枚举1的位置 那么剩下的方案为(R-1)! 那么总答案为 (R+1)*R/2(R-1)! 考虑L==2的时候 对于一个排列什么时候会终 ...

  5. Springboot拦截器使用及其底层源码剖析

    博主最近看了一下公司刚刚开发的微服务,准备入手从基本的过滤器以及拦截器开始剖析,以及在帮同学们分析一下上次的jetty过滤器源码与本次Springboot中tomcat中过滤器的区别.正题开始,拦截器 ...

  6. 《分享》Graphql入门与实践

    最近项目用到了graphql,学习了一些并在公司做了一个小分享,希望对你有帮助 一.介绍 Graphql是一种面向数据的API查询语言 Graphql给前端提供一种强力的查询工具,我们可以根据自己定义 ...

  7. C 语言学习 -1

    头文件  stdio.h stdlib.h sting.h 先学习上面三个头文件: 1: stdio.h  这个头文件包含了 程序与外界数据交互的各种函数 说白了就是    用来处理     输入/输 ...

  8. Hibernate 映射

    在使用单纯hibernate文件映射时,项目应包含以下文件: hibernate.cfg.xml  放在src/或根目录下 1 <?xml version='1.0' encoding='utf ...

  9. ios textView跟随键盘的移动

    实现效果: textview 能够跟随键盘的移动而移动 效果图如下: 下边贴上主要的代码: 1.创建textview @interface ViewController ()<UITextVie ...

  10. C、C++、boost、Qt在嵌入式系统开发中的使用

    概述 嵌入式系统开发相对来说属于偏底层的开发,也就是与硬件结合比较紧密,只能使用C/C++语言.对于做平台开发的人来说,C语言真的是很"古老"的语言,属于操作系统语言!好多人会觉得 ...