一、什么是动态代理?
代理类在程序运行时创建的代理方式被成为动态代理。动态代理的代理类并不是在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. LVS+Keepalived 实现高可用负载均衡

    前言 在业务量达到一定量的时候,往往单机的服务是会出现瓶颈的.此时最常见的方式就是通过负载均衡来进行横向扩展.其中我们最常用的软件就是 Nginx.通过其反向代理的能力能够轻松实现负载均衡,当有服务出 ...

  2. PHP mysqli_sqlstate() 函数

    返回最后一个 MySQL 操作的 SQLSTATE 错误代码: <?php 高佣联盟 www.cgewang.com // 假定数据库用户名:root,密码:123456,数据库:RUNOOB ...

  3. Typora+PicGo-Core(command line)+SMMS、github、gitee实现Typora图片上传到图床

    Typora+PicGo-Core(command line)+SMMS.github.gitee实现Typora图片上传到图床 1 安装插件2 配置config.json    2.1 设置SMMS ...

  4. 关于c/c++指针,指针的指针

    伪军迷祝:建军节快乐! 当调用一个函数时,实际上入参使用的都是副本(除非是引用),指针也不例外.举个例子如: void func(int a, int * p); 当调用func时无论是a还是p其实传 ...

  5. 最详尽的datagrip使用

    什么是datagrip? datagrip是jetbrains旗下的一款数据库管理工具,相信做过java开发的都知道,idea就是这家公司发明的. 为什么要使用datagrip? datagrip的有 ...

  6. 【原创】xenomai与VxWorks实时性对比(资源抢占上下文切换对比)

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ (下面数据,仅供个人参考) 可能大部分人一直好奇Vx ...

  7. 【NOIP2016】组合数问题 题解(组合数学+递推)

    题目链接 题目大意:给定$n,m,k$,求满足$k|C_i^j$的$C_i^j$的个数.$(0\leq i\leq n,1\leq j\leq \min(i,m))$. --------------- ...

  8. JS中的数组复制问题

    JS中的数组复制问题 前言 首先提到复制,也就是拷贝问题,就必须要明确浅拷贝和深拷贝. 浅拷贝:B由A复制而来,改变B的内容,A也改变 深拷贝:B由A复制而来,改变B的内容,A的内容不会改变 总的来说 ...

  9. IDEA插件配置推荐

    一.配置 [自动编译]如下图配置:推荐指数[***] [忽略大小写]说明:IDEA默认是匹配大小写,此开关如果未关,你输入字符一定要符合大小写.比如敲string是不会出现代码提示或只能补充.但是如果 ...

  10. 如何从appstore下架自己家的app

    本文主要讲如何下架appstore上边的app,我看了好多百度的,但是大部分说的都是14年左右的 ,我这边说一下最新的 1.用开发者帐号登陆到iTunes Connect 2.在iTunes Conn ...