java

java

EMQ 使用的实践

近一年半在做物联网相关的项目,MQTT 是物联网技术中非常常见且协议。EMQ 是对 MQTT 协议实现的很不错的 Broker。当前的稳定版本是 V3.2.7; 下面我罗列一下使用中的一些实践和想法; 如何正确获得设备端连接断开事件 有三种做法: * 订阅EMQ 的系统主题$SYS/brokers/${node}/clients/{clientId}/disconnected; * 使用 web hook 插件; * 客户端使用遗愿; 第 1 种做法 可使用通配符方式只订阅一个主题,缺点就是所有客户端的离线都收到消息,需要在消费的时候再做判断,是否要关心,再触发具体的关心的设备类型的离线。 但是如果不使用通配符方式订阅的话,就得设备挨个订阅主题,这样就增加了很多订阅主题,给消息路由带来压力,是极不划算的做法; 第 2 种做法 缺点和第 1 种做法一样,收到的是所有设备的离线回调,需要在 controller

By Jiacheng Wang

java

JDK 的动态代理相关分析

最近做个动态代理测试,鬼畜地写了如下代码: public interface SayHello { String say(String message); } public class SayHelloInvocationHandler implements InvocationHandler { private SayHello target; public SayHelloInvocationHandler(SayHello target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(StringUtils.equals(method.getName(), "say")) { System.out.println(proxy.getClass()); //打印第一行

By Jiacheng Wang

java

Java8 lambda 要注意的四个地方

Java8 往函数式编程迈入了一大步;引入了函数式接口的概念;并使用 lambda 表达式在语法上大大简化函数式接口写法; 帖上一段简单的示例代码: Runnbale run = () -> System.out.println("Hello Jack!"); new Thread(run).start(); lambda可以粗暴看作为匿名类的实现,提供了轻量级的语法上的实现,但远不止如此,比如还有改变 this 的指向; 在使用 lambda 的时候有几个要注意的地方: * 声明:函数式接口是指只有一个函数的接口,可以使用@FunctionalInterface注解来进行显示声明,这样编译器会验证接口是否满足函数接口的要求;也可以不使用@FunctionalInterface来显示声明,接口满足只有一个函数的要求即可,不包含有default默认实现的函数; * 类型推导:使用lambda的时候,简化的语法形式对指向类型变得泛化无法明确,对后续程序执行变得不安全,编译器自动根据使用上下文所期待的类型(即目标类型)来进行推导出来的具体函数式接口;例如我写了两个lambd

By Jiacheng Wang

java

Java 中的强引用 、软引用、弱引用、虚引用

这里整理一下之前一直理解得不是很清楚的 Java 的引用; Java 开发不像 C 语言有指针,不能通过编码回收内存,完全靠垃圾回收器不定时来进行垃圾回收; 虽然垃圾回收器的工作是靠 JVM 来自动控制,但是做为 Java 程序员仍然可以通过编程在一定程序上与垃圾回收器进行交互,以帮助程序员稍微精细的控制内存回收,帮助垃圾回收器更好的管理内存的回收工作; Java 中有存在着四种引用类型:强引用 、软引用、弱引用、虚引用;四种类型的引用强度由强至弱,依次递减。 强引用 强引用是 Java 中最常见的也是最直接的引用方式,例如 Person p = new Person("Tom"); 这样的代码就会生成一个 Person对象,和一个指向此对象的强引用;通常一个对象可能有多个强引用,只要对象存在强引用,垃圾回收器就不会回收这块内存。堆中的存在强引用的对象越来越多,最终内存不够用时,JVM就会抛出 java.lang.OutOfMemoryError这个错误! 软引用

By Jiacheng Wang

java

Auto proxy & Auto scan HTTP RPC library

周末在家,闲来无事,就想写一个服务器端自动扫描并注册,客户端自动扫描并代理的 RPC 组件,基于 Spring; 整理了一下思路,这个组件分三个部分:core、server和client;如下: 分三个步骤完成: * core:服务定义,数据序列化方式; * server:服务类自动扫描并注册、服务暴露; * client:客户端接口自动扫描并代理; 第一步 core * 服务定义:一个服务狭义地理解为一个函数,这里面就包含函数的入参数和出参;另外一个层面的问题,怎么样定位服务呢?站在 Java 角度,我使用ServiceNamespace和ServiceMapping两个注解,ServiceNamespace是一些同类服务的命名空间,ServiceMapping是具体服务入口;默认有一个 value 值,即为命名空间的名字和服务的名字; * 数据序列化方式:我这里选择了 ProtoStuff; 下面贴出相关代码: package io.http.rpc.core.annotation; import

By Jiacheng Wang