JDK 动态代理

  • 内容
    • 一、动态代理解析
      • 1. 代理模式
      • 2. 为什么要使用动态代理
      • 3. JDK 动态代理简单结构图
      • 4. JDK 动态代理实现步骤
      • 5. JDK 动态代理 API
        • 5.1 java.lang.reflect.Proxy
        • 5.1 java.lang.reflect.InvocationHandler
    • 二、JDK 动态代理的实现(代码)
      • 1. 项目结构图
      • 2. IRentService 接口
      • 3. LandlordServiceImpl 真实类
      • 4. TransactionInvocationHandler 代理类
      • 5. MyTransactionManager 增强类(模拟一下事务)
      • 6. applicationContext.xml
      • 7. TransactionInvocationHandlerTest 测试类
  • 总结

参考博文:https://blog.csdn.net/jiankunking/article/details/52143504

内容

一、动态代理解析

1. 代理模式

Java 这门语言有许多种设计模式,其中一种设计模式为代理模式,所谓代理模式,就是通过代理方来操作目标对象,而不是自己直接调用。代理模式又分为静态代理和动态代理。
静态代理:针对每个被代理对象写一个代理类,当有多个代理对象时需要写多个代理类,操作不够优雅;
动态代理:可以根据接口动态的生成代理类,这动态生成的类不需要自己书写,jdk帮我们完成了,代码变得简洁。
无论是动态代理还是静态代理,最终都会产生一个代理类(class文件),里面都含有对被代理对象的封装,只是诞生的途径不一样。下面我主要介绍 JDK 动态代理 的实现和原理。

2. 为什么要使用动态代理

动态代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

3. JDK 动态代理简单结构图

4. JDK 动态代理实现步骤

  1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法
  2. 创建被代理的类以及接口
  3. 通过Proxy的静态方法 newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
  4. 通过代理调用方法

注意: 真实类(被代理的类)必须实现接口

5. JDK 动态代理 API

5.1 java.lang.reflect.Proxy

Java 动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。
主要方法: public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler hanlder)

  • 方法职责:
    为指定类加载器、一组接口及调用处理器生成动态代理类实例。
  • 方法参数:
    loader : 类加载器,一般传递真实对象的类加载器;
    interfaces: 代理类需要实现的接口;
    handler: 代理执行处理器,说人话就是生成代理对象帮你要做什么。
  • 方法返回: 创建的代理对象。

5.1 java.lang.reflect.InvocationHandler

主要方法:public Object invoke(Object proxy, Method method, Object[] args)。

  • 方法职责:
    代理类实现该接口,负责集中处理动态代理类上的所有方法调用,让使用者自定义做什么事情, 对原来方法增强(加什么功能)。
  • 方法参数:
    proxy : 生成的代理对象;
    method: 当前调用的真实方法对象;
    args : 当前调用方法的实参。
  • 方法返回: 真实方法的返回结果。

二、JDK 动态代理的实现(代码)

1. 项目结构图

2. IRentService 接口

package com.yy.homework.service;
public interface IRentService {void rent();
}

3. LandlordServiceImpl 真实类

package com.yy.homework.service.impl;
import com.yy.homework.service.IRentService;
public class LandlordServiceImpl implements IRentService {@Overridepublic void rent() {System.out.println("我是房东,我以1000一个月的房价给中介帮我出租!");}
}

4. TransactionInvocationHandler 代理类

package com.yy.homework.service.impl;import com.yy.homework.tx.MyTransactionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class TransactionInvocationHandler implements InvocationHandler {private Object target;@Autowiredprivate MyTransactionManager myTransactionManager;public Object getTarget() {return target;}public void setTarget(Object target) {this.target = target;}/*** @author YanYang* @description: 负责集中处理动态代理类上的所有方法调用,让使用者自定义做什么事情,对原来方法增强(模拟一下事务)* proxy:生成的代理对象* method:调用真实对象的方法* args:当前调用方法的实参* return:返回真实方法的返回结果*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object retVal = null;try {// 开启事务myTransactionManager.begin();// 调用真实对象的方法retVal = method.invoke(target, args);// 提交事务myTransactionManager.commit();} catch (Exception e) {// 回滚事务myTransactionManager.rollback();e.printStackTrace();}return retVal;}
}

5. MyTransactionManager 增强类(模拟一下事务)

package com.yy.homework.tx;import org.springframework.stereotype.Component;/*** @program: static-proxy* @ClassName MyTransactionManager* @description:* @author: YanYang**/
@Component
public class MyTransactionManager {public void begin() {System.out.println("开启事务");}public void commit() {System.out.println("提交事务");}public void rollback() {System.out.println("回滚事务");}
}

6. applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.yy.homework"/><bean id="transactionInvocationHandler" class="com.yy.homework.service.impl.TransactionInvocationHandler"><property name="target"><!--    把房东真实对象参起来藏起来    --><bean class="com.yy.homework.service.impl.LandlordServiceImpl"/></property></bean></beans>

7. TransactionInvocationHandlerTest 测试类

package com.yy.homework.service.impl;import com.yy.homework.service.IRentService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.lang.reflect.Proxy;
import java.util.Arrays;/*** @program: static-proxy* @ClassName TransactionInvocationHandlerTest* @description:* @author: YanYang**/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TransactionInvocationHandlerTest {@AutowiredTransactionInvocationHandler handler;@Testpublic void invoke() {// 动态生成代理类并创建对象IRentService proxy = (IRentService) Proxy.newProxyInstance(// 类加载器,一般传递真实对象的类加载器handler.getTarget().getClass().getClassLoader(),// 代理类需要实现的接口,获取真实类实现的接口,生成代理类也是实现什么接口handler.getTarget().getClass().getInterfaces(),// 代理执行处理器,也就是生成代理对象帮你要做什么// 通过这个参数告诉 API 生成代理对象具体做什么handler);proxy.rent();System.out.println("handler = " + Arrays.toString(handler.getTarget().getClass().getInterfaces()));System.out.println("classLoader = " + handler.getTarget().getClass().getClassLoader());System.out.println("handler = " + handler);}
}

运行结果:

"C:\Program Files\Java\jdk-11.0.9\bin\java.exe"
com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.yy.homework.service.impl.TransactionInvocationHandlerTest,invoke
开启事务
我是房东,我以1000一个月的房价给中介帮我出租!
提交事务
handler = [interface com.yy.homework.service.IRentService]
classLoader = jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
handler = com.yy.homework.service.impl.TransactionInvocationHandler@36328d33Process finished with exit code 0

总结

以上就是对 JDK 动态代理 的总结了,代码仅供参考,欢迎讨论交流。

Java JDK 动态代理实现和代码分析相关推荐

  1. Java - JDK动态代理原理

    Java - JDK动态代理原理 前言 一. JDK动态代理源码分析 1.1 生成目标代理类 getProxyClass0 1.1.1 KeyFactory 生成接口的虚引用 1.1.2 ProxyC ...

  2. java jdk动态代理学习记录

    转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...

  3. Jdk动态代理 底层源码分析

    前言 java动态代理主要有2种,Jdk动态代理.Cglib动态代理,本文主要讲解Jdk动态代理的使用.运行机制.以及源码分析.当spring没有手动开启Cglib动态代理,即:<aop:asp ...

  4. JDK动态代理实现与原理分析

    1.何为代理 代理在我们的日常生活中,就有很多体现,房屋租赁代理,校园辅导班招生代理,化妆产品销售代理等.为什么我们要找代理呢,代理是专业的,是方便的.例如我们买一件化妆品,或买一本书,肯定是不能去找 ...

  5. java jdk动态代理 cglib动态代理demo

    最近在研究java动态代理这块,以前也看了很多次java动态代理,感觉一直不是怎么明白,这两天看了看又明白了些,现给出我参考网上写的一个demo jdk动态代理实现: View Code import ...

  6. Java JDK 动态代理

    代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代 ...

  7. JDK动态代理实现原理详解(源码分析)

    无论是静态代理,还是Cglib动态代理,都比较容易理解,本文就通过进入源码的方式来看看JDK动态代理的实现原理进行分析 要了解动态代理的可以参考另一篇文章,有详细介绍,这里仅仅对JDK动态代理做源码分 ...

  8. Java 结合实例学会使用 静态代理、JDK动态代理、CGLIB动态代理

    前言 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 代理 很多人至今都是看到 代理就懵, 静态代理.动态代理.JDK动态代理.CGL ...

  9. 谁与争锋,JDK动态代理大战CGLib动态代理

    文章目录 一.前言 二.基本概念 三.JDK 和 CGLib动态代理区别 3.1 JDK动态代理具体实现原理 3.2 CGLib动态代理 3.3 两者对比 3.4 使用注意 四.JDK 和 CGLib ...

最新文章

  1. CRM:把 isv.config.xml 按钮事件移动到 entity.onload()
  2. nginx编译安装,nginx静态资源访问和负载均衡的使用!
  3. Redis的搭建和Redis的集群搭建
  4. SOFAMosn 无损重启/升级
  5. 一句话讲清楚IOC容器以及什么时候使用@Autowired
  6. imagecomposition工程分析
  7. Ansys节点数据批量一键导出脚本生成CSV (ansys数据导出利用matlab脚本)
  8. 济南python工资一般多少-济南Python+人工智能
  9. linux免密码登录失败,ssh 免密码登录失败
  10. 视频直播CDN系统架构简析
  11. 运营商iptv服务器,IPTV 服务器
  12. sprintf函数的使用方法
  13. 芯片设计流程介绍(从硬件设计语言到芯片制造)
  14. Lipschitz continuity (利普希茨连续)
  15. 中文简体与繁体的转换
  16. 局域网内2台ubuntu电脑共享鼠标键盘
  17. 如何实现一个转动的太极图
  18. 填补空缺——压缩感知
  19. 李大潜:学习数学是战略性投资【导图版】
  20. 自动驾驶-第10届蓝桥杯Scratch省赛真题第5题

热门文章

  1. elasticSearch 中的查询关键词
  2. 在线教育平台架构设计
  3. Yolov5 系列1--- Yolo发展史以及Yolov5模型详解
  4. 什么是软件危机?为什么会出现软件危机?
  5. 基于Matlab的Robotics Toolbox工具箱的机器人仿真函数介绍(空间位姿表示与动力学)
  6. 【2018VR眼镜牌子排行榜推荐】UGP VR 、HTC vive、索尼PSVR哪个性价比高?什么VR眼镜好,来看看
  7. 机器学习常见术语汇总
  8. 考研资料 | 西安电子科技大学考研专业课资料(绝密)
  9. 2020Java就业前景好吗?
  10. Vijos CoVH之柯南开锁 (二分图)