两个接口抽象 Cache,CacheManager,具体的实现都是基于这两个抽象实现。 典型的SPI机制,和eat your dog food。当需要提供接口给外部调用,首先自己内部的实现也必须基于同样一套抽象机制
The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache and org.springframework.cache.CacheManager interfaces.
Spring Cache提供了这些缓存的实现,如果没有一种CacheManage,或者CacheResolver,会按照指定的顺序去实现
If you have not defined a bean of type CacheManager or a CacheResolver named cacheResolver (see CachingConfigurer), Spring Boot tries to detect the following providers (in the indicated order): 1.Generic 2.JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others) 3.EhCache 2.x 4.Hazelcast 5.Infinispan 6.Couchbase 7.Redis 8.Caffeine 9.Simple
step2 run demo
对Spring Cache有了一个大概的了解后,我们首先使用起来,跑个demo。
定义一个用户查询方法
@Component
public class CacheSample {
@Cacheable(cacheNames = "users")
public Map getUser(final Collection userIds) {
System.out.println("not cache");
final Map mapUser = new HashMap<>();
userIds.forEach(userId -> {
mapUser.put(userId, User.builder().userId(userId).name("name").build());
});
return mapUser;
}
复制代码
配置一个CacheManager
@Configuration
public class CacheConfig {
@Primary
@Bean(name = { "cacheManager" })
public CacheManager getCache() {
return new ConcurrentMapCacheManager("users");
}
复制代码
API调用
@RestController
@RequestMapping("/api/cache")
public class CacheController {
@Autowired
private CacheSample cacheSample;
@GetMapping("/user/v1/1")
public ListgetUser() {
return cacheSample.getUser(Arrays.asList(1L,2L)).values().stream().collect(Collectors.toList());
}
}
复制代码
// Check if we have a cached item matching the conditions
Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
// Collect puts from any @Cacheable miss, if no cached item is found
List cachePutRequests = new LinkedList<>();
if (cacheHit == null) {
collectPutRequests(contexts.get(CacheableOperation.class),
CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
}
复制代码
public static Object lookup(final CacheExtension cache, final Object key) {
if (key instanceof Collection) {
final Collection originalKeys = ((Collection) key);
if (originalKeys == null || originalKeys.isEmpty()) {
return CacheResult.builder().cache(cache).miss(
Collections.emptySet())
.build();
}
final List keys = originalKeys.stream()
.filter(Objects::nonNull).collect(Collectors.toList());
final Map hits = cache.getAll(keys);
final Set miss = new HashSet(keys);
miss.removeAll(hits.keySet());
return CacheResult.builder().cache(cache).hit(hits).miss(miss).build();
}
return null;
}
复制代码
CacheResult就是新的缓存结果格式
@Builder
@Setter
@Getter
static class CacheResult {
final CacheExtension cache;
// 命中的缓存结果
final Map hit;
// 需要重新调用源方法的keys
private Set miss;
}
复制代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml&q
1. 安装memcached server
a. 下载memcached-1.2.6-win32-bin.zip
b. 解压缩,dos 窗口切换到 memcached.exe所在目录,运行memcached.exe -d install
c.启动memcached Server,直接在dos窗口键入 net start "memcached Server&quo
Log4j组件:Logger、Appender、Layout
Log4j核心包含三个组件:logger、appender和layout。这三个组件协作提供日志功能:
日志的输出目标
日志的输出格式
日志的输出级别(是否抑制日志的输出)
logger继承特性
A logger is said to be an ancestor of anothe
public static void main(String[] args) throws IOException {
//输入流
InputStream in = Test.class.getResourceAsStream("/test");
InputStreamReader isr = new InputStreamReader(in);
Bu
对于那些具有强迫症的工程师来说,软件汉化固然好用,但是汉化不完整却极为头疼,本方法针对iReport汉化不完整的情况,强制使用英文版,方法如下:
在 iReport 安装路径下的 etc/ireport.conf 里增加红色部分启动参数,即可变为英文版。
# ${HOME} will be replaced by user home directory accordin
网上找了很久,都是用Gallery实现的,效果不是很满意,结果发现这个用OpenGL实现的,稍微修改了一下源码,实现了无限循环功能
源码地址:
https://github.com/jackfengji/glcoverflow
public class CoverFlowOpenGL extends GLSurfaceView implements
GLSurfaceV