spring native 初体验实现 小米控制美的空调
目前关于 spring native 分享的文章还比较少
写这篇文章的主要目前是分享一下自己写的一个 小米控制美的空调 的程序 集成 spring native 过程中碰到的一些问题和解决方法
先放地址 : https://github.com/toohandsome/xiaomi2meidi 欢迎star
对比一下速度:

上面是编译成exe运行,下面是jar运行 快了10倍.
Spring Native 可以通过 GraalVM 将 Spring 应用程序编译成原生镜像,提供了一种新的方式来部署 Spring 应用。
ps: 这篇文章主要是将其打包成exe,没有打包成docker镜像
注意 目前 Spring Native 已经不支持jdk8 了,这里选用的jvm 是 graalvm-ce-java17-22.2.0, maven 选用 apache-maven-3.8.6
首先在 start.spring.io 中 选择 spring native 和 web

下载后导入idea,把项目的sdk 和 语法 均设置为 17

按照 Visual Studio ,我这里是vs2019 , 更高版本应该也可以,可以参考这篇文章 https://www.cnblogs.com/luguojun/p/16132521.html
环境配置好了以后,
在 resource 下 创建 META-INF/native-image/{groupId}/{artifactId}
然后在下面创建
native-image.properties
proxy-config.json
reflect-config.json
resource-config.json
serialization-config.json
如图所示

开始编译主要有几种错误
1. must not contain "."
must not contain ".". This can happen implicitly if the builder runs exclusively on the --module-path but specifies the com.oracle.svm.hosted.NativeImageGeneratorRunner main class without --module.
经过排除发现是 classpath 环境变量不能有 "." , 只要保留
%JAVA_HOME%\lib;
即可,如图

2.UnsupportedFeatureError
UnsupportedFeatureError: Proxy class defined by interfaces[xxxx] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement.
会一直报错 某某bean 不能被创建 , 需要在 proxy-config.json 中 增加 报错信息中的 xxx 接口.
但是这里有个问题就是 它这个错会有很多,你改了一个bean , 下一个bean 又会有不同的接口,所以我写了一个程序来自动分析
Pattern p = Pattern.compile("Proxy class defined by interfaces \\[(.*?)\\]");
for (int i = 0; i < 10000; i++) {
Process process = Runtime.getRuntime().exec("F:\\springnative\\start.bat");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream(), "gbk"));
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
System.out.println("success");
String s = RuntimeUtil.execForStr("\"F:\\springnative\\target\\xiaomi2meidi.exe\"");
System.out.println("exe: " + s);
Matcher matcher = p.matcher(s);
if (matcher.find()) {
var interfaces = matcher.group(1).replace("interface ", "").replace(" ", "");
String[] split = interfaces.split(",");
JSONArray jsonArray = new JSONArray();
for (String s1 : split) {
System.out.println(s1);
jsonArray.add(s1);
}
String s1 = Files.readString(Paths.get("F:\\springnative\\src\\main\\resources\\META-INF\\native-image\\com.yxd.xiaomi2meidi\\proxy-config.json"));
List<JSONArray> jsonArrays = JSON.parseArray(s1, JSONArray.class);
jsonArrays.add(jsonArray);
String pretty = JSON.toJSONString(jsonArrays, JSONWriter.Feature.PrettyFormat,
JSONWriter.Feature.WriteMapNullValue,
JSONWriter.Feature.WriteNullListAsEmpty);
try {
Files.writeString(Paths.get("F:\\springnative\\src\\main\\resources\\META-INF\\native-image\\com.yxd.xiaomi2meidi\\proxy-config.json"), pretty);
} catch (Exception e) {
e.printStackTrace();
}
} else {
break;
}
}
写的比较粗糙
大概就是循环编译运行,把运行后得到的日志 用正则匹配出来,然后自动加到 proxy-config.json 中去,然后又重新编译,直到它不报错为止.
3. logback 没有日志或者报错找不到 ConsoleAppender 等日志相关的类
增加依赖
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.1.8</version>
</dependency>
在 reflect-config.json 增加配置
{
"name": "ch.qos.logback.core.ConsoleAppender",
"allPublicConstructors": true,
"allPublicMethods": true
}
这里的类名是怎么来的呢,其实是 logback-spring.xml 里面的类, 还有
ch.qos.logback.core.rolling.RollingFileAppender
ch.qos.logback.classic.PatternLayout
ch.qos.logback.classic.encoder.PatternLayoutEncoder
ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy
等, 根据自己的xml配置
最后说一下 如何使用 小米控制美的空调
首先说一下思路.
想用小爱控制,那么最好的办法自然是接入小米的iot平台,然而小米并不对个人开发者开发.
退而求其次,我们可以找一个第三方厂商,由他们做中间人接入.
blinker (点灯科技) 是一家物联网技术提供商, 官网 点灯科技 (https://diandeng.tech/home) (虽然文档烂,但是功能不含糊,该有的都有. )
虽然我之前参考 使用ESP32和Blinker实现远程网络唤醒电脑(接入语音助手,以小爱同学为例) 这篇帖子用esp32成功控制了电脑远程开机
但是这次我不想依赖硬件设备,不然成本太高了( 一台空调设备就得买一个esp32),
然后我就想blinker的代码既然能在树莓派上面跑,自然我就能把核心逻辑抠出来用java重写一遍
好.正文开始
首先我们在blinker官网下载 他们的app,注册.
注册后 登录,显示如下界面

你们这里应该是空的,我加过所以有其他设备
然后我们点击右上角的 加号 进行添加一个新的设备

点击 独立设备

选择网络接入

得到 authKey, 保存好,后面要用

然后我们返回设备列表,点击刚新加的设备. 右上角 三个点

编辑设备名称

输入名称, 这个名称就是后面你喊小爱的名称,同时 要和 美的美居 app 里面空调的名称要相同

确认修改后,我们下载 github 上的 程序 ,运行后在 程序提示的配置文件中输入
phone: 美的app手机号, password: 美的app密码,acNameList: 空调名称(多个用逗号隔开), blinkerKeyList: 点灯的authkey(多个用逗号隔开,需要与空调名称一一对应)
{
"phone":"13812345678",
"password":"123456",
"acNameList":"书房空调,主卧空调,次卧空调",
"blinkerKeyList":"8*****2,2*****9,0******8",
"uid":"",
"accessToken":"",
"tokenPwd":"",
"homeId":"",
"appVersion":"",
"deviceId":"",
"deviceName":"",
"osVersion":"",
"deviceList":[]
}

程序正常运行后.
我们 打开 米家 app , 点击 "我的" , 往下翻 选择 "其他平台设备"

先点添加, 找到 点灯科技. ,然后点击 同步设备.

如果这里出现了你刚新加的设备说明就成功了.
然后就可以用小爱控制了
spring native 初体验实现 小米控制美的空调的更多相关文章
- Spring之初体验
Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...
- spring cloud 初体验
spring cloud分为注册端.客户端以及消费端 初体验的理解就是: 注册端就是将之前所有的应用在这边进行注册,然后给每个应用都生成自己的标识,这些应用就是来自于客户端,消费端则通过调用注册端(有 ...
- Spring(三) Spring IOC 初体验
Web IOC 容器初体验 我们还是从大家最熟悉的 DispatcherServlet 开始,我们最先想到的还是 DispatcherServlet 的 init() 方法.我们发现在 Dispath ...
- 第23章 Spring MVC初体验
23.1 鸟瞰Spring MVC 粗略的介绍了SpringMVC的主要组成部分,SpringMVC作为一个Web层的框架,最大的作用是把我从繁重的web.xml文件编写中解救出来,再也不要不停的添加 ...
- Spring入门初体验
Spring其实就是一个容器,让我们更方便的拿到想要的对象. 1.编写一个service // userService.java public interface userService { publ ...
- spring roo初体验
1.下载spring-roo-2.0.0.M1,并执行如下命令,在/usr/local/bin下面建立一个roo的软连接 sudo ln -s /Users/pud/Documents/still ...
- spring mvc(2) spring mvc初体验
前面讲到随着前端技术的发展,web的开发已经实现了前后分离,并且spring mvc经过多个版本的更新,使用上也变得不一样,并且提供了很多便捷的功能.但是为了便于理解,我们使用比较原始的方式搭建spr ...
- 215.Spring Boot+Spring Security:初体验
[视频&交流平台] SpringBoot视频:http://t.cn/R3QepWG Spring Cloud视频:http://t.cn/R3QeRZc SpringBoot Shiro视频 ...
- Spring JDBCTemplate连接SQL Server之初体验
前言 在没有任何框架的帮助下我们操作数据库都是用jdbc,耗时耗力,那么有了Spring,我们则不用重复造轮子了,先来试试Spring JDBC增删改查,其中关键就是构造JdbcTemplate类. ...
随机推荐
- 基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
随着Vue3和TypeScript的大浪潮不断袭来,越来越多的Vue项目采用了TypeScript的语法来编写代码,而Vue3的JS中的Setup语法糖也越来越广泛的使用,给我们这些以前用弱类型的JS ...
- 40+倍提升,详解 JuiceFS 元数据备份恢复性能优化之路
JuiceFS 支持多种元数据存储引擎,且各引擎内部的数据管理格式各有不同.为了便于管理,JuiceFS 自 0.15.2 版本提供了 dump 命令允许将所有元数据以统一格式写入到 JSON 文件进 ...
- python代码如何写的优雅?
简介 在实际项目中,我们可能一开始为了完成功能而忽视了代码的整体质量,因此,使用一些高阶的函数或方法,能够更加使我们的代码更加优雅.废话不多说,现在马上开始. 使用enumerate方法替代range ...
- 一篇文章带你搞定BFC~
一.什么是BFC 是 Block Formatting Contexts 的缩写,名为"块级格式化上下文". 是指浏览器中创建了一个独立的渲染区域,并且拥有一套渲染规则,他决定了其 ...
- 『叶问』#41,三节点的MGR集群,有两个节点宕机后还能正常工作吗
『叶问』#41,三节点的MGR集群,有两个节点宕机后还能正常工作吗 每周学点MGR知识. 1. 三节点的MGR集群,有两个节点宕机后还能正常工作吗 要看具体是哪种情况. 如果两个节点是正常关闭的话,则 ...
- 在django中前后端传输数据的编码格式(contentType)
写在前面 在django中,针对前后端传输数据的编码格式,我们主要研究的是post请求:因为get请求传输的数据往往是直接放在url的后面的!如: url?username=zhang&pas ...
- Docker 06 部署Nginx
参考源 https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from=333.999.0.0 https://www.bilibili.com/vid ...
- TDM 三部曲 (与 Deep Retrieval)
推荐系统的主要目的是从海量物品库中高效检索用户最感兴趣的物品,既然是"海量",意味着用户基本不可能浏览完所有的物品,所以才需要推荐系统来辅助用户高效获取感兴趣的信息.同样也正是因为 ...
- openstack 创建虚拟机失败
虚拟机创建失败 用户创建一台虚拟机,虚拟机使用4个网络平面,所以虚拟机选择了4个不同平面的网络,创建虚拟机一直在孵化的过程中,最后创建虚拟机失败. 失败后返回的报错日志 Build of ins ...
- 如何定义 Java 的回调函数,与 JavaScript 回调函数的区别
JavaScript 中的回调函数 在 JavaScript 中经常使用回调函数,比如:get 请求.post 请求等异步任务.在我们请求之前以及请求之后,都需要完成一些固定的操作,比如:请求之前先从 ...