java种的hutool库接口说明和整理
1. Hutool库基本介绍
1.1. 地址
官网地址:https://www.hutool.cn/
1.2. 基本介绍
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool中的工具方法来自每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;
Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。
1.3. 包含组件
一个Java基础工具类,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类,同时提供以下组件:
模块 | 介绍 |
---|---|
hutool-aop | JDK动态代理封装,提供非IOC下的切面支持 |
hutool-bloomFilter | 布隆过滤,提供一些Hash算法的布隆过滤 |
hutool-cache | 简单缓存实现 |
hutool-core | 核心,包括Bean操作、日期、各种Util等 |
hutool-cron | 定时任务模块,提供类Crontab表达式的定时任务 |
hutool-crypto | 加密解密模块,提供对称、非对称和摘要算法封装 |
hutool-db | JDBC封装后的数据操作,基于ActiveRecord思想 |
hutool-dfa | 基于DFA模型的多关键字查找 |
hutool-extra | 扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等) |
hutool-http | 基于HttpUrlConnection的Http客户端封装 |
hutool-log | 自动识别日志实现的日志门面 |
hutool-script | 脚本执行封装,例如Javascript |
hutool-setting | 功能更强大的Setting配置文件和Properties封装 |
hutool-system | 系统参数调用封装(JVM信息等) |
hutool-json | JSON实现 |
hutool-captcha | 图片验证码实现 |
hutool-poi | 针对POI中Excel和Word的封装 |
hutool-socket | 基于Java的NIO和AIO的Socket封装 |
hutool-jwt | JSON Web Token (JWT)封装实现 |
2. 基本使用
2.1. 安装使用
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version>
</dependency>
2.2. hutool-aop切片使用
2.2.1. 启动main函数
import aop.Animal;
import aop.Cat;
import aop.TimeIntervalAspect;
import cn.hutool.aop.ProxyUtil;
import cn.hutool.core.lang.Console; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: PACKAGE_NAME * @CreateTime: 2023-08-09 16:38 * @Description: TODO * @Version: 1.0 */public class Application { public static void main(String[] args) { aopDeom(); } private static void aopDeom() { Console.log("-----------------------aop功能测试-----------------------"); Cat cat=new Cat(); TimeIntervalAspect pTimeIntervalAspect=new TimeIntervalAspect(); Animal proxyCat = ProxyUtil.proxy(cat, pTimeIntervalAspect); Console.log("创建对象完成"); proxyCat.eat(); }
}
2.2.2. Aop接口
package aop; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: aop * @CreateTime: 2023-08-09 16:50 * @Description: TODO * @Version: 1.0 */public interface Animal{ void eat();
}
2.2.3. 实现Cat子类
package aop; import cn.hutool.core.lang.Console; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: aop * @CreateTime: 2023-08-09 16:39 * @Description: TODO * @Version: 1.0 */public class Cat implements Animal{ public void eat() { Console.log("猫吃鱼"); }
}
2.2.4. 切片操作类
package aop; import cn.hutool.aop.aspects.SimpleAspect;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.lang.Console; import java.lang.reflect.Method; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: aop * @CreateTime: 2023-08-09 16:40 * @Description: TODO * @Version: 1.0 */public class TimeIntervalAspect extends SimpleAspect { //TimeInterval为Hutool实现的一个计时器 private TimeInterval interval = new TimeInterval(); @Override public boolean before(Object target, Method method, Object[] args) { Console.log("函数执行开始前[{}.{}] ", target.getClass().getName(), method.getName()); interval.start(); return true; } @Override public boolean after(Object target, Method method, Object[] args, Object returnVal) { Console.log("函数执行完毕后 [{}.{}] 共耗时 [{}]ms", target.getClass().getName(), method.getName(), interval.intervalMs()); return true; }
}
2.2.5. 代码输出
-----------------------aop功能测试-----------------------
创建对象完成
函数执行开始前[aop.Cat.eat]
猫吃鱼
函数执行完毕后 [aop.Cat.eat] 共耗时 [7]ms
与目标 VM 断开连接, 地址为: ''127.0.0.1:33198',传输: '套接字''
2.3. hutool-bloomFilter布隆过滤使用
2.3.1. main函数
public static void main(String[] args) { bloomFilterSample.sampleDemo(); }
2.3.2. bloomFilterSample案例代码
package bloomFilter; import cn.hutool.bloomfilter.BitMapBloomFilter;
import cn.hutool.bloomfilter.BloomFilter;
import cn.hutool.core.lang.Console; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: bloomFilter * @CreateTime: 2023-08-09 17:02 * @Description: TODO * @Version: 1.0 */public class bloomFilterSample { public static void sampleDemo() { Console.log("-----------------------hutool-bloomFilter功能测试-----------------------"); // 创建BloomFilter实例 BloomFilter bloomFilter = new BitMapBloomFilter(100); // 添加元素到BloomFilter bloomFilter.add("element1"); bloomFilter.add("element2"); // 检查元素是否存在于BloomFilter中 // 返回true boolean exists1 = bloomFilter.contains("element1"); // 返回false boolean exists2 = bloomFilter.contains("element3"); Console.log("Element 1 exists: " + exists1); Console.log("Element 3 exists: " + exists2); }
}
2.3.3. 代码输出
-----------------------hutool-bloomFilter功能测试-----------------------
Element 1 exists: true
Element 3 exists: false
与目标 VM 断开连接, 地址为: ''127.0.0.1:1696',传输: '套接字''
2.4. hutool-cache简单缓存实现
2.4.1. 介绍
Hutoo-cache模块提供了几种缓存策略实现:
2.4.1.1. FIFOCache
FIFO(first in first out) 先进先出策略。元素不停的加入缓存直到缓存满为止,当缓存满时,清理过期缓存对象,清理后依旧满则删除先入的缓存(链表首部对象)。
优点:简单快速 缺点:不灵活,不能保证最常用的对象总是被保留
2.4.1.2.LFUCache
LFU(least frequently used) 最少使用率策略。根据使用次数来判定对象是否被持续缓存(使用率是通过访问次数计算),当缓存满时清理过期对象,清理后依旧满的情况下清除最少访问(访问计数最小)的对象并将其他对象的访问数减去这个最小访问数,以便新对象进入后可以公平计数。
2.4.1.3. LRUCache
LRU (least recently used)最近最久未使用缓存。根据使用时间来判定对象是否被持续缓存,当对象被访问时放入缓存,当缓存满了,最久未被使用的对象将被移除。此缓存基于LinkedHashMap,因此当被缓存的对象每被访问一次,这个对象的key就到链表头部。这个算法简单并且非常快,他比FIFO有一个显著优势是经常使用的对象不太可能被移除缓存。缺点是当缓存满时,不能被很快的访问。
2.4.1.4. TimedCache
定时缓存,对被缓存的对象定义一个过期时间,当对象超过过期时间会被清理。此缓存没有容量限制,对象只有在过期后才会被移除
2.4.1.5. WeakCache
弱引用缓存。对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除。该类使用了WeakHashMap做为其实现,缓存的清理依赖于JVM的垃圾回收。
2.4.1.6. FileCach
FileCach是一个独立的缓存,主要是将小文件以byte[]的形式缓存到内容中,减少文件的访问,以解决频繁读取文件引起的性能问题。
主要实现有:
- LFUFileCache
- LRUFileCache
2.4.2. main函数
public static void main(String[] args) { cacheSample.cacheDemo();
}
2.4.3. cacheSample案例代码
package cache; import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.lang.Console;
import cn.hutool.core.thread.ThreadUtil; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: cache * @CreateTime: 2023-08-09 17:15 * @Description: TODO * @Version: 1.0 */public class cacheSample { public static void cacheDemo() { Console.log("-----------------------hutool-cache功能测试-----------------------"); FIFOCacheDemo(); LFUCacheDemo(); LRUCacheDemo(); TimedCacheDemo(); } private static void FIFOCacheDemo() { Console.log("----先入先出-FIFOCache--------------------------------------------"); Cache<String,String> fifoCache = CacheUtil.newFIFOCache(3); //加入元素,每个元素可以设置其过期时长,DateUnit.SECOND.getMillis()代表每秒对应的毫秒数,在此为3秒 fifoCache.put("key1", "xiaocaiTest----value1", DateUnit.SECOND.getMillis() * 3); fifoCache.put("key2", "xiaocaiTest----value2", DateUnit.SECOND.getMillis() * 3); fifoCache.put("key3", "xiaocaiTest----value3", DateUnit.SECOND.getMillis() * 3); Console.log("key1值为:{}",fifoCache.get("key1")); Console.log("缓存中插入key4值"); //由于缓存容量只有3,当加入第四个元素的时候,根据FIFO规则,最先放入的对象将被移除 fifoCache.put("key4", "xiaocaiTest----value4", DateUnit.SECOND.getMillis() * 3); //value1为null Console.log("key1值为:{}",fifoCache.get("key1")); } private static void LFUCacheDemo() { Console.log("----最少使用-LFUCache--------------------------------------------"); Cache<String, String> lfuCache = CacheUtil.newLFUCache(3); //通过实例化对象创建 //LFUCache<String, String> lfuCache = new LFUCache<String, String>(3); lfuCache.put("key1", "xiaocaiTest----value1", DateUnit.SECOND.getMillis() * 3); Console.log("key1值为:{}",lfuCache.get("key1")); lfuCache.put("key2", "xiaocaiTest----value2", DateUnit.SECOND.getMillis() * 3); lfuCache.put("key3", "xiaocaiTest----value3", DateUnit.SECOND.getMillis() * 3); Console.log("缓存中插入key4值"); lfuCache.put("key4", "xiaocaiTest----value4", DateUnit.SECOND.getMillis() * 3); //由于缓存容量只有3,当加入第四个元素的时候,根据LRU规则,最少使用的将被移除(2,3被移除) Console.log("key2值为:{}",lfuCache.get("key2")); Console.log("key3值为:{}",lfuCache.get("key3")); } private static void LRUCacheDemo() { Console.log("----最近最久未使用-LRUCache--------------------------------------------"); Cache<String, String> lruCache = CacheUtil.newLRUCache(3); //通过实例化对象创建 //LRUCache<String, String> lruCache = new LRUCache<String, String>(3); lruCache.put("key1", "xiaocaiTest----value1", DateUnit.SECOND.getMillis() * 3); lruCache.put("key2", "xiaocaiTest----value2", DateUnit.SECOND.getMillis() * 3); lruCache.put("key3", "xiaocaiTest----value3", DateUnit.SECOND.getMillis() * 3); //使用时间推近 Console.log("key1值为:{}",lruCache.get("key1")); lruCache.put("key4", "xiaocaiTest----value4", DateUnit.SECOND.getMillis() * 3); //由于缓存容量只有3,当加入第四个元素的时候,根据LRU规则,最少使用的将被移除(2被移除) Console.log("key2值为:{}",lruCache.get("key2")); } private static void TimedCacheDemo() { Console.log("----超时-TimedCache--------------------------------------------"); //创建缓存,默认4毫秒过期 TimedCache<String, String> timedCache = CacheUtil.newTimedCache(4); //实例化创建 //TimedCache<String, String> timedCache = new TimedCache<String, String>(4); timedCache.put("key1", "xiaocaiTest----value1", 1);//1毫秒过期 timedCache.put("key2", "xiaocaiTest----value2", DateUnit.SECOND.getMillis() * 5); timedCache.put("key3", "xiaocaiTest----value3");//默认过期(4毫秒) //启动定时任务,每5毫秒清理一次过期条目,注释此行首次启动仍会清理过期条目 timedCache.schedulePrune(5); Console.log("等待5毫秒"); //等待5毫秒 ThreadUtil.sleep(5); //5毫秒后由于value2设置了5毫秒过期,因此只有value2被保留下来 Console.log("key1值为:{}",timedCache.get("key1")); Console.log("key2值为:{}",timedCache.get("key2")); //5毫秒后,由于设置了默认过期,key3只被保留4毫秒,因此为null Console.log("key3值为:{}",timedCache.get("key3")); // //取消定时清理
// timedCache.cancelPruneSchedule(); }
}
2.4.4. 代码输出
-----------------------hutool-cache功能测试-----------------------
----先入先出-FIFOCache--------------------------------------------
key1值为:xiaocaiTest----value1
缓存中插入key4值
key1值为:null
----最少使用-LFUCache--------------------------------------------
key1值为:xiaocaiTest----value1
缓存中插入key4值
key2值为:null
key3值为:null
----最近最久未使用-LRUCache--------------------------------------------
key1值为:xiaocaiTest----value1
key2值为:null
----超时-TimedCache--------------------------------------------
等待5毫秒
key1值为:null
key2值为:xiaocaiTest----value2
key3值为:null
2.5. hutool-cron使用
2.5.1. main函数
public static void main(String[] args) { cronSample.cronDemo();
}
2.5.2. cronSample案例代码
package cron; import cn.hutool.core.lang.Console;
import cn.hutool.cron.CronUtil;
import cn.hutool.cron.task.Task; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: cron * @CreateTime: 2023-08-09 17:43 * @Description: TODO * @Version: 1.0 */public class cronSample { static int index=0; public static void cronDemo(){ Console.log("----全局定时任务-CronUtil--------------------------------------------"); CronUtil.schedule("*/2 * * * * *", new Task() { @Override public void execute() { Console.log("任务执行:{}",index++); } }); // 支持秒级别定时任务 CronUtil.setMatchSecond(true); CronUtil.start(); }
}
2.5.3. 代码输出
----全局定时任务-CronUtil--------------------------------------------
[2023-08-09 17:47:11] [DEBUG] cn.hutool.log.LogFactory: Use [Hutool Console Logging] Logger As Default.
任务执行:0
任务执行:1
任务执行:2
任务执行:3
2.6. hutool-crypto使用
2.6.1. 介绍
加密分为三种:
- 对称加密(symmetric),例如:AES、DES等
- 非对称加密(asymmetric),例如:RSA、DSA等
- 摘要加密(digest),例如:MD5、SHA-1、SHA-256、HMAC等
hutool-crypto针对这三种加密类型分别封装,并提供常用的大部分加密算法。
对于非对称加密,实现了:
- RSA
- DSA
对于对称加密,实现了:
- AES
- ARCFOUR
- Blowfish
- DES
- DESede
- RC2
- PBEWithMD5AndDES
- PBEWithSHA1AndDESede
- PBEWithSHA1AndRC2_40
对于摘要算法实现了:
- MD2
- MD5
- SHA-1
- SHA-256
- SHA-384
- SHA-512
- HmacMD5
- HmacSHA1
- HmacSHA256
- HmacSHA384
- HmacSHA512
其中,针对常用到的算法,模块还提供SecureUtil
工具类用于快速实现加密。
2.7. hutool-db使用
2.7.1. 介绍
Hutool-db是一个在JDBC基础上封装的数据库操作工具类,通过包装,使用ActiveRecord思想操作数据库。在Hutool-db中,使用Entity(本质上是个Map)代替Bean来使数据库操作更加灵活,同时提供Bean和Entity的转换提供传统ORM的兼容支持。
笔者没有使用过,等有时间了系统整理一下
2.8. hutool-dfa使用
2.8.1. DFA介绍
DFA全称为:Deterministic Finite Automaton,即确定有穷自动机。因为本人算法学的不好,有兴趣的可以看这篇博客: 基于DFA敏感词查询的算法简析(opens new window)
解释起来原理其实也不难,就是用所有关键字构造一棵树,然后用正文遍历这棵树,遍历到叶子节点即表示文章中存在这个关键字。
我们暂且忽略构建关键词树的时间,每次查找正文只需要O(n)复杂度就可以搞定。
针对DFA算法以及网上的一些实现,Hutool做了整理和改进,最终形成现在的Hutool-dfa模块。
2.8.2. main函数
public static void main(String[] args) { dfaSample.dfaDemo();
}
2.8.3. dfaSample案例代码
package dfa; import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Console;
import cn.hutool.dfa.WordTree; import java.util.List; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: dfa * @CreateTime: 2023-08-09 17:59 * @Description: TODO * @Version: 1.0 */public class dfaSample { public static void dfaDemo(){ Console.log("----DFA查找--------------------------------------------"); WordTree tree = new WordTree(); tree.addWord("大"); tree.addWord("大土豆"); tree.addWord("土豆"); tree.addWord("刚出锅"); tree.addWord("出锅"); //正文 String text = "我有一颗大土豆,刚出锅的"; Console.log("情况一:标准匹配,匹配到最短关键词,并跳过已经匹配的关键词"); // 【大】被匹配,最短匹配原则【大土豆】被跳过,【土豆继续被匹配】 // 【刚出锅】被匹配,由于不跳过已经匹配的词,【出锅】被匹配 List<String> matchAll_01 = tree.matchAll(text, -1, false, false);
// Assert.equals(matchAll_01.toString(), "[大, 土豆, 刚出锅, 出锅]"); Console.log("输出结果为{}",matchAll_01.toString()); Console.log("情况二:匹配到最短关键词,不跳过已经匹配的关键词"); // 【大】被匹配,最短匹配原则【大土豆】被跳过,【土豆继续被匹配】 // 【刚出锅】被匹配,由于不跳过已经匹配的词,【出锅】被匹配 List<String> matchAll_02 = tree.matchAll(text, -1, true, false);
// Assert.equals(matchAll_02.toString(), "[大, 土豆, 刚出锅, 出锅]"); Console.log("输出结果为{}",matchAll_02.toString()); Console.log("情况三:匹配到最长关键词,跳过已经匹配的关键词"); // 匹配到【大】,由于到最长匹配,因此【大土豆】接着被匹配 // 由于【大土豆】被匹配,【土豆】被跳过,由于【刚出锅】被匹配,【出锅】被跳过 List<String> matchAll_03 = tree.matchAll(text, -1, false, true);
// Assert.equals(matchAll_03.toString(), "[大, 大土豆, 刚出锅]"); Console.log("输出结果为{}",matchAll_03.toString()); Console.log("情况四:匹配到最长关键词,不跳过已经匹配的关键词(最全关键词)"); // 匹配到【大】,由于到最长匹配,因此【大土豆】接着被匹配,由于不跳过已经匹配的关键词,土豆继续被匹配 // 【刚出锅】被匹配,由于不跳过已经匹配的词,【出锅】被匹配 List<String> matchAll_04 = tree.matchAll(text, -1, true, true);
// Assert.equals(matchAll_03.toString(), "[大, 大土豆, 土豆, 刚出锅, 出锅]"); Console.log("输出结果为{}",matchAll_04.toString()); }
}
2.8.4. 代码输出
----DFA查找--------------------------------------------
情况一:标准匹配,匹配到最短关键词,并跳过已经匹配的关键词
输出结果为[大, 土豆, 刚出锅]
情况二:匹配到最短关键词,不跳过已经匹配的关键词
输出结果为[大, 土豆, 刚出锅, 出锅]
情况三:匹配到最长关键词,跳过已经匹配的关键词
输出结果为[大, 土豆, 刚出锅]
情况四:匹配到最长关键词,不跳过已经匹配的关键词(最全关键词)
输出结果为[大, 大土豆, 土豆, 刚出锅, 出锅]
2.9. hutool-extrat使用
2.9.1. 由来
由于Hutool的原则是不依赖于其它配置文件,但是很多时候我们需要针对第三方非常棒的库做一些工具类化的支持,因此Hutoo-extra包主要用于支持第三方库的工具类支持。
2.9.2. 介绍
现阶段扩展包括:
2.9.2.1. 模板引擎封装工具类
2.9.2.2. Servlet封装
2.9.2.3. Jsch库封装(SSH和Sftp)
2.9.2.4. Apache Commons Net封装(FTP部分)
2.9.2.5. 邮件封装
2.9.2.6.Zxing封装(二维码)
2.9.3. 案例代码另开博文整理
2.10. hutool-http使用
2.10.1. 由来
在Java的世界中,Http客户端之前一直是Apache家的HttpClient占据主导,但是由于此包较为庞大,API又比较难用,因此并不使用很多场景。而新兴的OkHttp、Jodd-http固然好用,但是面对一些场景时,学习成本还是有一些的。很多时候,我们想追求轻量级的Http客户端,并且追求简单易用。而JDK自带的HttpUrlConnection可以满足大部分需求。Hutool针对此类做了一层封装,使Http请求变得无比简单。
2.10.2. 介绍
Hutool-http针对JDK的HttpUrlConnection做一层封装,简化了HTTPS请求、文件上传、Cookie记忆等操作,使Http请求变得无比简单。
Hutool-http的核心集中在两个类:
- HttpRequest
- HttpResponse
同时针对大部分情境,封装了HttpUtil工具类。
2.10.2. Hutool-http优点
- 根据URL自动判断是请求HTTP还是HTTPS,不需要单独写多余的代码。
- 表单数据中有File对象时自动转为
multipart/form-data
表单,不必单做做操作。 - 默认情况下Cookie自动记录,比如可以实现模拟登录,即第一次访问登录URL后后续请求就是登录状态。
- 自动识别304跳转并二次请求
- 自动识别页面编码,即根据header信息或者页面中的相关标签信息自动识别编码,最大可能避免乱码。
- 自动识别并解压Gzip格式返回内容
2.10.3.使用
最简单的使用莫过于用HttpUtil工具类快速请求某个页面:
//GET请求
String content = HttpUtil.get(url);
一行代码即可搞定,当然Post请求也很简单:
//POST请求
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");String result1 = HttpUtil.post(url, paramMap);
Post请求只需使用Map预先制定form表单项即可。
2.10.4.更多
2.10.5. 案例代码另开博文整理
2.11. hutool-log
2.11.1. 介绍
Hutool-log做为一个日志门面,为了兼容各大日志框架,一个用于自动创建日志对象的日志工厂类必不可少。
LogFactory
类用于灵活的创建日志对象,通过static方法创建我们需要的日志,主要功能如下:
-
LogFactory.get
自动识别引入的日志框架,从而创建对应日志框架的门面Log对象(此方法创建一次后,下次再次get会根据传入类名缓存Log对象,对于每个类,Log对象都是单例的),同时自动识别当前类,将当前类做为类名传入日志框架。 -
LogFactory.createLog
与get方法作用类似。但是此方法调用后会每次创建一个新的Log对象。 -
LogFactory.setCurrentLogFactory
自定义当前日志门面的日志实现类。当引入多个日志框架时,我们希望自定义所用的日志框架,调用此方法即可。需要注意的是,此方法为全局方法,在获取Log对象前只调用一次即可。
2.11.2. 使用
2.11.3. #获取当前类对应的Log对象:
//推荐创建不可变静态类成员变量
private static final Log log = LogFactory.get();
如果你想获得自定义name的Log对象(像普通Log日志实现一样),那么可以使用如下方式获取Log:
private static final Log log = LogFactory.get("我是一个自定义日志名");
2.11.4. 自定义日志实现
//自定义日志实现为Apache Commons Logging
LogFactory.setCurrentLogFactory(new ApacheCommonsLogFactory());//自定义日志实现为JDK Logging
LogFactory.setCurrentLogFactory(new JdkLogFactory());//自定义日志实现为Console Logging
LogFactory.setCurrentLogFactory(new ConsoleLogFactory());
2.11.5. 自定义日志工厂(自定义日志门面实现)
LogFactory是一个抽象类,我们可以继承此类,实现createLog
方法即可(同时我们可能需要实现Log接口来达到自定义门面的目的),这样我们就可以自定义一个日志门面。最后通过LogFactory.setCurrentLogFactory
方法装入这个自定义LogFactory即可实现自定义日志门面。
PS 自定义日志门面的实现可以参考
cn.hutool.log.dialect
包中的实现内容自定义扩展。 本质上,实现Log接口,做一个日志实现的Wrapper,然后在相应的工厂类中创建此Log实例即可。同时,LogFactory中还可以初始化一些启动配置参数。
2.12. hutool-script使用
2.12.1. main函数
public static void main(String[] args) { scriptSample.scriptDemo(); }
2.12.2. scriptSample案例代码
package script; import cn.hutool.core.lang.Console;
import cn.hutool.script.ScriptRuntimeException;
import cn.hutool.script.ScriptUtil; import javax.script.CompiledScript;
import javax.script.ScriptException; /** * @BelongsProject: HutoolStudyDemo * @BelongsPackage: script * @Author: 蔡名洋 * @CreateTime: 2023-08-10 09:57 * @Description: TODO * @Version: 1.0 */public class scriptSample { public static void scriptDemo() { Console.log("----Script工具-ScriptUtil--------------------------------------------"); CompiledScript script = ScriptUtil.compile("print('Script test!');"); try { script.eval(); } catch (ScriptException e) { throw new ScriptRuntimeException(e); } }
}
2.12.3. 代码输出
----Script工具-ScriptUtil--------------------------------------------
Script test!
2.13. hutool-setting使用
2.13.1. 由来
2.13.2.Setting
众所周知,Java中广泛应用的配置文件Properties存在一个特别大的诟病:不支持中文。每次使用时,如果想存放中文字符,必须借助IDE相关插件才能转为Unicode符号,而这种反人类的符号在命令行下根本没法看(想想部署在服务器上后修改配置文件是一件多么痛苦的事情)
于是,在很多框架中开始渐渐抛弃Properties文件而转向XML配置文件(例如Hibernate和Spring早期版本)。但是XML罗嗦的配置方式实在无法忍受。于是,Setting诞生。
2.13.3. Props
Properties的第二个问题是读取非常不方便,需要我们自己写长长的代码进行load操作:
properties = new Properties();
try {Class clazz = Demo1.class;InputStream inputestream = clazz.getResourceAsStream("db.properties");properties.load( inputestream);
}catch (IOException e) {//ignore
}
而Props则大大简化为:
Props props = new Props("db.properties");
考虑到Properties使用依旧广泛,因此封装了Props类以应对兼容性。
2.14. hutool-system使用
2.14.1. 系统属性调用-SystemUtil
2.14.1.1. 概述
此工具是针对System.getProperty(name)
的封装,通过此工具,可以获取如下信息:
2.14.1.2. Java Virtual Machine Specification信息
SystemUtil.getJvmSpecInfo();
2.14.1.3. Java Virtual Machine Implementation信息
SystemUtil.getJvmInfo();
2.14.1.4. Java Specification信息
SystemUtil.getJavaSpecInfo();
2.14.1.5. Java Implementation信息
SystemUtil.getJavaInfo();
2.14.1.6. Java运行时信息
SystemUtil.getJavaRuntimeInfo();
2.14.1.7. 系统信息
SystemUtil.getOsInfo();
2.14.1.8. 用户信息
SystemUtil.getUserInfo();
2.14.1.9. 当前主机网络地址信息
SystemUtil.getHostInfo();
2.14.1.10. 运行时信息,包括内存总大小、已用大小、可用大小等
SystemUtil.getRuntimeInfo();
2.14.2. Oshi封装-OshiUtil
2.14.2.1. 概述
Oshi
是Java的免费基于JNA的操作系统和硬件信息库,Github地址是:https://github.com/oshi/oshi
它的优点是不需要安装任何其他本机库,并且旨在提供一种跨平台的实现来检索系统信息,例如操作系统版本,进程,内存和CPU使用率,磁盘和分区,设备,传感器等。
这个库可以监测的内容包括:
- 计算机系统和固件,底板
- 操作系统和版本/内部版本
- 物理(核心)和逻辑(超线程)CPU,处理器组,NUMA节点
- 系统和每个处理器的负载百分比和滴答计数器
- CPU正常运行时间,进程和线程
- 进程正常运行时间,CPU,内存使用率,用户/组,命令行
- 已使用/可用的物理和虚拟内存
- 挂载的文件系统(类型,可用空间和总空间)
- 磁盘驱动器(型号,序列号,大小)和分区
- 网络接口(IP,带宽输入/输出)
- 电池状态(电量百分比,剩余时间,电量使用情况统计信息)
- 连接的显示器(带有EDID信息)
- USB设备
- 传感器(温度,风扇速度,电压)
也就是说配合一个前端界面,完全可以搞定系统监控了。
2.14.2.2. 使用
先引入Oshi库:
<dependency><groupId>com.github.oshi</groupId><artifactId>oshi-core</artifactId><version>5.6.1</version>
</dependency>
然后可以调用相关API获取相关信息。
例如我们像获取内存总量:
long total = OshiUtil.getMemory().getTotal();
我们也可以获取CPU的一些信息:
CpuInfo cpuInfo = OshiUtil.getCpuInfo();
Console.log(cpuInfo);
CpuInfo{cpu核心数=12, CPU总的使用率=12595.0, CPU系统使用率=1.74, CPU用户使用率=6.69, CPU当前等待率=0.0, CPU当前空闲率=91.57, CPU利用率=8.43, CPU型号信息='AMD Ryzen 5 4600U with Radeon Graphics 1 physical CPU package(s)6 physical CPU core(s)12 logical CPU(s)
Identifier: AuthenticAMD Family 23 Model 96 Stepping 1
ProcessorID: xxxxxxxxx
Microarchitecture: unknown'}
2.15. hutool-json和hutool-xml
==**案例代码另开博文整理
2.16. hutool-poi
==**案例代码另开博文整理
2.17. hutool-socket
==**案例代码另开博文整理
2.18. hutool-jwt
==**案例代码另开博文整理
相关文章:
java种的hutool库接口说明和整理
1. Hutool库基本介绍 1.1. 地址 官网地址:https://www.hutool.cn/ 1.2. 基本介绍 Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅…...

控制国外各类电液伺服阀放大器
控制通用型不带反馈信号输入的伺服阀放大器,对射流管式电液伺服阀、喷嘴挡板式电液伺服阀及国外各类电液伺服阀进行控制。 通过系统参数有10V和4~20mA输入指令信号选择; 供电电源: 24VDC(标准) 输出电流:最大可达10…...
【go语言基础】go中的方法
先思考一个问题,什么是方法,什么是函数? 方法是从属于某个结构体或者非结构体的。在func这个关键字和方法名中间加了一个特殊的接收器类型,这个接收器可以是结构体类型的或者是非结构体类型的。从属的结构体获取该方法。 函数则…...

Go 语言并发编程 及 进阶与依赖管理
1.0 从并发编程本质了解Go高性能的本质 1.1 Goroutine 协程可以理解为轻量级线程; Go更适合高并发场景原因之一:Go语言一次可以创建上万协成; “快速”:开多个协成 打印。 go func(): 在函数前加 go 代表 创建协程; time.Sleep():…...

绽放趋势:Python折线图数据可视化艺术
文章目录 一 json数据格式1.1 json数据格式认识1.2 Python数据和Json数据的相互转换 二 pyecharts模块2.1 pyecharts概述2.2 pyecharts模块安装 三 pyecharts快速入门3.1 基础折线图3.2 pyecharts配置选项3.2.1 全局配置选项 3.4 折线图相关配置3.4.1 .add_yaxis相关配置选项3.…...

BGP小综合
实验要求及拓扑 一、思路 1.使用OSPF使R2-R7之间可通。 2.各自宣告AS区域,两个区域两两之间建邻,AS2两个小区域之间建联邦(R2与R5、R4与R7)。 3.使R3、R6为路由反射器 RR反射器选取各小区域的路由器作为客户端 、非客户端 4.优…...

一起学数据结构(3)——万字解析:链表的概念及单链表的实现
上篇文章介绍了数据结构的一些基本概念,以及顺序表的概念和实现,本文来介绍链表的概念和单链表的实现,在此之前,首先来回顾以下顺序表的特点: 1.顺序表特点回顾: 1. 顺序表是一组地址连续的存储单元依次存…...

9.2.1Socket(UDP)
一.传输层: 1.UDP:无连接,不可靠,面向数据报,全双工. 2.TCP:有连接,可靠,面向字节流,全双工. 注意:这里的可不可靠是相对的,并且和安不安全无关. 二.UDP数据报套接字编程: 1.socket文件:表示网卡的这类文件. 2.DatagramPacket:表示一个UDP数据报. 三.代码实现: 1.回显服务…...

9.1网络通信基础
一.基础概念: 1)IP地址:描述网络上的一个设备所在的位置. 2)端口号(port):区分一个主机上不同的进程,和pid一样的作用,但两者不同. 3)协议:网络通信传输数据的含义,协议表示一种约定,这种约定可以是任意的.协议分层之后,上层不需要知道下层协议的细节,可以灵活地调整,替换某…...

idea添加翻译插件并配置有道翻译
1、安装Translation插件 2、 创建有道云应用 有道智云控制台 3、设置idea 4、效果(选中文本右键翻译,默认快捷键CtrlShiftY)...

激光切割机的操作中蛙跳技术是什么意思
其实,蛙跳技术就是指在激光切割机运行的过程中,机器换位置的方式。打个比方,你刚刚在这儿把孔1切好了,接下来就得跑到那儿把孔2切了。 在这个过程中,激光切割机就像是一只青蛙,要从一个位置跳到另一个位置。…...

Typescript+React入门
初识Typescript 出现背景 Typescript(以下简称TS)实际上就是JavaScriptType,用数据类型的方式来约束了JS的变量定义 在JS的基础上增加了类型支持 在JS中大多数错误都是因为数据类型造成的,所以TS为了规避这个问题加入了类型限制…...

竞赛项目 酒店评价的情感倾向分析
前言 🔥 优质竞赛项目系列,今天要分享的是 酒店评价的情感倾向分析 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/post…...

加载并绘制时间域内的心电图信号,并实施Q因子为1的陷波滤波器以去除50 Hz频率研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

瑞数信息《2023 API安全趋势报告》重磅发布: API攻击持续走高,Bots武器更聪明
如今API作为连接服务和传输数据的重要通道,已成为数字时代的新型基础设施,但随之而来的安全问题也日益凸显。为了让各个行业更好地应对API安全威胁挑战,瑞数信息作为国内首批具备“云原生API安全能力”认证的专业厂商,近年来持续输…...
HCIA静态路由与动态路由
目录 一、静态路由 定义: 适用环境 二、动态路由 定义: 特点: 动态路由协议: 三、缺点: 1)静态路由缺点: 2)动态路由的缺点: 四、静态路由与动态路由的区别 静态路由: 动态路由: 一、静态路…...

【前端 | CSS】flex布局
基本概念 Flexible模型,通常被称为 flexbox,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力 我们说 flexbox 是一种一维的布局,是因为一个 flexbox 一次只能处理一个维度上的元素布局,一行或者…...
YoloV8优化:感受野注意力卷积运算(RFAConv),效果秒杀CBAM和CA等 | 即插即用系列
💡💡💡本文改进:感受野注意力卷积运算(RFAConv),解决卷积块注意力模块(CBAM)和协调注意力模块(CA)只关注空间特征,不能完全解决卷积核参数共享的问题 RFAConv| 亲测在多个数据集能够实现大幅涨点,有的数据集达到3个点以上 💡💡💡Yolov8魔术师,独家首…...

面对AI冲击,技术人才该如何考核?
一天下午,在与知名企业的技术交流会议室里,一位兄弟企业的CTO 小力苦笑着,分享了一个技术招聘的故事: “我们有个高级工程师,为了搞定MySQL三个表Join的问题,搞了一整天都研究不出来。结果他尝试将表结构扔…...

放弃51单片机,直接学习STM32开发可能会面临的问题
学习51单片机并非仅仅是为了学习51本身,而是通过它学习一种方法,即如何仅仅依靠Datasheet和例程来学习一种新的芯片。51单片机相对较简单,是这个过程中最容易上手的选择,而AVR单片机则更为复杂。虽然您已经学习了大约十天的51单片…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...