深入分析Java反射(四)-动态代理
深入分析Java反射(四)-动态代理动态代理的简介Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。Java动态代理实际上通过反射技术,把代理对象和被代理对象(真实对象)的代理关系建立延迟到程序运行之后,动态创建新的代理类去完成对真实对象的代理操作(可以改变原来真实对象的方法行为),这一点成为了当前主流的AOP框架和延迟加载功能的基础。本文在查看和编写动态代理相关的代码使 ...
阅读更多
深入分析Java反射(三)-泛型
深入分析Java反射(三)-泛型前提Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行Debug。 本文主要介绍反射中一个比较难的问题-泛型。 泛型的简介泛型是在2004年JavaSE 5.0(JDK1.5)版本中添加到Java编程语言中的泛型编程工具。泛型的设计是为了应用在Java的类型系统,提供”用类型或者方法操作各种类型的对象从而提供编译期的类型安全功能(原文:a type or method to operate on objects of v ...
阅读更多
深入分析Java反射(二)-数组和枚举
深入分析Java反射(二)-数组和枚举前提Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行Debug。 本文主要介绍反射中可能用到的两个比较特殊的类型,数组和枚举,分别对应java.lang.reflect.Array和java.lang.Enum,后者其实并不是反射类库包中的类,但是反射的基础类库里面有使用枚举类型的方法。 数组类型数组是一种包含固定数量的相同类型组件(Component)的引用类型对象,也就是说数组的长度是不可变,它的每个元素都是 ...
阅读更多
深入分析Java反射(一)-核心类库和方法
深入分析Java反射(一)-核心类库和方法前提Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行Debug。 本文主要介绍反射的基本概念以及核心类Class、Constructor、Method、Field、Parameter的常用方法。 本文极长,请准备一个使自己舒服的姿势阅读。 什么是反射反射(Reflection)是一种可以在运行时检查和动态调用类、构造、方法、属性等等的编程语言的能力,甚至可以不需要在编译期感知类的名称、方法的名称等等。Orac ...
阅读更多
RabbitMQ扩展之直接回复(Direct reply-to)
前提本文内容参考RabbitMQ官方文档Direct reply-to。 直接回复直接回复(Direct reply-to)是一种可以避免声明回复队列并且实现类似于RPC功能的一种特性。RabbitMQ中允许使用客户端和RabbitMQ消息代理中间件实现RPC模式,典型的做法是:RPC客户端发送请求(消息)到一个持久化的已知服务端队列,RPC服务端消费该服务端队列的消息,然后使用消息属性中的reply-to属性对应的值作为客户端回复队列发送回复消息到RPC客户端。 客户端回复队列需要考虑创建问题。客户端可以为每个请求-响应声明一个一次性的队列,但是这样的做法是十分低效的,因为即使是非持久状态下 ...
阅读更多
浅析JDK中ServiceLoader的源码
前提紧接着上一篇《通过源码浅析JDK中的资源加载》,ServiceLoader是SPI(Service Provider Interface)中的服务类加载的核心类,也就是,这篇文章先介绍ServiceLoader的使用方式,再分析它的源码。 ServiceLoader的使用这里先列举一个经典的例子,MySQL的Java驱动就是通过ServiceLoader加载的,先引入mysql-connector-java的依赖: <dependency> <groupId>mysql</groupId> <artifactId>mysql-co ...
阅读更多
通过源码浅析Java中的资源加载
前提最近在做一个基础组件项目刚好需要用到JDK中的资源加载,这里说到的资源包括类文件和其他静态资源,刚好需要重新补充一下类加载器和资源加载的相关知识,整理成一篇文章。 什么是类加载器虚拟机设计团队把类加载阶段中的”通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到了Java虚拟机外部实现,以便让应用程序自己决定如何去获取所需要的类,而实现这个动作的代码模块称为”类加载器(ClassLoader)”。 类加载器虽然只用于实现类加载的功能,但是它在Java程序中起到的作用不局限于类加载阶段。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立类在Java虚拟机中的唯一性,每一个 ...
阅读更多
RabbitMQ扩展之消费者优先级
前提本文来源于官方文档Consumer Priorities。 消费者优先级消费者优先级的机制: 高优先级的消费者处于活跃状态的情况下优先接收和处理消息。 消息会流入到低优先级的活跃消费者仅当高优先级的消费者处于阻塞状态。 正常情况下,所有订阅同一个队列的活跃消费者以循环的(round-robin)方式从队列中接收消息。当使用了消费者优先级,如果多个活跃消费者使用了相同的高优先级属性,那么消息投递也是以循环的方式进行(其实使用了相同的优先级类似于没有启用优先级)。 活跃消费者的定义活跃的消费者就是可以在不用等待的情况下接收和处理消息的消费者,也就是消费者如果无法接收消息,那么它就是出于非活 ...
阅读更多
RabbitMQ扩展之消费者消息预读取
前提本文来源于官方文档Consumer Prefetch。 消费者消息预读取消费者消息预读取是一个更加合理和高效的限制未确认消息数量的解决方式。 AMQP 0-9-1协议中定义了basic.qos方法用于限制信道或者连接上的未确认消息数量,这个消息数据量命名为prefetch_count。不幸的是,信道其实并不是限制未确认消息数量的理想范畴,因为单个信道有可能有多个消费者订阅多个不同的队列,所以信道和队列需要为发送的每个消息相互协调,以确保消息总数量不超过限制,造成了性能下降,单机性能出现瓶颈,在集群方案中耗时更加严重。 basic.qos定义了两个属性: prefetch_count:预读 ...
阅读更多
RabbitMQ扩展之消费者取消通知
前提本文来源于官方文档Consumer Cancel Notification。 消费者取消通知当一个信道上建立的消费者订阅了一个队列,有可能出现各种原因导致消费停止。一个很明显的原因就是客户端在同一个信道上发出basic.cancel命令,消息中间件代理响应basic.cancel-ok,将会导致消费者被取消。还有其他的事件如队列的删除或者集群方案所在队列的集群节点失败也有可能导致消费者被取消,消费者被取消这个事件并不会通知客户端对应的信道,这样子会造成客户端无法感知消费者被取消。 为了避免上面这些情况出现,RabbitMQ引入了扩展特性:由于消息中间件代理出现的异常或者正常情况导致消费者取 ...
阅读更多