spring boot缓存_Spring Boot和缓存抽象

spring boot缓存

缓存是大多数应用程序的主要组成部分,只要我们设法避免磁盘访问,缓存就会保持强劲。 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 boot缓存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/335562.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有c基础学java多久_有c十十基础的自学java语言每天6小时要多长时间?

建议花6个月学习。1、前面2个月学习下面这本书。2、后面4个月同时学习数据结构与算法 刷LeetCode 学习Spring BootSpring boot 看这本书 官方文档 找点视频看看。Spring Boot provides a variety of features that address todays business needs with a powerful database…

Apache的架构师总结出30条架构设计原则

Srinath是一位科学家&#xff0c;软件架构师&#xff0c;也是一名在分布式系统上工作的程序员。 他是Apache Axis2项目的联合创始人&#xff0c;也是Apache Software基金会的成员。 他是WSO2流处理器&#xff08;wso2.com/analytics&#xff09;的联席架构师。 Srinath撰写了两…

本地运行flowable_在CockroachDB上运行Flowable

本地运行flowable什么是CockroachDB&#xff1f; CockroachDB是一个我一直关注了很长时间的项目。 这是一个开放源代码的Apache 2许可数据库&#xff08; Github链接 &#xff09;&#xff0c;该数据库在很大程度上汲取了Google Spanner白皮书的启发 。 它的核心是可水平扩展的…

win10禁用驱动程序强制签名_图文细说 win10系统未检测到第三个监视器的途径 -win10使用教程...

据统计调查&#xff0c;好多朋友都在为图文细说 win10系统未检测到第三个监视器的途径 的问题而烦恼&#xff0c;小编决定将解决的办法分享给大家。对于电脑菜鸟而言看到图文细说 win10系统未检测到第三个监视器的途径 是很无奈的&#xff0c;试着独自一个人解决图文细说 win10…

HH SaaS电商系统的各种编号(编码/代码/代号)设计

文章目录主订单编号规则一&#xff08;租户内唯一&#xff09;主订单编号规则二&#xff08;租户内唯一&#xff09;子订单编号规则&#xff08;租户内唯一&#xff09;租户编号规则&#xff08;系统内唯一&#xff09;供应商编号规则&#xff08;租户内唯一&#xff09;平台编…

安装openstack_午餐前如何安装OpenStack Cloud

安装openstack图1. QuickStart的内部工作原理 云安装程序 如果我告诉您可以在必须停下来吃午餐之前进行OpenStack Cloud环境设置&#xff0c;该怎么办&#xff1f; 您会感到惊讶吗&#xff1f; 你今天可以做吗&#xff1f; 在大多数情况下&#xff0c;我敢打赌您的答案是不…

5e怎么绑定一键跳投_怎么开通淘宝亲情账号 淘宝亲情账号申请步骤【详解】

据官方消息&#xff0c;淘宝将在2月1日上线“亲情账号”功能。那么 淘宝亲情账号怎么开通?在哪申请? 下面为大家介绍下&#xff0c;一起来看看。亲情账号用户在淘宝账号中可以创建“父亲”或“母亲”角色关系&#xff0c;对父母发出注册邀请或直接绑定他们的账号。完成亲情关…

java redis集群连接池_(08)redis之使用java客户端、spring连接redis、redis集群示例...

一、java代码连接1、新建工程&#xff0c;并引入以下包&#xff1a;jedis-2.7.0.jar、commons-pool2-2.3.jar、junit-4.10.jar2、单实例连接/*** 单实例连接*/Testpublic voidjedisClient(){//创建一个Jedis的连接Jedis jedisnew Jedis("192.168.7.151",6379);//可以…

混合模式商城的可经销商品池

需求背景 自营店铺不允许发布商品 自营店铺的经营模式为“O2O” 自营店铺需开通仓储系统&#xff0c;选售商品后&#xff0c;门店需要自己囤货在仓库&#xff0c;后续在其店铺出售并自行发货出库&#xff0c;若创建的自营店铺未开通仓储系统&#xff0c;选售商品之后&#xf…

探索cqrs和事件源_实践中的事件源和CQRS

探索cqrs和事件源任何尝试实施完全符合ACID的系统的人都知道&#xff0c;您需要做很多事情。 您需要确保可以自由创建&#xff0c;修改和删除数据库实体而不会出错&#xff0c;并且在大多数情况下&#xff0c;解决方案将以性能为代价。 可以用来解决此问题的一种方法是根据一系…

windows功能_你的Windows杀毒软件有这个功能吗?

安全软件首推-火绒&#xff0c;良心之作。比起360安全卫士、腾讯电脑管家&#xff0c;它无广告&#xff0c;无捆绑&#xff0c;无劫持&#xff0c;无弹窗&#xff0c;还免费。我认为最喜人最贴心的功能属它的‘弹窗拦截’了&#xff0c;可以拦截程序推送烦人的弹窗。五大浓缩亮…

base64 二进制流java_读取和base64编码二进制文件

我m trying to read a binary file from the filesystem and then base64 encode it in JavaScript. I使用FileReader API读取数据并找到base64编码器here .我的代码似乎接近工作&#xff0c;问题是生成的base64数据是错误的 . 这是我到目前为止所得到的&#xff1a;function s…

drools dmn_使用Drools的DMN运行时示例

drools dmn正如去年宣布的那样 &#xff0c;Drools 7.0将在合规级别3对DMN模型提供全面的运行时支持。 在撰写本文时&#xff0c;运行时实现已完成&#xff0c;并且该团队现在正在努力进行改进&#xff0c;以进行错误修复和用户友好。 不幸的是&#xff0c;对于7.0版本&#…

笔记本电脑关机后指示灯还亮_汽车仪表常见指示符号之清洗液指示灯,灯亮了怎么办?...

清洗液指示灯就是玻璃水指示灯&#xff0c;用来显示玻璃水的储存量的&#xff0c;平时为熄灭状态&#xff0c;当玻璃水不足时就会点亮提醒驾驶员该添加了。添加后清洗液指示灯还亮的说明出现故障&#xff0c;检查玻璃水电机&#xff0c;相关线路保险丝等&#xff0c;行车中此灯…

java image 设置大小_如何在Java中调整BufferedImage的大小

单步缩放的主要问题是它们通常不会产生高质量的输出&#xff0c;因为它们专注于将原始图像压缩到更小的空间中&#xff0c;通常通过剔除大量像素信息(不同的算法完成不同的事情&#xff0c;所以我归纳有效)威尔drawGraphics规模上下&#xff0c;是的&#xff0c;它会向它或产生…

xxx钻石商城功能开发需求

文章目录1. 买家小程序端1.1. 首页1.2. 店铺1.2.1. 搜索门店1.2.2. 门店信息1.2.3. 预约试戴1.3. 购物袋1.3.1. 加入购物车1.3.2. 编辑购物车1.4. 个人中心1.4.1. 个人信息1.4.2. 实名认证1.4.3. 我的等级1.4.4. 查看收益1.4.4.1 门店收益1.4.4.1.1查看结算单1.4.4.2 分享收益1…

drools6.5_Drools 6.5.0.Final可用

drools6.5最新和最出色的Drools 6.5.0.Final版本现已可供下载。 这是我们以前的版本的增量版本&#xff0c;重点是一些重要的改进以完善6.x系列。 您可以在此处找到更多详细信息&#xff0c;下载和文档&#xff1a; Drools网站 资料下载 文献资料 发行说明 请阅读下面的一…

c++ vector 一部分_C++ vector 使用注意事项

1、初始化c 11以后新增了大括号{}的初始化方式&#xff0c;需要注意与()的区别,如&#xff1a;std::vector<int> vecTest1(5); //初始化5个元素&#xff0c;每个都是0std::vector<int> vecTest2{ 5 }; //初始化1个元素&#xff0c;值是52、添加元素&#xff1a;pus…

java list 取前3个_用java 截取字符串,每三个一组

展开全部以下是将一长串数字分组用逗号隔开,每三个一组,转化为字符串.例如:2345678--->2,345,67823--->23private static String convert(long space) {String str String.valueOf(space);StringBuilder builder new StringBuilder(str);str builder.reverse().toStri…