1. 动态类型和静态类型:语言类型是 运行时 检查,还是 编译期 检查
  2. 强类型和弱类型:为 不同类型 的变量赋值时,是否需要进行 显式的类型转换
  3. Java是 静态的强类型语言 ,但提供了类似 反射 等机制,因此也具备了 部分 动态类型语言的能力

反射

  1. 反射机制是Java语言提供的一种基础功能,赋予程序 在运行时自省 的能力
  2. 通过反射可以 直接操作类或者对象
  • 获取某个对象的类定义
  • 获取类声明的属性和方法
  • 调用方法或者构造函数
  • 运行时修改类定义

setAccessible

  1. AccessibleObject.setAccessible(boolean flag):可以在 运行时 修改成员的 访问限制
  2. setAccessible的应用遍布在日常开发、测试、依赖注入等框架中
  • 在O/R Mapping框架中,为一个Java实体对象,运行时自动生成getter/setter方法
  • 绕过API的访问控制,来调用内部API

动态代理

  1. 动态代理是一种方便 运行时动态构建代理、动态处理代理方法调用 的机制
  2. 很多场景都是利用类似的机制来实现的,例如用来 包装RPC调用 和 AOP
  3. 实现动态代理的方式
  • JDK自身提供的动态代理,主要利用 反射 机制
  • 字节码操作机制 ,类似ASM、cglib(基于ASM)和Javassist

解决的问题

  1. 动态代理是一种 代理 机制,代理可以看作对调用目标的 包装 ,对目标代码的调用是通过代理完成的
  2. 通过代理可以让 调用者和实现者解耦 ,例如RPC调用,框架内部的寻址、序列化、反序列化等,对调用者没什么意义

发展历程

  1. 静态代理 -> 动态代理
  2. 静态代理:需要引入 额外的工作 ,而这些工作与实际的业务逻辑没有关系
  • 古董技术RMI,需要rmic之类的工具生成静态stub等文件,增加了很多繁琐的准备工作
  1. 动态代理:相应的stub等类,可以在运行时生成,对应的调用操作也是动态生成的,极大地提高生产力

JDK Proxy + cglib

public class MyDynamicProxy {public static void main(String[] args) {Hello hello = new HelloImpl();MyInvocationHandler handler = new MyInvocationHandler(hello);// 构造代理实例Hello proxyHello = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), hello.getClass().getInterfaces(), handler);// 调用代理方法proxyHello.sayHello();// 输出//  MyInvocationHandler Invoking HelloImpl#sayHello//  HelloImpl : Hello World}
}interface Hello {void sayHello();
}class HelloImpl implements Hello {@Overridepublic void sayHello() {System.out.println(getClass().getSimpleName() + " : Hello World");}
}@AllArgsConstructor
class MyInvocationHandler implements InvocationHandler {private Object target;@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(getClass().getSimpleName() + " Invoking " + target.getClass().getSimpleName() + "#" + method.getName());Object result = method.invoke(target, args);return result;}
}

  1. 实现InvocationHandler,添加 额外 逻辑
  2. 以Hello接口为纽带,为被调用目标构建 代理对象 ,可以使用代理对象 间接 运行调用目标的逻辑
  3. 以 接口 为中心,相当于添加了一种 对被调用者没有太大意义的限制
  4. 另外实例化的是 Proxy对象 ,而不是真正的被调用类型,可能会带来各种不变和能力退化
  5. 如果 被调用者没有实现接口 ,可以通过 cglib 来实现动态代理(克服了对接口的依赖)
  • cglib动态代理的方式:创建目标类的 子类 ,可以达到 近似使用被调用者本身 的效果

优势对比

JDK Proxy

  1. 最小化依赖关系 ,简化开发和维护,JDK本身的支持
  2. JDK平滑升级 ,而字节码类库通常需要进行 更新 以保证在新版Java上能够使用
  3. 代码实现简单

cglib

  1. 侵入性更小,JDK Proxy是基于 接口 的,而 限定被调用者实现特定接口 是有侵入性的实践
  2. 只需操作关心的类 ,而不必为其它相关类增加工作量
  3. 高性能

性能对比

  1. 在 主流 的JDK版本中,JDK Proxy在 典型场景 可以提供 对等的性能水平 ,在数量级的差距并不是广泛存在的
  2. 反射机制的性能在 现代 JDK中,已经得到了 极大的改进和优化 ,同时JDK的很多功能同样使用了 ASM 进行字节码操作
  3. 在选型时,性能并不是唯一考量,而 可靠性、可维护性和编程工作量 才是更主要的考虑因素

java动态代理_Java核心 -- 动态代理相关推荐

  1. java如何实现动态时钟_Java实现动态数字时钟

    本文实例为大家分享了Java实现动态数字时钟的具体代码,供大家参考,具体内容如下 构建: Clock继承 JFrame 为运行页面 ClockText 测试类 创建 Clock 对象 运行效果: 具体 ...

  2. java数字时钟_Java实现动态数字时钟

    本文实例为大家分享了Java实现动态数字时钟的具体代码,供大家参考,具体内容如下 构建: Clock继承 JFrame 为运行页面 ClockText 测试类 创建 Clock 对象 运行效果: 具体 ...

  3. java动态打包_java 调用动态库打包sdk

    java连接c++动态库并生成jar包提供给别人调用 1.需要将java通过jni生成头文件,并导入到c++项目并对c++进行jni方法继承 在项目的src目录执行,否则会提示 错误:找不到符号 ja ...

  4. java常量配置_java项目动态配置常量和peiconfig.properties配置使用详解

    java项目动态配置常量和peiconfig.properties配置使用详解 点击:2 Java工程中配置信息一般都写在 properties文件中,下面这篇文章是对java基础配置的一点学习心得整 ...

  5. java动态录音_java实现动态录音,声卡有声音进来就自动录音

    TargetDataLine是声音的输入(麦克风),而SourceDataLine是输出(音响,耳机). 整个过程,请参见下面的程序.(运行后,实时地从麦克风录音,实时输出). import java ...

  6. java 卷轴式_java核心卷轴之泛型程序设计

    本文根据<Java核心卷轴>第十二章总结而来,更加详细的内容请查看<Java核心卷轴> 1. 泛型类型只能是引用类型,不可以使用基本数据类型. 2. 类型变量含义 E :集合K ...

  7. java 流式_Java核心教程5: 流式编程

    本次课程的标题不像之前那样易懂,是一个陌生的概念,"流式编程"是个什么东西? 在了解流式编程之前先思考一下"流",水流.电流.人流,这些都是流.而流式编程则是让 ...

  8. springboot 注解动态赋值_java springboot动态给注解属性参数赋值

    场景: 最近做了一个系统,使用Elasticsearch做了全文搜索,系统分为开发环境和正式环境,正式环境供公司内部使用,因为服务器资源不太充裕,决定开发环境和正式环境共用一个Elasticsearc ...

  9. java 分布式事务_Java核心知识 Spring原理十五 JPA 原理

    1. 事务 事务是计算机应用中不可或缺的组件模型,它保证了用户操作的原子性 ( Atomicity ).一致性 ( Consistency ).隔离性 ( Isolation ) 和持久性 ( Dur ...

  10. java 复制对象_Java核心知识 基础七 JAVA 复制

    将一个对象的引用复制给另外一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式 是浅拷贝,第三种是深拷贝.所以大家知道了哈,这三种概念实际上都是为了拷贝对象. 1. 直接赋值复制 直接赋值.在 ...

最新文章

  1. Nature Genetics:微生物如何适应植物的?(articles)
  2. 阅读笔记一——java高并发的性能优化
  3. 栅格数据的像素值保存问题
  4. Py之matplotlib.pyplot:matplotlib.pyplot的plt.legend函数的简介、使用方法之详细攻略
  5. VUE2.x的浏览器兼容情况汇总
  6. 微型计算机文献,微型计算机控制系统期刊文章参考文献 哪里有微型计算机控制系统参考文献...
  7. mysql中什么是选择引擎_Mysql 应该选择什么引擎
  8. css行内元素和块级元素
  9. 初学C语言 输出图形
  10. js统计页面刷新次数
  11. 网站被封了要换服务器吗,网站被惩罚或被封该怎么办?
  12. 二元非洲秃鹫优化算法附Matlab代码
  13. android10管理权限,Android 权限管理
  14. 机器学习算法(二十五):KD树详解及KD树最近邻算法
  15. 安装Robo 3T(Robomongo)MongoDB可视化工具
  16. 《CLR via C#》读书笔记---06 类型和成员基础
  17. 使用webflow的感觉
  18. Python 3.10 尝鲜
  19. HSQLDB基本认识
  20. Jenkins中Changelog插件使用

热门文章

  1. centos6.5 yum安装php5.5,mysql5.5.46 ,aphche 2.2.15
  2. 软中断和tasklet
  3. Unable to resolve dependency for ':app@debug/compileClasspath'
  4. 【开源资讯】开源文档管理系统 Wizard 1.2.5 发布
  5. mysql视图的更新 条件_MySQL进阶16 - 视图的创建/修改/删除/更新--可更新性的不适用条件...
  6. 最大弹窗_你不在意的小弹窗,为什么总是出现问题?
  7. grdraw用法 lisp_AutoCAD 2000 Visual LISP开发
  8. python 条件查询_Python SQLAlchemy 不确定条件查询
  9. 导航猫连接Oracle
  10. concurrenthashmap获取不到_面试必问的ConcurrentHashMap