缓存是大多数应用程序的主要组成部分,只要我们设法避免磁盘访问,缓存就会保持强劲。 Spring对各种配置的缓存提供了强大的支持 。 您可以根据需要简单地开始,然后进行更多可定制的操作。

这将是spring提供的最简单的缓存形式的示例。
Spring默认带有一个内存缓存,它很容易设置。

让我们从gradle文件开始。

group 'com.gkatzioura'
version '1.0-SNAPSHOT'buildscript {repositories {mavenCentral()}dependencies {classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.2.RELEASE")}
}apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'repositories {mavenCentral()
}sourceCompatibility = 1.8
targetCompatibility = 1.8dependencies {compile("org.springframework.boot:spring-boot-starter-web")compile("org.springframework.boot:spring-boot-starter-cache")compile("org.springframework.boot:spring-boot-starter")testCompile("junit:junit")
}bootRun {systemProperty "spring.profiles.active", "simple-cache"
}

由于同一项目将用于不同的缓存提供程序,因此会有多个spring配置文件。 本教程的Spring配置文件将是简单缓存,因为我们将使用基于ConcurrentMap的缓存,该缓存恰好是默认缓存。

我们将实现一个应用程序,该应用程序将从本地文件系统中获取用户信息。 该信息应位于users.json文件中

[{"userName":"user1","firstName":"User1","lastName":"First"},{"userName":"user2","firstName":"User2","lastName":"Second"},{"userName":"user3","firstName":"User3","lastName":"Third"},{"userName":"user4","firstName":"User4","lastName":"Fourth"}
]

我们还将为要检索的数据指定一个简单的模型。

package com.gkatzioura.caching.model;/*** Created by gkatzioura on 1/5/17.*/
public class UserPayload {private String userName;private String firstName;private String lastName;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}
}

然后,我们将添加一个将读取信息的bean。

package com.gkatzioura.caching.config;import com.fasterxml.jackson.databind.ObjectMapper;
import com.gkatzioura.caching.model.UserPayload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.Resource;import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;/*** Created by gkatzioura on 1/5/17.*/
@Configuration
@Profile("simple-cache")
public class SimpleDataConfig {@Autowiredprivate ObjectMapper objectMapper;@Value("classpath:/users.json")private Resource usersJsonResource;@Beanpublic List<UserPayload> payloadUsers() throws IOException {try(InputStream inputStream = usersJsonResource.getInputStream()) {UserPayload[] payloadUsers = objectMapper.readValue(inputStream,UserPayload[].class);return Collections.unmodifiableList(Arrays.asList(payloadUsers));}}
}

显然,为了访问信息,我们将使用实例化的Bean包含所有用户信息。

下一步将是创建一个存储库接口,以指定将使用的方法。

package com.gkatzioura.caching.repository;import com.gkatzioura.caching.model.UserPayload;import java.util.List;/*** Created by gkatzioura on 1/6/17.*/
public interface UserRepository {List<UserPayload> fetchAllUsers();UserPayload firstUser();UserPayload userByFirstNameAndLastName(String firstName,String lastName);}

现在,让我们深入研究将包含所需缓存注释的实现。

package com.gkatzioura.caching.repository;import com.gkatzioura.caching.model.UserPayload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Repository;import java.util.List;
import java.util.Optional;/*** Created by gkatzioura on 12/30/16.*/
@Repository
@Profile("simple-cache")
public class UserRepositoryLocal implements UserRepository {@Autowiredprivate List<UserPayload> payloadUsers;private static final Logger LOGGER = LoggerFactory.getLogger(UserRepositoryLocal.class);@Override@Cacheable("alluserscache")public List<UserPayload> fetchAllUsers() {LOGGER.info("Fetching all users");return payloadUsers;}@Override@Cacheable(cacheNames = "usercache",key = "#root.methodName")public UserPayload firstUser() {LOGGER.info("fetching firstUser");return payloadUsers.get(0);}@Override@Cacheable(cacheNames = "usercache",key = "{#firstName,#lastName}")public UserPayload userByFirstNameAndLastName(String firstName,String lastName) {LOGGER.info("fetching user by firstname and lastname");Optional<UserPayload> user = payloadUsers.stream().filter(p-> p.getFirstName().equals(firstName)&&p.getLastName().equals(lastName)).findFirst();if(user.isPresent()) {return user.get();} else {return null;}}}

包含@Cacheable的方法将触发缓存填充,这与包含@CacheEvict的方法将触发缓存逐出相反。 通过使用@Cacheable而不是仅指定将存储我们的值的缓存映射,我们还可以基于方法名称或方法参数来指定键。

因此,我们实现了方法缓存。 例如,方法firstUser使用方法名称作为键,而方法userByFirstNameAndLastName使用方法参数以创建键。

带有@CacheEvict批注的两种方法将清空指定的缓存。

LocalCacheEvict将是处理驱逐的组件。

package com.gkatzioura.caching.repository;import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;/*** Created by gkatzioura on 1/7/17.*/
@Component
@Profile("simple-cache")
public class LocalCacheEvict {@CacheEvict(cacheNames = "alluserscache",allEntries = true)public void evictAllUsersCache() {}@CacheEvict(cacheNames = "usercache",allEntries = true)public void evictUserCache() {}}

由于我们使用非常简单的缓存形式,因此不支持驱逐ttl。 因此,我们将仅针对此特定情况添加一个调度程序,该调度程序将在一定时间后退出缓存。

package com.gkatzioura.caching.scheduler;import com.gkatzioura.caching.repository.LocalCacheEvict;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;/*** Created by gkatzioura on 1/7/17.*/
@Component
@Profile("simple-cache")
public class EvictScheduler {@Autowiredprivate LocalCacheEvict localCacheEvict;private static final Logger LOGGER = LoggerFactory.getLogger(EvictScheduler.class);@Scheduled(fixedDelay=10000)public void clearCaches() {LOGGER.info("Invalidating caches");localCacheEvict.evictUserCache();localCacheEvict.evictAllUsersCache();}}

最后,我们将使用控制器来调用指定的方法

package com.gkatzioura.caching.controller;import com.gkatzioura.caching.model.UserPayload;
import com.gkatzioura.caching.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** Created by gkatzioura on 12/30/16.*/
@RestController
public class UsersController {@Autowiredprivate UserRepository userRepository;@RequestMapping(path = "/users/all",method = RequestMethod.GET)public List<UserPayload> fetchUsers() {return userRepository.fetchAllUsers();}@RequestMapping(path = "/users/first",method = RequestMethod.GET)public UserPayload fetchFirst() {return userRepository.firstUser();}@RequestMapping(path = "/users/",method = RequestMethod.GET)public UserPayload findByFirstNameLastName(String firstName,String lastName ) {return userRepository.userByFirstNameAndLastName(firstName,lastName);}}

最后但并非最不重要的一点是,我们的Application类应包含两个额外的注释。 为了启用调度程序,需要@EnableScheduling;为了启用缓存,需要@EnableCaching

package com.gkatzioura.caching;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling;/*** Created by gkatzioura on 12/30/16.*/
@SpringBootApplication
@EnableScheduling
@EnableCaching
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class,args);}}

您可以在github上找到源代码。

翻译自: https://www.javacodegeeks.com/2017/01/spring-boot-cache-abstraction.html

Spring启动和缓存抽象相关推荐

  1. Spring 3.1缓存抽象教程

    即将发布的Spring 3.1版本中引入的新功能之一是缓存抽象之一 . Spring Framework提供了对将缓存透明添加到现有Spring应用程序中的支持. 与事务支持类似,缓存抽象允许一致使用 ...

  2. Spring指南之使用Spring缓存数据(Spring Framework官方文档之缓存抽象详解)

    1.请参见官方文档Spring指南之使用 Spring 缓存数据 2.请参见Spring官方文档之缓存抽象 3.参见github代码 文章目录 一.简介 二.你将创造什么(What You Will ...

  3. 简单的Spring Memcached – Spring缓存抽象和Memcached

    在任何读取繁重的数据库应用程序中,缓存仍然是最基本的性能增强机制之一. Spring 3.1发行版提供了一个很酷的新功能,称为Cache Abstraction . Spring Cache Abst ...

  4. (转)使用 Spring缓存抽象 支持 EhCache 和 Redis 混合部署

    背景:最近项目组在开发本地缓存,其中用到了redis和ehcache,但是在使用注解过程中发现两者会出现冲突,这里给出解决两者冲突的具体方案. spring-ehcache.xml配置: <?x ...

  5. Spring Boot————默认缓存应用及原理

    引言 应用程序的数据除了可以放在配置文件中.数据库中以外,还会有相当一部分存储在计算机的内存中,这部分数据访问速度要快于数据库的访问,因此通常在做提升数据访问速度时,会将需要提升访问速度的数据放入到内 ...

  6. 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)

    Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...

  7. 基于Spring的Web缓存

    缓存的基本思想其实是以空间换时间.我们知道,IO的读写速度相对内存来说是非常比较慢的,通常一个web应用的瓶颈就出现在磁盘IO的读写上.那么,如果我们在内存中建立一个存储区,将数据缓存起来,当浏览器端 ...

  8. kafka 启动_「首席看Event Hub」如何在您的Spring启动应用程序中使用Kafka

    在体系结构规划期间选择正确的消息传递系统始终是一个挑战,但这是需要确定的最重要的考虑因素之一.作为一名开发人员,我每天都要编写需要服务大量用户并实时处理大量数据的应用程序. 通常,我将Java与Spr ...

  9. spring 启动加载数据_12个很棒的Spring数据教程来启动您的数据项目

    spring 启动加载数据 Spring Data的任务是为数据访问提供一个熟悉且一致的,基于Spring的编程模型,同时仍保留基础数据存储的特​​殊特征. 它使使用数据访问技术,关系和非关系数据库, ...

最新文章

  1. 【Paper】2021_Observer-Based Controllers for Incrementally Quadratic Nonlinear Systems With Disturbanc
  2. 11.3 free:查看系统内存信息
  3. poj 2201 构造
  4. 颜宁的学生都已经副院长了!还发表了学校首篇Nature
  5. 真首发!雷军预热小米12:第一时间把最新最酷的科技带给用户
  6. 《Solution-Centric Organization》解决方案导向型组织 节选 IV
  7. #VSTS日志# Xamarin构建支持和一大波更新
  8. ECMAScript 学习笔记01
  9. linux网络子系统分析
  10. Java 删除文件夹以及文件夹下的文件
  11. 【应急响应】Linux应急响应入侵排查思路
  12. 全网最详细的ensp模拟器安装教程
  13. 视频教程-Visio应用视频教程(下)-Office/WPS
  14. Java Web前后端分离架构
  15. MemoryBarrier
  16. Ceres 曲线拟合
  17. 面试 http://mp.weixin.qq.com/s/p5mXVzixSDZZ6o9DpU5Xaw
  18. win gvim erlang 环境配置
  19. java编写数独计算器
  20. OpenCV图像处理_2:平滑smoothing模糊blurring操作

热门文章

  1. 零配置 之 Spring注解实现Bean定义
  2. JDK8新特性之Optional
  3. 《金色梦乡》金句摘抄(六)
  4. Ajax基本案例详解之$.get的实现
  5. 2020蓝桥杯省赛---java---B---6(成绩分析)
  6. mysql group和order_mysql 用 group by 和 order by同时使用
  7. 系统架构设计师考试999999999999
  8. qmc0转换mp3工具_GoldenRecords for Mac(唱片录音转换软件)
  9. React 相关的优秀资源
  10. 设计模式入门(策略模式)