全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

什么是代理模式?

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

为什么要使用代理模式?

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

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

  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();
}

添加一个实现类:MrLi

package com.zpj.designMode.proxy;

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

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

}

静态代理:

添加一个静态代理类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");
  }

}

静态代理测试程序:

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();
  }
}

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;
  }

}

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();
  }
}

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;
  }

}

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();
  }
}

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

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


# cglib和jdk  # jdk动态代理和cglib  # jdk代理和cglib代理  # java动态代理(jdk与cglib)详细解析  # 浅谈Java代理(jdk静态代理、动态代理和cglib动态代理)  # Java反射(JDK)与动态代理(CGLIB)详解  # Java JDK与cglib动态代理有什么区别  # java 中动态代理(JDK  # cglib)实例代码  # java中jdk代理和cglib代理使用步骤详解  # 上午  # 实现了  # 可以实现  # 则可  # 不属于  # 后处理  # 不需要  # 这也  # 要注意  # 第二个  # 不做  # 但对  # 来完成  # 要使  # 大家多多  # 不直接  # 直接调用  # 决定了  # 异同点  # private 


相关文章: 简易网站制作视频教程,使用记事本编写一个简单的网页html文件?  简历在线制作网站免费,免费下载个人简历的网站是哪些?  子杰智能建站系统|零代码开发与AI生成SEO优化指南  如何制作网站标识牌,动态网站如何制作(教程)?  c# Task.ConfigureAwait(true) 在什么场景下是必须的  如何在腾讯云免费申请建站?  大同网页,大同瑞慈医院官网?  C++时间戳转换成日期时间的步骤和示例代码  如何选择美橙互联多站合一建站方案?  如何高效完成自助建站业务培训?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?  建站之星×万网:智能建站系统+自助建站平台一键生成  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  建站之家VIP精选网站模板与SEO优化教程整合指南  用v-html解决Vue.js渲染中html标签不被解析的问题  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  网站制作壁纸教程视频,电脑壁纸网站?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  如何通过IIS搭建网站并配置访问权限?  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  定制建站模板如何实现SEO优化与智能系统配置?18字教程  建站DNS解析失败?如何正确配置域名服务器?  如何用景安虚拟主机手机版绑定域名建站?  建站之星ASP如何实现CMS高效搭建与安全管理?  太平洋网站制作公司,网络用语太平洋是什么意思?  专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?  建站之星CMS五站合一模板配置与SEO优化指南  番禺网站制作公司哪家值得合作,番禺图书馆新馆开放了吗?  南平网站制作公司,2025年南平市事业单位报名时间?  如何在新浪SAE免费搭建个人博客?  如何在VPS电脑上快速搭建网站?  Python文件管理规范_工程实践说明【指导】  沈阳制作网站公司排名,沈阳装饰协会官方网站?  如何在万网自助建站中设置域名及备案?  建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析  为什么Go需要go mod文件_Go go mod文件作用说明  建站之星安装后界面空白如何解决?  建站之星云端配置指南:模板选择与SEO优化一键生成  制作证书网站有哪些,全国城建培训中心证书查询官网?  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  在线制作视频网站免费,都有哪些好的动漫网站?  安徽网站建设与外贸建站服务专业定制方案  建站之星安装路径如何正确选择及配置?  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  完全自定义免费建站平台:主题模板在线生成一站式服务  建站之星好吗?新手能否轻松上手建站?  网站制作软件免费下载安装,有哪些免费下载的软件网站?  制作网站怎么制作,*游戏网站怎么搭建?  已有域名能否直接搭建网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。