服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - springboot 缓存@EnableCaching实例

springboot 缓存@EnableCaching实例

2022-07-06 10:25micro_hz Java教程

这篇文章主要介绍了springboot 缓存@EnableCaching实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

springboot 缓存@EnableCaching

很多时候系统的瓶颈都在一些比较复杂的IO操作,例如读取数据库,如果一些比较稳定的数据,一般的解决方案就是用缓存。spring boot提供了比较简单的缓存方案。只要使用 @EnableCaching即可完成简单的缓存功能。

缓存的实现有多种实现,ConcurentHashMapCache , GuavaCache, EnCacheCache等多种实现,spring boot 有默认的实现。本文不深入源码解读,首先用起来。

此处我们模拟要缓存的User

?
1
2
3
4
5
class User {
 private Long id;
 private String name;
// setter getter
}

然后我们业务对象:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import javax.annotation.PostConstruct;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Component;
/**
 * @author micro
 * @date 2017年8月2日
 * @description :
 */
@Component
@EnableCaching
public class UserDao {
 private Map<Long, User> userMap;
 @PostConstruct
 public void init() {
  //模拟数据库
  userMap = new HashMap<Long, User>();
  userMap.put(1L, new User(1L,"micro1"));
  userMap.put(2L, new User(2L, "micro2"));
 }
 
 @Cacheable("user"// 注解key属性可以执行缓存对象user(可以理解为一个map)的key
 public User getUser(Long userId) {
  System.out.println("查询数据库:userId ->" + userId);
  return userMap.get(userId);
 }
 
 @Cacheable(value = "nameCache", key = "#name")
 public User getUserByName(Long userId, String name) {
  System.out.println("查询数据库:userId ->" + userId);
  return userMap.get(userId);
 }
 
 @Cacheable("nameCache")
 public User getUserByName(String name) {
  System.out.println("查询数据库:userName : " + name);
  for (Long k : userMap.keySet()) {
   if (userMap.get(k).equals(name)) {
    return userMap.get(k);
   }
  }
  return null;
 }
 
 @CachePut("user") // 与Cacheable区别就是Cacheable先看缓存如果有,直接缓存换回,CachePut则是每次都会调用并且把返回值放到缓存
 public User getUser2(Long userId) {
  System.out.println("查询数据库:userId : " + userId);
  return userMap.get(userId);
 }
 
 @CacheEvict("user")
 public void removeFromCache(Long userId) {
  return ;
 }
}

然后我们编写启动类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@SpringBootApplication
public class CacheTest implements CommandLineRunner {
 @Autowired
 private UserDao userDao;
 public static void main(String[] args) {
  new SpringApplication(CacheTest.class).run(args);
 }
 @Override
 public void run(String... args) throws Exception {
  System.out.println("第一次查询");
  System.out.println(userDao.getUser(1L));
  System.out.println("第二次查询");
  System.out.println(userDao.getUser(1L));
  userDao.removeFromCache(1L);// 移除缓存
  System.out.println("第三次查询");
  userDao.getUser(1L);// 没有缓存了 
  System.out.println("--------");
  // 测试不同的key缓存
  userDao.getUserByName("micro1");
  userDao.getUserByName(1L, "micro1");// 指定了参数name 为key 此次读取缓存
 }
}

打印结果:

第一次查询
查询数据库:userId ->1
User@65da01f4
第二次查询
User@65da01f4
第三次查询
查询数据库:userId ->1
--------
查询数据库:userName : micro1

Spring @EnableCaching的工作原理

1、开发人员使用注解@EnableCaching

2、注解@EnableCaching导入CachingConfigurationSelector

3、CachingConfigurationSelector根据注解@EnableCaching 属性AdviceMode mode决定引入哪些配置类

  • PROXY : AutoProxyRegistrar,ProxyCachingConfiguration;
  • ASPECTJ : AspectJCachingConfiguration;

本文以mode=PROXY为例;

4、CachingConfigurationSelector导入AutoProxyRegistrar会确保容器中存在一个自动代理创建器(APC);

  • 用于确保目标bean需要被代理时有可用的代理创建器

5、ProxyCachingConfiguration向容器定义如下基础设施bean

  • 名称为org.springframework.cache.config.internalCacheAdvisor类型为BeanFactoryCacheOperationSourceAdvisor的bean
  • 名称为cacheOperationSource类型为CacheOperationSource的bean

用于获取方法调用时最终应用的Spring Cache注解的元数据

  • 名称为cacheInterceptor类型为CacheInterceptor的bean

一个MethodInterceptor,包裹在目标bean外面用于操作Cache的AOP Advice。

6、AutoProxyRegistrar在容器启动阶段对每个bean创建进行处理,如果该bean中有方法应用了Spring Cache注解,为其创建相应的代理对象,包裹上面定义的BeanFactoryCacheOperationSourceAdvisor bean;

7、使用了Spring Cache注解的bean方法被调用,其实调用首先发生在代理对象上,先到达cacheInterceptor,然后才是目标bean方法的调用;

  • cacheInterceptor既处理调用前缓存操作,也处理调用返回时缓存操作

以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/micro_hz/article/details/76599632

延伸 · 阅读

精彩推荐
  • Java教程java SpringMVC学习使用详解

    java SpringMVC学习使用详解

    本篇文章主要介绍了java SpringMVC——如何获取请求参数详解,详细的介绍了每种参数注解的用法及其实例。感兴趣的小伙伴们可以参考一下...

    wbb1662020-09-12
  • Java教程JavaTCP上传文本文件代码

    JavaTCP上传文本文件代码

    今天小编就为大家分享一篇关于JavaTCP上传文本文件代码,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    凌晨两点半的太阳7622021-07-14
  • Java教程dom4j读取XML文件详解

    dom4j读取XML文件详解

    这篇文章主要为大家详细介绍了dom4j读取XML文件的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    刘水镜11622021-02-20
  • Java教程java读取ftp中TXT文件的案例

    java读取ftp中TXT文件的案例

    这篇文章主要介绍了java读取ftp中TXT文件的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    zhang061055867312020-09-24
  • Java教程详解Spring3.x 升级至 Spring4.x的方法

    详解Spring3.x 升级至 Spring4.x的方法

    本篇文章主要介绍了详解Spring3.x 升级至 Spring4.x的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    deniro4322021-04-22
  • Java教程一篇文章带你了解JAVA面对对象应用

    一篇文章带你了解JAVA面对对象应用

    Java是一门面向对象的语言。对象是Java程序中的基本实体。除了对象之外Java程序同样处理基本数据。下面这篇文章主要给大家总结了关于Java中面向对象的知...

    铅华殿5352021-11-03
  • Java教程浅谈关于Java的GC垃圾回收器的一些基本概念

    浅谈关于Java的GC垃圾回收器的一些基本概念

    这篇文章主要介绍了关于Java的GC垃圾回收器的一些基本概念,牵扯倒JVM内存模型的一些知识,需要的朋友可以参考下 ...

    王小明1231992020-03-01
  • Java教程初识Java8中的Stream

    初识Java8中的Stream

    lambda表达式是stream的基础,接下来通过实例代码给大家详细介绍java8中的stream,感兴趣的朋友一起看看吧...

    【兰陵笑笑生】4462020-12-20