JRT和springboot比较测试

想要战胜他,必先理解他。这两天系统的学习Maven和跑springboot工程,从以前只是看着复杂,现在到亲手体验一下,亲自实践的才是更可靠的了解。

第一就是首先Maven侵入代码结构,代码一般要按约定搞src/main/java。如果是能严格执行测试的项目用着还行,需求性的项目测试根本跟不上,多增加层级就是增加负担。

第二就是Maven所带来的好处和所需要的环境配置和学习成本不匹配,增加学习成本,好处并没有绝对优势,当然如果架构没解决业务脚本化的问题,那么不同模块之间肯定相互引用很多,这时候是有优势的。所以根源不是Maven有多好、而是没解决业务编码便捷性问题,为了解决这个问题而引入的新问题,还要鼓吹有多好。然后就是Maven编译打包Spring太慢了,每个操作都要一分钟起,给喝咖啡带来了充分的时间。

同时经过测试发现Spring启动后太费内存了,什么都不做内存就占用1700兆了,同等启动的JRTWeb占用137兆,相差10倍以上。用多余内存给DolerGet做缓存用不香吗,多用的内存都能内存缓存千万级别的数据了。

然后就是环境太复杂,又要配Maven,又要运行ridis,又要运行nginx配置代理,还没进入开发过程就能浪费两天时间,发布还得再额外学。针对单体机构的软件真的有必要像互联网那样用ridis那些么?杀鸡焉用牛刀,部署的时候也得额外安装ridis(麻烦的要死)。

实现原理上Spring和JRT基本一致,只是面向发布和开发理念不同。两者都是内嵌Web服务器,然后按请求的url执行对应的业务类。不同的是Spring按注解反射初始化容器,按url通过注解从容器取对象执行。JRT按业务脚本目录给每个业务编译jar包,按请求url执行对应jar,理论上应该是JRT执行效率更高,因为不需要解析注解那些,直接按路径得到类全面执行就行了。注解用的好确实是简化程序,但是什么都注解也不一定好,感觉Spring用点过渡注解的意思。综合就是Spring流程定义更全面和规范、用着更复杂更加重量级,一个开发要全面掌控不容易。JRT更注重简化业务和环境,要哪些就做哪些,不引入多余的东西,可以达到一个开发全面掌控的效果。

Springboot编译用了55秒
在这里插入图片描述

用cmd启动要1分钟开外
在这里插入图片描述
idea启动用了52秒
在这里插入图片描述

JRT网站在5秒编译和启动完成,并用谷歌打开指定的页面
在这里插入图片描述

springboot网站启动后占用的内存
在这里插入图片描述

JRT网站启动后占用的内存
在这里插入图片描述

Spring启动定制测试程序。由于这个springboot的前后台分离没做到分而不离,所以需要nginx代码前端后后台来避免跨域,因此启动网站之前需要启动nginx,同时又依赖了ridis,这里一起给启动了。

package xxxxxx;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.Properties;@ServletComponentScan(basePackages = "com.xxxxxx")
@MapperScan(basePackages = {"xxxxx.**.mapper"})
@SpringBootApplication
@EnableAsync
public class LimpApplication {public static void main(String[] args) {//尝试启动相关软件try {if (IsOSLinux() == false) {System.out.println("检查D:\\nginx-1.23.2是否存在,尝试启动nginx");File niginx = new File("D:\\nginx-1.23.2\\nginx.exe");if (niginx.exists()) {System.out.println("存在nginx,尝试启动");StartExe(niginx.toString(), "D:\\nginx-1.23.2");}System.out.println("检查D:\\Redis-x64-3.2.100是否存在,尝试启动ridis");File ridis = new File("D:\\Redis-x64-3.2.100\\start.bat");if (ridis.exists()) {System.out.println("存在ridis,尝试启动");StartExe(ridis.toString(), "D:\\Redis-x64-3.2.100");}}}catch (Exception ex){}//启动前先启动ridis和nginxSpringApplication.run(LimpApplication.class, args);}/*** 判断OS** @return 得到是否是Linux*/public static boolean IsOSLinux() {Properties prop = System.getProperties();String os = prop.getProperty("os.name");if (os != null && os.toLowerCase().indexOf("linux") > -1) {return true;} else {return false;}}/*** 启动Exe* @param cmdStr 命令串* @param runDir 运行路径*/private static void StartExe(String cmdStr,String runDir){File directory = new File(runDir);try{System.out.println("启动:"+cmdStr);// 创建进程并执行命令Process process = Runtime.getRuntime().exec(cmdStr,null,directory);}catch (Exception ex){System.out.println(ex.getMessage());}}}

由于很多开发不知道启动后该打开那个url使用,所以需要在Spring启动后执行一个逻辑,用谷歌打开特定页面

package xxxxxxx;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;/*** 启动后执行,打开登录页面等*/
@Component
public class SpringBootApplicationRunner implements ApplicationRunner {/*** 启动后执行的逻辑* @param args* @throws Exception*/@Overridepublic void run(ApplicationArguments args) throws Exception {//打开页面辅助器OpenUrl("http://localhost:8527/imedicallis-hos/imedicallis/webui/test/form/demoHtml.html");}/*** 打印页面** @param url 路径* @throws Exception*/public static void OpenUrl(String url) throws Exception {//获取操作系统类型String os = System.getProperty("os.name").toLowerCase();//根据操作系统类型调用不同的命令if (os.contains("win")) {String path = GetChromePath();if (!path.isEmpty()) {File file = new File(path);if (file.exists()) {//使用Runtime.exec执行命令Runtime.getRuntime().exec(path + " "+ url);return;}}//使用Runtime.exec执行命令Runtime.getRuntime().exec("cmd /c start " + url);} else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {//Linux or Mac//使用ProcessBuilder创建一个进程ProcessBuilder pb = new ProcessBuilder("google-chrome", url);Process p = pb.start();} else {System.out.println("Unsupported OS");}}/*** 得到谷歌程序地址** @return* @throws Exception*/private static String GetChromePath() throws Exception {String path = GetExeRegedit("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");if (path.isEmpty()) {path = GetExeRegedit("HKEY_LOCAL_MACHINE\\HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");}if (!path.isEmpty()) {path += "\\chrome.exe";}return path;}/*** 得到注册表值** @param path 执行路径* @return* @throws Exception*/private static String GetExeRegedit(String path) throws Exception {Process ps = null;//当路径中有空格时,要把路径打上引号。ps = Runtime.getRuntime().exec("reg query \"" + path + "\"");ps.getOutputStream().close();InputStreamReader i = new InputStreamReader(ps.getInputStream());String line;BufferedReader ir = new BufferedReader(i);String ret = "";while ((line = ir.readLine()) != null) {if (line.contains("Path")) {String[] arr = line.split("    ");ret = arr[arr.length - 1];}}return ret;}
}

逻辑都是参照JRT启动来的,JRT的启动引导

package WebLoader;import JRT.Core.Util.LogUtils;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.*;
import java.net.Socket;
import java.nio.file.Paths;
import java.util.Scanner;/*** 网站加载器,参照操作系统引导概念,引导加载网站*/
public class Main {/*** 加载入口* @param args*/public static void main(String[] args) {//站点名称String WebName="JRTWeb";//自动打开的页面String OpenUrlStr="https://localhost:8081/JRTWeb/sys/form/frmCodeTableManager.aspx";boolean isWin=true;System.out.println("本控制台将负责引导启动网站");try{String osName = System.getProperty("os.name");String StartCmd="startup.bat";String ShutdownCmd="shutdown.bat";//判断Windowsif(osName != null && !osName.startsWith("Windows")) {isWin=false;StartCmd="startup.sh";ShutdownCmd="shutdown.sh";}File directory = new File("");// 参数为空String courseFile = directory.getCanonicalPath();System.out.println(courseFile);String binPath= Paths.get(courseFile,"WebSrc","bin").toString();String stopBatPath= Paths.get(courseFile,"WebSrc","bin",ShutdownCmd).toString();String startBatPath= Paths.get(courseFile,"WebSrc","bin",StartCmd).toString();if(isWin==true) {//结束打开页面工具KillProcess("DevOpenPage.exe");}System.out.println("尝试停止站点");System.out.println("执行脚本:"+stopBatPath);TryExecCmd(stopBatPath,binPath);//存在就删除File jrtOkFile=new File(Paths.get(courseFile,"WebSrc","webapps","JRTWeb","jrt.ok").toString());//不存在就创建,网站启动成功会删除if(!jrtOkFile.exists()){jrtOkFile.createNewFile();}//用线程打开页面ThreadOpenUrl(jrtOkFile,OpenUrlStr);System.out.println("尝试启动站点");System.out.println("执行脚本:"+startBatPath);TryExecCmd(startBatPath,binPath);}catch (Exception ex){System.out.println(ex.getMessage());}}/*** 打开页面* @param jrtOkFile 成功文件* @param OpenUrlStr 打开地址* @throws Exception*/private static void ThreadOpenUrl(File jrtOkFile,String OpenUrlStr) throws Exception{Thread thread = new Thread(new Runnable() {@Overridepublic void run() {try {int tryNum = 0;//等待网站启动while (true) {tryNum++;//标志文件没了就是网站启动了if (!jrtOkFile.exists()) {break;}if (tryNum > 200) {break;}Thread.sleep(100);}//打开页面辅助器OpenUrl("https://localhost:8081/JRTWeb/sys/form/frmDevOpenPage.aspx");//打开起始页面OpenUrl(OpenUrlStr);}catch (Exception ex){ex.printStackTrace();}}});thread.start();}//结束指定名称进程//processName:进程名public static void KillProcess(String processName) {try {String line;Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe");BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));while ((line = input.readLine()) != null) {if (line.contains(processName)) {String processId = line.split("\\s+")[1];Runtime.getRuntime().exec("taskkill /F /PID " + processId);System.out.println("Process " + processName + " has been killed.");}}input.close();} catch (IOException e) {e.printStackTrace();}}/*** 启动Exe* @param cmdStr 命令串* @param runDir 运行路径*/private static void StartExe(String cmdStr,String runDir){File directory = new File(runDir);try{System.out.println("启动:"+cmdStr);// 创建进程并执行命令Process process = Runtime.getRuntime().exec(cmdStr,null,directory);}catch (Exception ex){System.out.println(ex.getMessage());}}/*** 执行cmd* @param cmdStr 命令串* @param runDir 运行路径*/private static void TryExecCmd(String cmdStr,String runDir){File directory = new File(runDir);try{System.out.println("执行:"+cmdStr);// 创建进程并执行命令Process process = Runtime.getRuntime().exec(cmdStr,null,directory);// 获取命令行程序的输出结果BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));String line;while ((line = reader.readLine()) != null) {System.out.println(line);}// 等待命令行程序执行完毕int exitCode=process.waitFor();// 关闭资源reader.close();System.out.println("返回:"+exitCode);}catch (Exception ex){System.out.println(ex.getMessage());}}/*** 打印页面** @param url 路径* @throws Exception*/public static void OpenUrl(String url) throws Exception {//获取操作系统类型String os = System.getProperty("os.name").toLowerCase();//根据操作系统类型调用不同的命令if (os.contains("win")) {String path = GetChromePath();if (!path.isEmpty()) {File file = new File(path);if (file.exists()) {//使用Runtime.exec执行命令Runtime.getRuntime().exec(path + " "+ url);return;}}//使用Runtime.exec执行命令Runtime.getRuntime().exec("cmd /c start " + url);} else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {//Linux or Mac//使用ProcessBuilder创建一个进程ProcessBuilder pb = new ProcessBuilder("google-chrome", url);Process p = pb.start();} else {System.out.println("Unsupported OS");}}/*** 得到谷歌程序地址** @return* @throws Exception*/private static String GetChromePath() throws Exception {String path = GetExeRegedit("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");if (path.isEmpty()) {path = GetExeRegedit("HKEY_LOCAL_MACHINE\\HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe");}if (!path.isEmpty()) {path += "\\chrome.exe";}return path;}/*** 得到注册表值** @param path 执行路径* @return* @throws Exception*/private static String GetExeRegedit(String path) throws Exception {Process ps = null;//当路径中有空格时,要把路径打上引号。ps = Runtime.getRuntime().exec("reg query \"" + path + "\"");ps.getOutputStream().close();InputStreamReader i = new InputStreamReader(ps.getInputStream());String line;BufferedReader ir = new BufferedReader(i);String ret = "";while ((line = ir.readLine()) != null) {if (line.contains("Path")) {String[] arr = line.split("    ");ret = arr[arr.length - 1];}}return ret;}
}

我以前理解的和spring.net差不多的,配置一堆容器XML,搞多层。因为亲自经历过那种工程的失败,以及后面我推广的简化版Spring.net也因为维护麻烦被架空。实践springboot之后只能说比以前的有过之而无不及,工程和结构起码复杂了几倍的难度,没办法,谁让互联网大、分工详细的呢。传统软件生搬硬套只能说是在找死,哈哈哈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/422551.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2526. 随机数生成器(BSGS,推导)

题目路径: https://www.acwing.com/problem/content/2528/ 思路:

【UEFI基础】EDK网络框架(MTFTP4)

MTFTP4 在TCP/IP网络协议族中有FTP协议,但是UEFI下的MTFTP4并不是对FTP协议的实现,两者虽然功能上差不多,但是实现却是不同的。FTP下层使用TCP来连接: 而MTFTP4下层却是UDP4。 MTFTP4代码综述 MTFTP4的实现在NetworkPkg\Mtftp4…

【数据结构】在链队列中你可能忽视的二三事

链队列及其基本操作的C语言实现 导言一、链队列二、链队列的基本操作的实现2.1 链队列的数据类型2.2 链队列的初始化2.2.1 带头结点的链队列的初始化2.2.3 不带头结点的链队列的初始化 2.3 链队列的判空2.3.1 带头结点的链队列的判空2.3.2 不带头结点的链队列的判空 2.4 链队列…

数据集笔记:UJIIndoorLoc

1 数据集介绍 UJIIndoorLoc - UCI Machine Learning Repository UJIIndoorLoc是一个多建筑多楼层的室内定位数据库,用于测试依赖于WLAN/WiFi指纹的室内定位系统。 2 数据读取 数据分类训练数据和测试数据 import pandas as pdapd.read_csv(Downloads/ujiindoo…

《WebKit 技术内幕》学习之五(1): HTML解释器和DOM 模型

第五章 HTML 解释器和 DOM 模型 1.DOM 模型 1.1 DOM标准 DOM (Document Object Model)的全称是文档对象模型,它可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构。这里的文档可以是 HTML 文档、XML 文档或者 XHTML 文档。D…

《WebKit 技术内幕》学习之七(4): 渲染基础

4 WebKit软件渲染技术 4.1 软件渲染过程 在很多情况下,也就是没有那些需要硬件加速内容的时候(包括但不限于CSS3 3D变形、CSS3 03D变换、WebGL和视频),WebKit可以使用软件渲染技术来完成页面的绘制工作(除非读者强行…

pytorch学习笔记(十一)

优化器学习 把搭建好的模型拿来训练,得到最优的参数。 import torch.optim import torchvision from torch import nn from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear from torch.utils.data import DataLoaderdataset torchvision.datas…

《WebKit 技术内幕》学习之六(2): CSS解释器和样式布局

2 CSS解释器和规则匹配 在了解了CSS的基本概念之后,下面来理解WebKit如何来解释CSS代码并选择相应的规则。通过介绍WebKit的主要设施帮助理解WebKit的内部工作原理和机制。 2.1 样式的WebKit表示类 在DOM树中,CSS样式可以包含在“style”元素中或者使…

最全笔记软件盘点!你要的笔记神器都在这里:手写笔记、知识管理、文本笔记、协作笔记等!

在当今的信息化社会中,人们对信息的处理速度越来越快,从工作到生活,我们都面临着大量信息的冲击。在这样的环境下,一个能够帮助我们管理、整理和储存信息的好工具显得尤为重要,而笔记软件恰恰可以满足这些需求。 在选…

中仕教育:国考调剂和补录的区别是什么?

国考笔试成绩和进面名单公布之后,考生们就需要关注调剂和补录了,针对二者之间的区别很多考生不太了解,本文为大家解答一下关于国考调剂和补录的区别。 1.补录 补录是在公式环节之后进行的,主要原因是经过面试、体检和考察&#…

在vscode中悄无声息地摸鱼

想法 作为前端开发者,大多数人都使用 VSCode,并且可能会找一些在 VSCode 中可以摸鱼的插件。我也尝试了一些: Zhihu On VSCode,知乎摸鱼。 daily anime,追番插件。 韭菜盒子,看股票、基金、期货实时数据…

GitHub README-Template.md - README.md 模板

GitHub README-Template.md - README.md 模板 1. README-Template.md 预览模式2. README-Template.md 编辑模式References A template to make good README.md. https://gist.github.com/PurpleBooth/109311bb0361f32d87a2 1. README-Template.md 预览模式 2. README-Templat…