• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > 深入理解java动态代理的两种实现方式(JDK/Cglib)

深入理解java动态代理的两种实现方式(JDK/Cglib)

作者:PerKins.Zhu 字体:[增加 减小] 来源:互联网 时间:2017-05-28

PerKins.Zhu 通过本文主要向大家介绍了jdk动态代理 cglib,jdk代理和cglib代理,jdk和cglib,java cglib动态代理,java cglib等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

什么是代理模式?

代理模式:在调用处不直接调用目标类进行操作,而是调用代理类,然后通过代理类来调用目标类进行操作。在代理类调用目标类的前后可以添加一些预处理和后处理操作来完成一些不属于目标类的功能。

为什么要使用代理模式?

通过代理模式可以实现对目标类调用的控制、在目标类调用前/后进行一些不属于目标类的操作,如:数据验证、预处理、后处理、异常处理等

什么是静态代理什么是动态代理?

  1. 静态代理:代理类只能实现对”特定接口的实现类“进行代理
  2. 动态代理:代理类可以实现对多种类的代理

jdk代理和cglib代理区别在哪里?

  1. jdk动态代理:代理所有“实现的有接口”的目标类
  2. cglib动态代理:代理任意一个目标类,但对final类和方法无法代理

不同点:jdk动态代理的目标类必须实现的有接口,因为在调用Proxy.newProxyInstance()的时候需要传入目标类的接口类。而cglib不做此限制。    

下面看代码分析:

定义一个Person接口

package com.zpj.designMode.proxy;

//定义一个Person接口
public interface Person {
  public void doWork();
}
</div>

添加一个实现类:MrLi

package com.zpj.designMode.proxy;

//添加一个实现类
public class MrLi implements Person {

  @Override
  public void doWork() {
    System.out.println("-----doWork");
  }

}
</div>

静态代理:

添加一个静态代理类Proxy

package com.zpj.designMode.proxy;

//静态代理,代理必须和目标类实现共同的接口
public class Proxy implements Person {
  private Person person;// 被代理人

  //这里的目标类型决定了该代理类只能代理实现了Person接口的实例,而不能接收其他类型参数,这也就是静态代理的局限性
  public Proxy(Person person) {
    this.person = person;
  }

  @Override
  public void doWork() {
    System.out.println("doSomething-----start");
    person.doWork();
    System.out.println("doSomething-----end");
  }

}
</div>

静态代理测试程序:

package com.zpj.designMode.proxy;

public class Run {
  public static void main(String[] args) {
    MrLi li = new MrLi();
    Proxy proxy = new Proxy(li);
    //调用处直接调用代理进行目标方法的操作。
    proxy.doWork();
  }
}
</div>

JDK动态代理:

添加一个代理JDKProxy,该代理实现InvocationHandler接口且覆写invoke方法。

package com.zpj.designMode.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/***
 @author Perkins Zhu
 @date 2017年3月13日 上午8:41:10
 */
public class JDKProxy implements InvocationHandler {

  private Object person;// 被代理人
   
  
  //这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理。但是要注意下面的newProxyInstance()中的参数
  public Object getInstance(Object person) {
    this.person = person;
    //与cglib的区别在于这里构建代理对象的时候需要传入被代理对象的接口对象,第二个参数。而cglib不需要被代理对象实现任何接口即可    
    return Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), this);
  }

 

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("doSomething---------start");
    method.invoke(person, args);
    System.out.println("doSomething---------end");
    return null;
  }

}
</div>

JDK动态代理测试程序

package com.zpj.designMode.proxy.jdk;

import com.zpj.designMode.proxy.MrLi;
import com.zpj.designMode.proxy.Person;

/***
 * @author Perkins Zhu
 * @date 2017年3月13日 上午8:51:31
 */
public class Run {

  public static void main(String[] args) {
    Person person = (Person) new JDKProxy().getInstance(new MrLi());
    //注意这里的person不是目标类person,而是代理类person:debug的时候显示null,有'$'标识符
    person.doWork();
  }
}

</div>

Cglib动态代理:

添加一个CglibProxy代理,同时实现MethodInterceptor接口。

package com.zpj.designMode.proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/***
 * @author Perkins Zhu
 * @date 2017年3月13日 上午9:02:54
 */
public class CglibProxy implements MethodInterceptor {
  private Object targetObject;

  // 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
  public Object getInstance(Object target) {
    this.targetObject = target;
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(target.getClass());
    enhancer.setCallback(this);
    //注意该处代理的创建过程
    Object proxyObj = enhancer.create();
    return proxyObj;// 返回代理对象
  }

  @Override
  public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    Object obj = null;
    System.out.println("doSomething---------start");
    obj = method.invoke(targetObject, args);
    System.out.println("doSomething---------end");
    return obj;
  }

}

</div>

Cglib动态代理测试程序

package com.zpj.designMode.proxy.cglib;

import com.zpj.designMode.proxy.MrLi;
import com.zpj.designMode.proxy.Person;

/***
 @author Perkins Zhu
 @date 2017年3月13日 上午9:07:38
 */
public class Run {

  public static void main(String[] args) {
    Person person = (Person)new CglibProxy().getInstance(new MrLi());
    person.doWork();
  }
}
</div>

仔细对比Proxy、CglibProxy和JDKProxy区分静态代理、JDK动态代理和Cglib动态代理的异同点!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • spring cglib 与 jdk 动态代理
  • java 中动态代理(JDK,cglib)实例代码
  • 深入理解java动态代理的两种实现方式(JDK/Cglib)
  • spring cglib 与 jdk 动态代理
  • java 中动态代理(JDK,cglib)实例代码

相关文章

  • 2017-05-28老生常谈Java异常处理和设计(推荐)
  • 2017-05-28java中建立0-10m的消息(字符串)实现方法
  • 2017-05-28java文件操作之Path,Paths,Files
  • 2017-05-28Java实例化的几种方法总结
  • 2017-05-28Java基于正则实现的日期校验功能示例
  • 2017-05-28SpringBoot创建JSP登录页面功能实例代码
  • 2017-05-28java服务端微信APP支付接口详解
  • 2017-05-28Java 多线程优先级实例详解
  • 2017-05-28Spring+SpringMVC+MyBatis深入学习及搭建(三)之MyBatis全局配置文件解析
  • 2017-05-28深入讲解Java 9中的九个新特性

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • java打包成jar并执行jar包中指定的main方法
    • 详解Java中接口的定义与实例代码
    • servlet监听实现统计在线人数功能 附源码下载
    • 面向对象和面向过程的区别(动力节点java学院整理)
    • java中List、Array、Map、Set等集合相互转换
    • Java 中的Printstream介绍_动力节点Java学院整理
    • Java 中的FileReader和FileWriter源码分析_动力节点Java学院整理
    • java中参数传递方式详解
    • JAVA 中Spring的@Async用法总结
    • Java自定义注解实现Redis自动缓存的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有