两个接口抽象 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 List getUser() {
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;
}
然后扩展CacheManager,没什么重写,就是自定义一种manager类型 为缓存指定新的CacheManager @Primary @Bean public CacheManager getExtensionCache() { return new CacheExtensionManage("users2"); } 完整代码 https://github.com/FS1360472174/javaweb/tree/master/web/src/main/java/com/fs/web/cache
java中最常用jar包的用途
jar包用途axis.jarSOAP引擎包commons-discovery-0.2.jar用来发现、查找和实现可插入式接口,提供一些一般类实例化、单件的生命周期管理的常用方法.jaxrpc.jarAxis运行所需要的组件包saaj.jar创建到端点的点到点连接的方法、创建并处理SOAP消息和附件的方法,以及接收和处理SOAP错误的方法. w
创建图表事件监听非常简单:首先是通过addEventListener('监听类型',js监听方法)添加事件监听,然后在js监听方法中定义具体监听逻辑。
以钻取操作为例,当用户点击图表某一个point的时候弹出point的name和value,代码如下:
<script>
//创建AnyChart
var chart = new AnyChart();
//添加钻取操作&quo
我们来看下面的例子:
create or replace view testview
as
select empno,ename from emp where ename like ‘M%’
with check option;
这里我们创建了一个视图,并使用了with check option来限制了视图。 然后我们来看一下视图包含的结果:
select * from testv