springboot 缓存@EnableCaching实例

目录
  • springboot 缓存@EnableCaching
  • Spring @EnableCaching的工作原理

springboot 缓存@EnableCaching

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

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

此处我们模拟要缓存的User

class User {
 private Long id;
 private String name;
// setter getter
}

然后我们业务对象:

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 ;
 }
}

然后我们编写启动类:

@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既处理调用前缓存操作,也处理调用返回时缓存操作

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring Boot设置并使用缓存的步骤

    几个缓存注解的作用: @Cacheable:将方法的返回结果根据key指定的键保存在缓存中,以后要获取相同的数据直接从缓存中共获取 cacheNames/value:指定Cache组件名称 key:指定缓存时使用的key,默认使用方法参数值,可以使用#a0.#p0.#参数名等,支持SpEL表达式,root可省略 keyGenerator:指定key的生成器的组件id,如自定义的KeyGenerator cacheManager:指定缓存管理器 cacheResolver:指定缓存解析器 cond

  • Spring Boot 中使用cache缓存的方法

    一.什么是缓存 Cache Cache 一词最早来自于CPU设计 当CPU要读取一个数据时,首先从CPU缓存中查找,找到就立即读取并送给CPU处理:没有找到,就从速率相对较慢的内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存.正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在CPU缓存中,只有大约10%需要从内存读取.这大大节省了CPU直接读取内存的

  • Spring Boot缓存实战 Caffeine示例

    Caffeine和Spring Boot集成 Caffeine是使用Java8对Guava缓存的重写版本,在Spring Boot 2.0中将取代Guava.如果出现Caffeine,CaffeineCacheManager将会自动配置.使用spring.cache.cache-names属性可以在启动时创建缓存,并可以通过以下配置进行自定义(按顺序): spring.cache.caffeine.spec: 定义的特殊缓存 com.github.benmanes.caffeine.cache.

  • 详解SpringBoot的三种缓存技术(Spring Cache、Layering Cache 框架、Alibaba JetCache 框架)

    引言 ​前两天在写一个实时数据处理的项目,项目要求是 1s 要处理掉 1k 的数据,这时候显然光靠查数据库是不行的,技术选型的时候老大跟我提了一下使用 Layering-Cache 这个开源项目来做缓存框架. ​之间问了一下身边的小伙伴,似乎对这块了解不多.一般也就用用 Redis 来缓存,应该是很少用多级缓存框架来专门性的管理缓存吧. ​趁着这个机会,我多了解了一些关于 SpringBoot 中缓存的相关技术,于是有了这篇文章! 在项目性能需求比较高时,就不能单单依赖数据库访问来获取数据了,必

  • 使用ehcache三步搞定springboot缓存的方法示例

    本次内容主要介绍基于Ehcache 3.0来快速实现Spring Boot应用程序的数据缓存功能.在Spring Boot应用程序中,我们可以通过Spring Caching来快速搞定数据缓存.接下来我们将介绍如何在三步之内搞定Spring Boot缓存. 1. 创建一个Spring Boot工程并添加Maven依赖 你所创建的Spring Boot应用程序的maven依赖文件至少应该是下面的样子: <?xml version="1.0" encoding="UTF-8

  • springboot 缓存@EnableCaching实例

    目录 springboot 缓存@EnableCaching Spring @EnableCaching的工作原理 springboot 缓存@EnableCaching 很多时候系统的瓶颈都在一些比较复杂的IO操作,例如读取数据库,如果一些比较稳定的数据,一般的解决方案就是用缓存.spring boot提供了比较简单的缓存方案.只要使用 @EnableCaching即可完成简单的缓存功能. 缓存的实现有多种实现,ConcurentHashMapCache , GuavaCache, EnCac

  • 详解SpringBoot缓存的实例代码(EhCache 2.x 篇)

    本篇介绍了SpringBoot 缓存(EhCache 2.x 篇),分享给大家,具体如下: SpringBoot 缓存 在 spring Boot中,通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManager),Spring Boot根据下面的顺序去侦测缓存提供者: Generic JCache (JSR-107) EhCache 2.x Hazelcast Infinispan Redis Guava Simple 关于 Spring Boot 的缓存机制: 高速

  • SpringBoot加入Guava Cache实现本地缓存代码实例

    这篇文章主要介绍了SpringBoot加入Guava Cache实现本地缓存代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在pom.xml中加入guava依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version>

  • springboot自带的缓存@EnableCaching用法

    目录 springboot自带的缓存@EnableCaching 1.@Cacheable添加缓存 2.@CacheEvict 清理缓存 使用springboot自带缓存步骤 1.在启动类XXXApplication 2.在service层需要使用缓存的方法 3.修改和删除数据时将缓存删除 springboot自带的缓存@EnableCaching 一般使用springboot自带缓存时,直接就在启动类里添加注解@EnableCaching . @EnableCaching她有两个经常使用的方法

  • SpringBoot缓存Ehcache的使用详解

    目录 为什么引入缓存 SpringBoot抽象缓存 代码实现 添加缓存依赖 开启缓存 数据缓存 @Cacheable @CachePut @CacheEvict 集成EhCache 添加EhCache依赖 添加Ehcache相关配置 注解含义: 测试 spring缓存(EhCache)是在Spring3.1开始引入的,但是其本身只提供了缓存接口,不提供具体缓存的实现,其实现需要第三方缓存实现(Generic.EhCache.Redis等).EhCache.Redis比较常用,使用Redis的时候

  • Springboot与vue实例讲解实现前后端分离的人事管理系统

    目录 一,项目简介 二,环境介绍 三,系统展示 四,核心代码展示 五,项目总结 一,项目简介 系统是前后端分离的项目,直接启动Springboot应用程序类后,再启动前端工程访问即可.主要实现了企业的人事管理功能,主要包含员工管理.薪资管理.职位管理.权限管理.网盘文件分享管理等模块. 系统亮点:使用REDIS进行数据缓存,优化查询性能:使用分布式文件系统进行文件存储服务:基于Springboot+vue实现前后端分离开发 二,环境介绍 语言环境:Java: jdk1.8 数据库:Mysql:

  • shiro缓存机实例代码

    Shiro提供了类似于Spring的Cache抽象,即Shiro本身不实现Cache,但是对Cache进行了又抽象,方便更换不同的底层Cache实现. Shiro提供的Cache接口: Java代码 public interface Cache<K, V> { //根据Key获取缓存中的值 public V get(K key) throws CacheException; //往缓存中放入key-value,返回缓存中之前的值 public V put(K key, V value) thr

  • Java实现LRU缓存的实例详解

    Java实现LRU缓存的实例详解 1.Cache Cache对于代码系统的加速与优化具有极大的作用,对于码农来说是一个很熟悉的概念.可以说,你在内存中new 了一个一段空间(比方说数组,list)存放一些冗余的结果数据,并利用这些数据完成了以空间换时间的优化目的,你就已经使用了cache. 有服务级的缓存框架,如memcache,Redis等.其实,很多时候,我们在自己同一个服务内,或者单个进程内也需要缓存,例如,lucene就对搜索做了缓存,而无须依赖外界.那么,我们如何实现我们自己的缓存?还

  • SpringBoot Tomcat启动实例代码详解

    废话不多了,具体内容如下所示: Application configuration class: @SpringBootApplication public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return appli

  • MyBatis 动态SQL和缓存机制实例详解

    有的时候需要根据要查询的参数动态的拼接SQL语句 常用标签: - if:字符判断 - choose[when...otherwise]:分支选择 - trim[where,set]:字符串截取,其中where标签封装查询条件,set标签封装修改条件 - foreach: if案例 1)在EmployeeMapper接口文件添加一个方法 public Student getStudent(Student student); 2)如果要写下列的SQL语句,只要是不为空,就作为查询条件,如下所示,这样

随机推荐