加入收藏 | 设为首页 | 会员中心 | 我要投稿 北几岛 (https://www.beijidao.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Spring Boot 集成 Redis 实现缓存机制

发布时间:2021-07-06 05:26:27 所属栏目:大数据 来源: https://www.cnblogs.com/xiado
导读:?本文章牵涉到的技术点比较多:spring?Data JPA、Redis、Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对以上这些技术点有一定的了解或者也可以先看看这篇文章,针对文章中实际的技术点在进一步了解(注意,您需要自己下载Redis Server到您的本地

?本文章牵涉到的技术点比较多:spring?Data JPA、Redis、Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对以上这些技术点有一定的了解或者也可以先看看这篇文章,针对文章中实际的技术点在进一步了解(注意,您需要自己下载Redis Server到您的本地,所以确保您本地的Redis可用,这里还使用了MySQL数据库,当然你也可以内存数据库进行测试)。这篇文章会提供对应的Eclipse代码示例,具体大体的分如下几个步骤:

(1)新建Java?MavenProject;

(2)在pom.xml中添加相应的依赖包;

(3)编写Spring Boot启动类;

(4)配置application.properties;

(5)编写RedisCacheConfig配置类;

(6)编写DemoInfo测试实体类;

(7)编写DemoInfoRepository持久化类;

(8)编写DemoInfoService类;

(9)编写DemoInfoController类;

(10)测试代码是否正常运行了

(11)自定义缓存key;

?

???????接下来我们看看具体每个步骤具体的操作吧。
(1)新建Java?Maven Project;

???????这个步骤就不细说,新建一个spring-boot-redis Java mavenproject;

?

(2)在pom.xml中添加相应的依赖包;

在Maven中添加相应的依赖包,主要有:springboot 父节点依赖;spring boot web支持;缓存服务spring-context-support;添加redis支持;JPA操作数据库;MysqL 数据库驱动,具体pom.xml文件如下:

<project?xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

??xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

?<modelVersion>4.0.0</modelVersion>

?

?<groupId>com.kfit</groupId>

?<artifactId>spring-boot-redis</artifactId>

?<version>0.0.1-SNAPSHOT</version>

?<packaging>jar</packaging>

?

?<name>spring-boot-redis</name>

?<url>http://maven.apache.org</url>

?

?<properties>

???<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

???<!--?配置JDK编译版本. -->

???????<java.version>1.8</java.version>

?</properties>

?

?<!-- spring boot?父节点依赖,

??????????????引入这个之后相关的引入就不需要添加version配置,

????????????? ?spring boot会自动选择最合适的版本进行添加。

?????? -->

???????<parent>

??????????????<groupId>org.springframework.boot</groupId>

??????????????<artifactId>spring-boot-starter-parent</artifactId>

??????????????<version>1.3.3.RELEASE</version>

???????</parent>

?

?

?<dependencies>

?????????

??????????<dependency>

?????????????????????<groupId>junit</groupId>

?????????????????????<artifactId>junit</artifactId>

?????????????????????<scope>test</scope>

??????????????</dependency>

?

??????????????<!-- springboot web支持:mvc,aop... -->

??????????????<dependency>

?????????????????????<groupId>org.springframework.boot</groupId>

?????????????????????<artifactId>spring-boot-starter-web</artifactId>

??????????????</dependency>

?????????????

??????????????<!--

?????????????????????包含支持UI模版(Velocity,FreeMarker,JasperReports),

?????????????????????邮件服务,

?????????????????????脚本服务(JRuby),

?????????????????????缓存Cache(EHCache),

?????????????????????任务计划Scheduling(uartz)。

????????????? ?-->

??????????????<dependency>

?????? ??????<groupId>org.springframework</groupId>

?????? ??????<artifactId>spring-context-support</artifactId>

?????? ????</dependency>

?

??????????????<!--?添加redis支持-->

??????????????<dependency>

????????????<groupId>org.springframework.boot</groupId>

???????????<artifactId>spring-boot-starter-redis</artifactId>

????????</dependency>

?????????????

??????????????<!-- JPA操作数据库. -->

??????????????<dependency>

?????? ??????<groupId>org.springframework.boot</groupId>

?????? ??????<artifactId>spring-boot-starter-data-jpa</artifactId>

?????? ????</dependency>

?????????????

??????????????<!--?MysqL数据库驱动. -->

??????????????<dependency>

?????? ??????<groupId>MysqL</groupId>

?????? ??????<artifactId>MysqL-connector-java</artifactId>

?????? ????</dependency>

?????? ???

?????? ????<!--?单元测试. -->

??????????????<dependency>

????????????<groupId>org.springframework.boot</groupId>

????????????<artifactId>spring-boot-starter-test</artifactId>

????????????<scope>test</scope>

????????</dependency>

?????????????

?</dependencies>

</project>

上面是完整的pom.xml文件,每个里面都进行了简单的注释。

?

(3)编写Spring Boot启动类(com.kfit.App);

package com.kfit;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

?* Spring Boot启动类;

?*

?* @authorAngel(QQ:412887952)

?* @version v.0.1

?*/

?

@SpringBootApplication

public class App {

?????? /**

?????? ?*-javaagent:.libspringloaded-1.2.4.RELEASE.jar -noverify

?????? ?* @param args

?????? ?*/

?????? public static voidmain(String[] args) {

????????????? SpringApplication.run(App.class,args);

?????? }

}

?

(4)配置application.properties;

这里主要是配置两个资源,第一就是数据库基本信息;第二就是redis配置;第三就是JPA的配置;

Src/main/resouces/application.properties:

########################################################

###datasource??配置MysqL数据源;

########################################################

spring.datasource.url?=jdbc:MysqL://localhost:3306/test

spring.datasource.username?=?root

spring.datasource.password?=?root

spring.datasource.driverClassName?=com.MysqL.jdbc.Driver

spring.datasource.max-active=20

spring.datasource.max-idle=8

spring.datasource.min-idle=8

spring.datasource.initial-size=10

?

?

?

########################################################

###REDIS (RedisProperties) redis基本配置;

########################################################

# database name

spring.redis.database=0

# server host1

spring.redis.host=127.0.0.1??

# server password

#spring.redis.password=

#connection port

spring.redis.port=6379

# pool settings ...

spring.redis.pool.max-idle=8

spring.redis.pool.min-idle=0

spring.redis.pool.max-active=8

spring.redis.pool.max-wait=-1

# name of Redis server

#spring.redis.sentinel.master=

# comma-separated list of host:portpairs

#spring.redis.sentinel.nodes=

?

?

########################################################

### Java Persistence Api?自动进行建表

########################################################

# Specify the DBMS

spring.jpa.database?=?MysqL

# Show or not log for each sqlquery

spring.jpa.show-sql?=?true

#?hibernate?ddl auto (create,create-drop,update)

spring.jpa.hibernate.ddl-auto?=?update

# Naming strategy

spring.jpa.hibernate.naming-strategy?=org.hibernate.cfg.ImprovedNamingStrategy

# stripped before adding them tothe entity manager)

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MysqL5Dialect

?

?

?

(5)编写RedisCacheConfig配置类;

???????缓存主要有几个要实现的类:其一就是CacheManager缓存管理器;其二就是具体操作实现类;其三就是CacheManager工厂类(这个可以使用配置文件配置的进行注入,也可以通过编码的方式进行实现);其四就是缓存key生产策略(当然Spring自带生成策略,但是在Redis客户端进行查看的话是系列化的key,对于我们肉眼来说就是感觉是乱码了,这里我们先使用自带的缓存策略)。

com.kfit.config/RedisCacheConfig:

package?com.kfit.config;

?

importorg.springframework.cache.CacheManager;

importorg.springframework.cache.annotation.CachingConfigurerSupport;

importorg.springframework.cache.annotation.EnableCaching;

importorg.springframework.context.annotation.Bean;

import?org.springframework.context.annotation.Configuration;

importorg.springframework.data.redis.cache.RedisCacheManager;

importorg.springframework.data.redis.connection.RedisConnectionFactory;

importorg.springframework.data.redis.core.RedisTemplate;

?

/**

?*?redis?缓存配置;

?*

?*?注意:RedisCacheConfig这里也可以不用继承 :CachingConfigurerSupport,也就是直接一个普通的Class就好了;

?*

?*?这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。

?*

?*?普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。

?*

?*?@author?Angel(QQ:412887952)

?*?@version?v.0.1

?*/

@Configuration

@EnableCaching?//启用缓存,这个注解很重要;

public?class?RedisCacheConfig?extendsCachingConfigurerSupport {

??????

??????

???????/**

?????? ?*?缓存管理器.

?????? ?*?@param?redisTemplate

?????? ?*?@return

?????? ?*/

???????@Bean

???????public?CacheManagercacheManager(RedisTemplate<?,?>?redisTemplate) {

????????????? CacheManagercacheManager?=?newRedisCacheManager(redisTemplate);

??????????????return?cacheManager;

?????? }

?

??????

???????/**

?????? ?*?redis模板操作类,类似于jdbcTemplate的一个类;

?????? ?*

?????? ?*?虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活;

?????? ?*

?????? ?*?这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们

?????? ?*

?????? ?*?自己的缓存类,比如:RedisStorage类;

?????? ?*

?????? ?*?@param?factory :?通过Spring进行注入,参数在application.properties进行配置;

?????? ?*?@return

?????? ?*/

???????@Bean

???????publicRedisTemplate<String,String> redisTemplate(RedisConnectionFactory?factory) {

????????????? RedisTemplate<String,String>?redisTemplate?=?new?RedisTemplate<String,String>();

??????????????redisTemplate.setConnectionFactory(factory);

?????????????

??????????????//key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;

??????????????//所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer

??????????????//或者JdkSerializationRedisSerializer序列化方式;

//?????????? RedisSerializer<String>redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;

//?????????? redisTemplate.setKeySerializer(redisSerializer);

//?????????? redisTemplate.setHashKeySerializer(redisSerializer);

?????????????

??????????????return?redisTemplate;

?????? }

?

}

在以上代码有很详细的注释,在这里还是在简单的提下:

RedisCacheConfig这里也可以不用继承:CachingConfigurerSupport,也就是直接一个普通的Class就好了;这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。

?

?

(6)编写DemoInfo测试实体类;

???????编写一个测试实体类:com.kfit.bean.DemoInfo:

package?com.kfit.bean;

?

import?java.io.Serializable;

import?javax.persistence.Entity;

import?javax.persistence.GeneratedValue;

import?javax.persistence.Id;

/**

?*?测试实体类,这个随便;

?*?@author?Angel(QQ:412887952)

?*?@version?v.0.1

?*/

@Entity

public?class?DemoInfo??implements?Serializable{

???????private?static?final?long?serialVersionUID?= 1L;

???????@Id?@GeneratedValue

???????private?long?id;

???????private?String?name;

???????private?String?pwd;

???????public?long?getId() {

??????????????return?id;

?????? }

???????public?void?setId(long?id) {

??????????????this.id?=?id;

?????? }

???????public?StringgetName() {

??????????????return?name;

?????? }

???????public?void?setName(String?name) {

??????????????this.name?=?name;

?????? }

???????public?String getPwd(){

??????????????return?pwd;

?????? }

???????public?void?setPwd(String?pwd) {

??????????????this.pwd?=?pwd;

?????? }

??????

???????@Override

???????public?StringtoString() {

?????? ???????return?"DemoInfo [id="?+?id?+?",name="?+?name?+?",pwd="?+?pwd?+?"]";

?????? }

}

?

(7)编写DemoInfoRepository持久化类;

?????? DemoInfoRepository使用Spirng DataJPA实现:

com.kfit.repository.DemoInfoRepository:

package?com.kfit.repository;

?

import?org.springframework.data.repository.CrudRepository;

?

import?com.kfit.bean.DemoInfo;

?

/**

?* DemoInfo持久化类

?*?@author?Angel(QQ:412887952)

?*?@version?v.0.1

?*/

public?interfaceDemoInfoRepository?extends?CrudRepository<DemoInfo,Long> {

?

}

?

(8)编写DemoInfoService类;

???????编写DemoInfoService,这里有两个技术方面,第一就是使用Spring @Cacheable注解方式和RedisTemplate对象进行操作,具体代码如下:

com.kfit.service.DemoInfoService:

package?com.kfit.service;

?

import?com.kfit.bean.DemoInfo;

?

/**

?* demoInfo?服务接口

?*?@author?Angel(QQ:412887952)

?*?@version?v.0.1

?*/

public?interface?DemoInfoService{

??????

???????public?DemoInfofindById(long?id);

??????

???????public?voiddeleteFromCache(long?id);

?

???????void?test();

}

?

?

com.kfit.service.impl.DemoInfoServiceImpl:

package?com.kfit.service.impl;

?

import?javax.annotation.Resource;

?

importorg.springframework.cache.annotation.CacheEvict;

importorg.springframework.cache.annotation.Cacheable;

importorg.springframework.data.redis.core.RedisTemplate;

importorg.springframework.data.redis.core.ValueOperations;

importorg.springframework.stereotype.Service;

?

import?com.kfit.bean.DemoInfo;

importcom.kfit.repository.DemoInfoRepository;

import?com.kfit.service.DemoInfoService;

?

/**

?*

?*DemoInfo数据处理类

?*

?*?@author?Angel(QQ:412887952)

?*?@version?v.0.1

?*/

@Service

public?class?DemoInfoServiceImpl?implements?DemoInfoService{

??????

???????@Resource

???????privateDemoInfoRepository?demoInfoRepository;

??????

???????@Resource

???????privateRedisTemplate<String,String>?redisTemplate;

??????

???????@Override

???????public?void?test(){

????????????? ValueOperations<String,String>valueOperations?=?redisTemplate.opsForValue();

??????????????valueOperations.set("mykey4",?"random1="+Math.random());

????????????? System.out.println(valueOperations.get("mykey4"));

?????? }

??????

???????//keyGenerator="myKeyGenerator"

???????@Cacheable(value="demoInfo")?//缓存,这里没有指定key.

???????@Override

???????public?DemoInfofindById(long?id) {

????????????? System.err.println("DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id="+id);

??????????????return?demoInfoRepository.findOne(id);

?????? }

??????

???????@CacheEvict(value="demoInfo")

???????@Override

???????public?void?deleteFromCache(long?id) {

????????????? System.out.println("DemoInfoServiceImpl.delete().从缓存中删除.");

?????? }

??????

}

?

?

(9)编写DemoInfoController类;

package?com.kfit.controller;

?

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.stereotype.Controller;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.bind.annotation.ResponseBody;

?

import?com.kfit.bean.DemoInfo;

import?com.kfit.service.DemoInfoService;

?

/**

?*?测试类.

?*?@author?Angel(QQ:412887952)

?*?@version?v.0.1

?*/

@Controller

public?class?DemoInfoController {

??????

???????@Autowired

?????? ?DemoInfoService?demoInfoService;

?????? ?

??????

???????@RequestMapping("/test")

???????public?@ResponseBody?String test(){

?????? ??? DemoInfo?loaded?=?demoInfoService.findById(1);

System.out.println("loaded="+loaded);

DemoInfo?cached?=?demoInfoService.findById(1);

?????? ?? ?System.out.println("cached="+cached);

?????? ????loaded?=?demoInfoService.findById(2);

?????? ??? System.out.println("loaded2="+loaded);

?????? ????return?"ok";

?????? }

??????

??????

???????@RequestMapping("/delete")

???????public?@ResponseBody?String delete(long?id){

?????? ????demoInfoService.deleteFromCache(id);

?????? ????return?"ok";

?????? }

??????

???????@RequestMapping("/test1")

???????public?@ResponseBody?String test1(){

?????? ????demoInfoService.test();

?????? ??? System.out.println("DemoInfoController.test1()");

?????? ????return?"ok";

?????? }

??????

}

?

(10)测试代码是否正常运行了

?

启动应用程序,访问地址:http://127.0.0.1:8080/test

查看控制台可以查看:

DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1

loaded=DemoInfo [id=1,name=张三,pwd=123456]

cached=DemoInfo [id=1,pwd=123456]

DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=2

loaded2=DemoInfo [id=2,pwd=123456]

如果你看到以上的打印信息的话,那么说明缓存成功了。

?

访问地址:http://127.0.0.1:8080/test1

random1=0.9985031320746356

DemoInfoController.test1()

?

二次访问:http://127.0.0.1:8080/test

loaded=DemoInfo [id=1,pwd=123456]

loaded2=DemoInfo [id=2,pwd=123456]

这时候所有的数据都是执行缓存的。

?

这时候执行删除动作:http://127.0.0.1:8080/delete?id=1

然后在访问:http://127.0.0.1:8080/test

DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1

loaded=DemoInfo [id=1,pwd=123456]

?

(11)自定义缓存key;

在com.kfit.config.RedisCacheConfig类中重写CachingConfigurerSupport中的keyGenerator,具体实现代码如下:

?

/**

?????? ?*?自定义key.

?????? ?*?此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。

?????? ?*/

???????@Override

???????public?KeyGeneratorkeyGenerator() {

????????????? System.out.println("RedisCacheConfig.keyGenerator()");

??????????????return?new?KeyGenerator(){

?????????????????????@Override

?????????????????????public?Objectgenerate(Object?o,Method?method,Object...?objects) {

????????????????????????????// This willgenerate a unique key of the class name,the method name

????????????????????????????//and allmethod parameters appended.

??????????????????????????? StringBuildersb?=?newStringBuilder();

????????????????????????????sb.append(o.getClass().getName());

????????????????????????????sb.append(method.getName());

????????????????????????????for?(Object?obj?:?objects) {

??????????????????????????? ???????sb.append(obj.toString());

??????????????????????????? }

??????????????????????????? System.out.println("keyGenerator="?+?sb.toString());

????????????????????????????return?sb.toString();

???????????????????? }

????????????? };

?????? }

?

这时候在redis的客户端查看key的话还是序列化的肉眼看到就是乱码了,那么我改变key的序列方式,这个很简单,redis底层已经有具体的实现类了,我们只需要配置下:

//key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;

//所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer

//或者JdkSerializationRedisSerializer序列化方式;

????????????? RedisSerializer<String>redisSerializer?=?newStringRedisSerializer();//Long类型不可以会出现异常信息;

??????????????redisTemplate.setKeySerializer(redisSerializer);

??????????????redisTemplate.setHashKeySerializer(redisSerializer);

综上以上分析:RedisCacheConfig类的方法调整为:

package?com.kfit.config;

?

import?java.lang.reflect.Method;

?

importorg.springframework.cache.CacheManager;

importorg.springframework.cache.annotation.CachingConfigurerSupport;

importorg.springframework.cache.annotation.EnableCaching;

importorg.springframework.cache.interceptor.KeyGenerator;

import?org.springframework.context.annotation.Bean;

importorg.springframework.context.annotation.Configuration;

importorg.springframework.data.redis.cache.RedisCacheManager;

importorg.springframework.data.redis.connection.RedisConnectionFactory;

importorg.springframework.data.redis.core.RedisTemplate;

importorg.springframework.data.redis.serializer.RedisSerializer;

importorg.springframework.data.redis.serializer.StringRedisSerializer;

?

/**

?*?redis?缓存配置;

?*

?*?注意:RedisCacheConfig这里也可以不用继承 :CachingConfigurerSupport,也就是直接一个普通的Class就好了;

?*

?*?这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。

?*

?*?普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。

?*

?*?@author?Angel(QQ:412887952)

?*?@version?v.0.1

?*/

@Configuration

@EnableCaching?//启用缓存,这个注解很重要;

public?class?RedisCacheConfig?extendsCachingConfigurerSupport {

??????

???????/**

?????? ?*?缓存管理器.

?????? ?*?@param?redisTemplate

?????? ?*?@return

?????? ?*/

???????@Bean

???????public?CacheManagercacheManager(RedisTemplate<?,?>?redisTemplate) {

????????????? CacheManagercacheManager?=?newRedisCacheManager(redisTemplate);

??????????????return?cacheManager;

?????? }

?

??????

???????/**

?????? ?* RedisTemplate缓存操作类,但是如果方法上有Long等非String类型的话,会报类型转换错误;

??????????????//所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer

??????????????//或者JdkSerializationRedisSerializer序列化方式;

????????????? RedisSerializer<String>redisSerializer?=?newStringRedisSerializer();//Long类型不可以会出现异常信息;

??????????????redisTemplate.setKeySerializer(redisSerializer);

??????????????redisTemplate.setHashKeySerializer(redisSerializer);

?????????????

??????????????return?redisTemplate;

?????? }

??????

???????/**

?????? ?*?自定义key.

?????? ?*?此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,the method name

????????????????????????????//and allmethod parameters appended.

??????????????????????????? StringBuildersb?=?newStringBuilder();

????????????????????????????sb.append(o.getClass().getName());

????????????????????????????sb.append(method.getName());

????????????????????????????for?(Object?obj?:?objects) {

???????????????????????????????????sb.append(obj.toString());

??????????????????????????? }

??????????????????????????? System.out.println("keyGenerator="?+?sb.toString());

????????????????????????????return?sb.toString();

???????????????????? }

????????????? };

?????? }

?

}

?

这时候在访问地址:http://127.0.0.1:8080/test

这时候看到的Key就是:com.kfit.service.impl.DemoInfoServiceImplfindById1

在控制台打印信息是:

(1)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1

(2)DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1

(3)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1

(4)loaded=DemoInfo[id=1,pwd=123456]

(5)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1

(6)cached=DemoInfo[id=1,pwd=123456]

(7)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById2

(8)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById2

(10)DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=2

(11)loaded2=DemoInfo[id=2,pwd=123456]

其中@Cacheable,@CacheEvict下节进行简单的介绍,这节的东西实在是太多了,到这里就打住吧,剩下的就需要靠你们自己进行扩展了。

(编辑:北几岛)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读