From c32d1c7ddc361599f33d9fdb4e7ea895e1fc1b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E8=9C=97=E7=89=9B?= <1003271829@qq.com> Date: Sat, 23 Dec 2023 11:34:12 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=93=E5=AD=98=E4=B9=8B=E7=8E=8B=EF=BC=81?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=9C=80=E4=BD=B3=E5=AE=9E=E8=B7=B5=EF=BC=81?= =?UTF-8?q?Guava=E8=87=AA=E5=8A=A0=E8=BD=BD=E7=BC=93=E5=AD=98LoadingCache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- guavaexception/guavaloadingcache/.gitignore | 33 ++++++++++ guavaexception/guavaloadingcache/README.md | 11 ++++ guavaexception/guavaloadingcache/pom.xml | 65 +++++++++++++++++++ .../demo/DemoRequestScopeApplication.java | 16 +++++ .../demo/component/AutoRefreshCache.java | 33 ++++++++++ .../demo/component/CacheMonitoring.java | 27 ++++++++ .../demo/component/LoadingCacheExample.java | 20 ++++++ .../com/example/demo/component/UserCache.java | 28 ++++++++ .../example/demo/component/ZuiJiaShiJian.java | 45 +++++++++++++ .../java/com/example/demo/entity/User.java | 10 +++ .../com/example/demo/service/UserService.java | 9 +++ .../src/main/resources/application.properties | 3 + 12 files changed, 300 insertions(+) create mode 100644 guavaexception/guavaloadingcache/.gitignore create mode 100644 guavaexception/guavaloadingcache/README.md create mode 100644 guavaexception/guavaloadingcache/pom.xml create mode 100644 guavaexception/guavaloadingcache/src/main/java/com/example/demo/DemoRequestScopeApplication.java create mode 100644 guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/AutoRefreshCache.java create mode 100644 guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/CacheMonitoring.java create mode 100644 guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/LoadingCacheExample.java create mode 100644 guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/UserCache.java create mode 100644 guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/ZuiJiaShiJian.java create mode 100644 guavaexception/guavaloadingcache/src/main/java/com/example/demo/entity/User.java create mode 100644 guavaexception/guavaloadingcache/src/main/java/com/example/demo/service/UserService.java create mode 100644 guavaexception/guavaloadingcache/src/main/resources/application.properties diff --git a/guavaexception/guavaloadingcache/.gitignore b/guavaexception/guavaloadingcache/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/guavaexception/guavaloadingcache/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/guavaexception/guavaloadingcache/README.md b/guavaexception/guavaloadingcache/README.md new file mode 100644 index 0000000..c912aec --- /dev/null +++ b/guavaexception/guavaloadingcache/README.md @@ -0,0 +1,11 @@ +# demo-request-scope + +《基于ThreadLocal实现一个上下文管理组件》技术博客对应源码 + +https://juejin.cn/post/7153287656624324638 + +本文基于`ThreadLocal`原理,实现了一个上下文状态管理组件`Scope`,通过开启一个自定义的`Scope`,在`Scope`范围内,可以通过`Scope`各个方法读写数据; + +通过自定义线程池实现上下文状态数据的线程间传递; + +提出了一种基于`Filter`和`Scope`的`Request`粒度的上下文管理方案。 diff --git a/guavaexception/guavaloadingcache/pom.xml b/guavaexception/guavaloadingcache/pom.xml new file mode 100644 index 0000000..9f67f92 --- /dev/null +++ b/guavaexception/guavaloadingcache/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.4 + + + com.example + demo-request-scope + 0.0.1-SNAPSHOT + demo-request-scope + Demo project for Spring Boot + + 8 + + + + + + + com.google.guava + guava + 30.1-jre + + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.projectlombok + lombok + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/guavaexception/guavaloadingcache/src/main/java/com/example/demo/DemoRequestScopeApplication.java b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/DemoRequestScopeApplication.java new file mode 100644 index 0000000..b11e739 --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/DemoRequestScopeApplication.java @@ -0,0 +1,16 @@ +package com.example.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Guava自加载缓存LoadingCache + */ +@SpringBootApplication +public class DemoRequestScopeApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoRequestScopeApplication.class, args); + } + +} diff --git a/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/AutoRefreshCache.java b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/AutoRefreshCache.java new file mode 100644 index 0000000..e7f97ef --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/AutoRefreshCache.java @@ -0,0 +1,33 @@ +package com.example.demo.component; + + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +import java.util.concurrent.TimeUnit; + +public class AutoRefreshCache { + public static void main(String[] args) throws Exception { + LoadingCache cache = CacheBuilder + .newBuilder() + .refreshAfterWrite(5, TimeUnit.SECONDS) // 设置5s后刷新 更新缓存 + .build(new CacheLoader() { + @Override + public String load(String key) { + return fetchDataFromDatabase(key); // 模拟从数据库加载数据 + } + }); + // 使用缓存 + System.out.println(cache.get("key1")); // 第一次加载 + // 5s钟后,尝试再次获取,将触发刷新操作 + TimeUnit.SECONDS.sleep(5); + System.out.println(cache.get("key1")); // 第二次加载 + + } + + private static String fetchDataFromDatabase(String key) { + // 模拟数据库操作 + return "Data for " + key; + } +} diff --git a/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/CacheMonitoring.java b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/CacheMonitoring.java new file mode 100644 index 0000000..893586c --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/CacheMonitoring.java @@ -0,0 +1,27 @@ +package com.example.demo.component; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.cache.RemovalListener; + +public class CacheMonitoring { + public static void main(String[] args) throws Exception { + RemovalListener removalListener = notification -> { + System.out.println("Removed: " + notification.getKey() + ", Cause: " + notification.getCause()); + }; + LoadingCache cache = CacheBuilder + .newBuilder() + .maximumSize(100) + .removalListener(removalListener) + .build(new CacheLoader() { + @Override + public String load(String key) throws Exception { + return key; + } + }); + String value = cache.get("key"); + System.out.println(value); + cache.cleanUp(); + } +} diff --git a/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/LoadingCacheExample.java b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/LoadingCacheExample.java new file mode 100644 index 0000000..3c0c680 --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/LoadingCacheExample.java @@ -0,0 +1,20 @@ +package com.example.demo.component; + + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +public class LoadingCacheExample { + public static void main(String[] args) { + LoadingCache cache = CacheBuilder.newBuilder() + .maximumSize(100) // 最大缓存项数 + .build(new CacheLoader() { + @Override + public String load(String key) throws Exception { + return "Hello, " + key; // 定义缓存加载的方式 + } + }); + System.out.println(cache.getUnchecked("Guava")); // 输出:Hello, Guava + } +} diff --git a/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/UserCache.java b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/UserCache.java new file mode 100644 index 0000000..05e09af --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/UserCache.java @@ -0,0 +1,28 @@ +package com.example.demo.component; + + +import com.example.demo.entity.User; +import com.example.demo.service.UserService; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +public class UserCache { + // 假设有一个用户服务,用于获取用户信息 + private static UserService userService = new UserService(); + public static void main(String[] args) throws Exception { + CacheLoader loader = new CacheLoader() { + @Override + public User load(String userId) throws Exception { + return userService.getUserById(userId); + } + }; + // 创建LoadingCache + LoadingCache cache = CacheBuilder.newBuilder() + .maximumSize(100) // 设置最大缓存数 + .build(loader); + // 使用缓存获取用户信息 + User user = cache.get("123"); // 如果缓存中没有,会调用load方法加载数据 + System.out.println(user); + } +} diff --git a/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/ZuiJiaShiJian.java b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/ZuiJiaShiJian.java new file mode 100644 index 0000000..86b8249 --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/component/ZuiJiaShiJian.java @@ -0,0 +1,45 @@ +package com.example.demo.component; + + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +import java.util.concurrent.TimeUnit; + +/** + * 缓存使用最佳实践 + */ +public class ZuiJiaShiJian { + + public static void main(String[] args) { + LoadingCache cache = CacheBuilder.newBuilder() + .maximumSize(1000) // 设置最大缓存项为1000 合理配置缓存大小 + .expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期 设置合适的过期策略 + .expireAfterAccess(5, TimeUnit.MINUTES) // 访问后5分钟过期 设置合适的过期策略 + .softValues() // 使用软引用存储值 + .weakKeys() // 使用弱引用存储键 + .removalListener(notification -> { + // 监听移除通知 + System.out.println("Removed: " + notification.getKey() + ", Cause: " + notification.getCause()); + }) + .build(new CacheLoader() { + @Override + public String load(String key) throws Exception { + try { + // 异常处理策略 + return fetchData(key); + } catch (Exception e) { + // 处理异常 + return null; + } + } + private String fetchData(String key) { + throw new RuntimeException(); + } + }); + + + + } +} diff --git a/guavaexception/guavaloadingcache/src/main/java/com/example/demo/entity/User.java b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/entity/User.java new file mode 100644 index 0000000..d8db4b0 --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/entity/User.java @@ -0,0 +1,10 @@ +package com.example.demo.entity; + +import lombok.Data; + +@Data +public class User { + + private String name; + private int age; +} diff --git a/guavaexception/guavaloadingcache/src/main/java/com/example/demo/service/UserService.java b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/service/UserService.java new file mode 100644 index 0000000..c909fd0 --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/java/com/example/demo/service/UserService.java @@ -0,0 +1,9 @@ +package com.example.demo.service; + +import com.example.demo.entity.User; + +public class UserService { + public User getUserById(String userId) { + return new User(); + } +} diff --git a/guavaexception/guavaloadingcache/src/main/resources/application.properties b/guavaexception/guavaloadingcache/src/main/resources/application.properties new file mode 100644 index 0000000..1b0e4b6 --- /dev/null +++ b/guavaexception/guavaloadingcache/src/main/resources/application.properties @@ -0,0 +1,3 @@ + +spring.redis.host=192.168.56.10 +spring.redis.password=123456 \ No newline at end of file