1. Hutool库基本介绍
1.1. 地址
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. 安装使用
xml
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
2.2. hutool-aop切片使用
2.2.1. 启动main函数
java
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接口
java
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子类
java
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. 切片操作类
java
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函数
java
public static void main(String[] args) {
bloomFilterSample.sampleDemo();
}
2.3.2. bloomFilterSample案例代码
java
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. 代码输出
java
-----------------------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函数
java
public static void main(String[] args) {
cacheSample.cacheDemo();
}
2.4.3. cacheSample案例代码
java
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函数
java
public static void main(String[] args) {
cronSample.cronDemo();
}
2.5.2. cronSample案例代码
java
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函数
java
public static void main(String[] args) {
dfaSample.dfaDemo();
}
2.8.3. dfaSample案例代码
java
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函数
java
public static void main(String[] args) {
scriptSample.scriptDemo();
}
2.12.2. scriptSample案例代码
java
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操作:
java
properties = new Properties();
try {
Class clazz = Demo1.class;
InputStream inputestream = clazz.getResourceAsStream("db.properties");
properties.load( inputestream);
}catch (IOException e) {
//ignore
}
而Props则大大简化为:
java
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信息
java
SystemUtil.getJvmSpecInfo();
2.14.1.3. Java Virtual Machine Implementation信息
java
SystemUtil.getJvmInfo();
2.14.1.4. Java Specification信息
java
SystemUtil.getJavaSpecInfo();
2.14.1.5. Java Implementation信息
java
SystemUtil.getJavaInfo();
2.14.1.6. Java运行时信息
java
SystemUtil.getJavaRuntimeInfo();
2.14.1.7. 系统信息
java
SystemUtil.getOsInfo();
2.14.1.8. 用户信息
java
SystemUtil.getUserInfo();
2.14.1.9. 当前主机网络地址信息
java
SystemUtil.getHostInfo();
2.14.1.10. 运行时信息,包括内存总大小、已用大小、可用大小等
java
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库:
xml
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>5.6.1</version>
</dependency>
然后可以调用相关API获取相关信息。
例如我们像获取内存总量:
java
long total = OshiUtil.getMemory().getTotal();
我们也可以获取CPU的一些信息:
java
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
==**案例代码另开博文整理