程序员蜗牛
1 year ago
12 changed files with 300 additions and 0 deletions
@ -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/ |
@ -0,0 +1,11 @@ |
|||
# demo-request-scope |
|||
|
|||
《基于ThreadLocal实现一个上下文管理组件》技术博客对应源码 |
|||
|
|||
https://juejin.cn/post/7153287656624324638 |
|||
|
|||
本文基于`ThreadLocal`原理,实现了一个上下文状态管理组件`Scope`,通过开启一个自定义的`Scope`,在`Scope`范围内,可以通过`Scope`各个方法读写数据; |
|||
|
|||
通过自定义线程池实现上下文状态数据的线程间传递; |
|||
|
|||
提出了一种基于`Filter`和`Scope`的`Request`粒度的上下文管理方案。 |
@ -0,0 +1,65 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<parent> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-parent</artifactId> |
|||
<version>2.7.4</version> |
|||
<relativePath/> <!-- lookup parent from repository --> |
|||
</parent> |
|||
<groupId>com.example</groupId> |
|||
<artifactId>demo-request-scope</artifactId> |
|||
<version>0.0.1-SNAPSHOT</version> |
|||
<name>demo-request-scope</name> |
|||
<description>Demo project for Spring Boot</description> |
|||
<properties> |
|||
<java.version>8</java.version> |
|||
</properties> |
|||
|
|||
|
|||
<dependencies> |
|||
|
|||
<dependency> |
|||
<groupId>com.google.guava</groupId> |
|||
<artifactId>guava</artifactId> |
|||
<version>30.1-jre</version> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-aop</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-data-redis</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-web</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-starter-test</artifactId> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.projectlombok</groupId> |
|||
<artifactId>lombok</artifactId> |
|||
<optional>true</optional> |
|||
</dependency> |
|||
</dependencies> |
|||
|
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.springframework.boot</groupId> |
|||
<artifactId>spring-boot-maven-plugin</artifactId> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
|
|||
</project> |
@ -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); |
|||
} |
|||
|
|||
} |
@ -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<String, String> cache = CacheBuilder |
|||
.newBuilder() |
|||
.refreshAfterWrite(5, TimeUnit.SECONDS) // 设置5s后刷新 更新缓存
|
|||
.build(new CacheLoader<String, String>() { |
|||
@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; |
|||
} |
|||
} |
@ -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<String, String> removalListener = notification -> { |
|||
System.out.println("Removed: " + notification.getKey() + ", Cause: " + notification.getCause()); |
|||
}; |
|||
LoadingCache<String, String> cache = CacheBuilder |
|||
.newBuilder() |
|||
.maximumSize(100) |
|||
.removalListener(removalListener) |
|||
.build(new CacheLoader<String, String>() { |
|||
@Override |
|||
public String load(String key) throws Exception { |
|||
return key; |
|||
} |
|||
}); |
|||
String value = cache.get("key"); |
|||
System.out.println(value); |
|||
cache.cleanUp(); |
|||
} |
|||
} |
@ -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<String, String> cache = CacheBuilder.newBuilder() |
|||
.maximumSize(100) // 最大缓存项数
|
|||
.build(new CacheLoader<String, String>() { |
|||
@Override |
|||
public String load(String key) throws Exception { |
|||
return "Hello, " + key; // 定义缓存加载的方式
|
|||
} |
|||
}); |
|||
System.out.println(cache.getUnchecked("Guava")); // 输出:Hello, Guava
|
|||
} |
|||
} |
@ -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<String, User> loader = new CacheLoader<String, User>() { |
|||
@Override |
|||
public User load(String userId) throws Exception { |
|||
return userService.getUserById(userId); |
|||
} |
|||
}; |
|||
// 创建LoadingCache
|
|||
LoadingCache<String, User> cache = CacheBuilder.newBuilder() |
|||
.maximumSize(100) // 设置最大缓存数
|
|||
.build(loader); |
|||
// 使用缓存获取用户信息
|
|||
User user = cache.get("123"); // 如果缓存中没有,会调用load方法加载数据
|
|||
System.out.println(user); |
|||
} |
|||
} |
@ -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<String, String> 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<String, String>() { |
|||
@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(); |
|||
} |
|||
}); |
|||
|
|||
|
|||
|
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
package com.example.demo.entity; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class User { |
|||
|
|||
private String name; |
|||
private int age; |
|||
} |
@ -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(); |
|||
} |
|||
} |
@ -0,0 +1,3 @@ |
|||
|
|||
spring.redis.host=192.168.56.10 |
|||
spring.redis.password=123456 |
Loading…
Reference in new issue