SpringBoot Maven环境下实现cache缓存

一 前期准备

1.SpringBoot + maven
2.本文使用分布式缓存 即以redis作为缓存容器

二 项目依赖

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

备注:依次为redis支持,web支持,测试支持。

三 项目目录结构


1 配置文件application

#========== 服务器 配置信息===========#
#服务器端口映射
server.port=8099
#服务项目名
server.servlet.path=/SpringBoot-cache


#==========cache 配置信息===========#
#缓存保存时间 单位ms
spring.cache.redis.time-to-live=10000
#缓存类别 可以不设置系统自动识别
spring.cache.type=redis


#==========redis 配置信息===========#

#(单机redis)数据库ip
spring.redis.host=127.0.0.1
#(单机redis)数据库端口
spring.redis.port= 6379
#数据库指定索引
spring.redis.database= 1
#数据库密码
spring.redis.password=
#超时时间
spring.redis.timeout= 5000
#连接池最大连接数,负值表示不限制
spring.redis.jedis.pool.max-active= 1000
#连接池中最大空闲连接
spring.redis.jedis.pool.max-idle= 10
#连接池中最小空闲连接
spring.redis.jedis.pool.min-idle= 2
#连接池最大阻塞等待时间,负值表示不限制
spring.redis.jedis.pool.max-wait= -1


备注:由于使用redis作为缓存容器,需要redis配置。spring-cache能自动识别缓存类别,redis采用缓存时效性管理缓存。

也可以自定义缓存策略进行缓存算法缓存算法

2 缓存配置 CacheConfig

package com.zyj.cache;

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Method;

/**
*@Description: 缓存配置文件
*@Author: zyj 2018/5/26 18:04
*/
@Configuration
@EnableCaching /**启用缓存**/
public class CacheConfig extends CachingConfigurerSupport {

    /**
    *@Description: 重写主键生成策略
    *@Author: zyj 2018/5/26 18:15
    */
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects){
                //TODO 结合object和method上面的注解信息 进行缓存注解设计
                StringBuilder sb = new StringBuilder();
                sb.append("KEY--");
                sb.append(o.getClass().getName());
                sb.append(method.getName());
                for (Object obj : objects) {
                    sb.append(obj.toString());
                }
                System.out.println(sb.toString());
                return sb.toString();
            }
        };
    }

}

备注:若不自定义缓存主键自定义,则不需要继承和重写方法,仅需要@EnableCache

3.缓存使用 CacheTestService

package com.zyj.service;

import com.zyj.bean.CacheTestBean;
import com.zyj.cache.CacheConfig;
import io.netty.util.internal.StringUtil;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
*@Description: 缓存测试服务
*@Author: zyj 2018/5/26 18:32
*/
@Service
public class CacheTestService {
    /**模拟数据库进行存储**/
    public  Map<String,CacheTestBean> list = new HashMap<String,CacheTestBean>();


    /**
    *@Description: 添加到map
    *@Author: zyj 2018/5/26 18:43
    */
    @CachePut(value = "cacheTestBean", key="#cacheTestBean.key",condition = "#cacheTestBean.name != null ")
    public CacheTestBean add(CacheTestBean cacheTestBean){
        if(null!=cacheTestBean
                &&!StringUtil.isNullOrEmpty(cacheTestBean.getKey())
                &&!list.containsKey(cacheTestBean.getKey())){
            /**设置创建时间**/
            cacheTestBean.setCreatTime(new Date());
            System.out.println("添加到内存:"+cacheTestBean);
            return list.put(cacheTestBean.getKey(),cacheTestBean);
        }
        return new CacheTestBean();
    }

    /**
     *@Description: 获取map
     *@Author: zyj 2018/5/26 18:43
     */
    @Cacheable(value = "cacheTestBean",key="#key", condition = "#key != null ")
    public CacheTestBean get(String key){
        if(!StringUtil.isNullOrEmpty(key)&&list.containsKey(key)){
            CacheTestBean current=list.get(key);
            /**设置更新时间**/
            current.setUpdateTime(new Date());
            list.put(key,current);
            System.out.println("读取内存:"+current);
            return current;
        }
        return new CacheTestBean();
    }

    /**
     *@Description: 删除map
     *@Author: zyj 2018/5/26 18:43
     */
    @CacheEvict(value = "cacheTestBean",key="#key",condition = "#key != null ")
    public CacheTestBean del(String key){
        if(!StringUtil.isNullOrEmpty(key)&&list.containsKey(key)){
            System.out.println("删除内存:"+key);
            return list.remove(key);
        }
        return new CacheTestBean();
    }
}

备注:使用map代替数据库查询,不影响缓存使用。

@Cacheable

最常用的注解,会把被注解方法的返回值缓存。工作原理是:首先在缓存中查找,如果没有执行方法并缓存结果,然后返回数据。此注解的缓存名必须指定,和cacheManager中的caches中的某一个Cache的name值相对应。可以使用value或cacheNames指定。
如果没有指定key属性,spring会使用默认的主键生成器产生主键。也可以自定义主键,在key中可以使用SpEL表达式。
value (也可使用 cacheNames) : 可看做命名空间,表示存到哪个缓存里了。
key : 表示命名空间下缓存唯一key,使用Spring Expression Language(简称SpEL,详见参考文献[5])生成。

condition : 表示在哪种情况下才缓存结果(对应的还有unless,哪种情况不缓存),同样使用SpEL


@CacheEvict 

该注解负责从缓存中显式移除数据,通常缓存数据都有有效期,当过期时数据也会被移除。
value (也可使用 cacheNames) : 同Cacheable注解,可看做命名空间。表示删除哪个命名空间中的缓存 
allEntries: 标记是否删除命名空间下所有缓存,默认为false
condition : 表示在哪种情况下才缓存结果(对应的还有unless,哪种情况不缓存),同样使用SpEL
key: 同Cacheable注解,代表需要删除的命名空间下唯一的缓存key。
beforeInvocation:在方法调用前还是调用后完成移除操作。true/false



@CachePut 

先执行方法,然后将返回值放回缓存。可以用作缓存的更新,可用于后台保存配置时及时刷新缓存。
value: 同上
key: 同上
condition(unless): 同上


4.缓存测试

CacheTestBean

package com.zyj.bean;

import java.io.Serializable;
import java.util.Date;

/**
*@Description: 缓存测试实体
*@Author: zyj 2018/5/26 18:28
*/
public class CacheTestBean implements Serializable{

    /**键**/
    String key;
    /**值**/
    String name;
    /**创建时间**/
    Date creatTime;
    /**更新时间**/
    Date updateTime;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreatTime() {
        return creatTime;
    }

    public void setCreatTime(Date creatTime) {
        this.creatTime = creatTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }


    @Override
    public String toString() {
        return "CacheTestBean{" +
                "key='" + key + '\'' +
                ", name='" + name + '\'' +
                ", creatTime=" + creatTime +
                ", updateTime=" + updateTime +
                '}';
    }
}

CacheTestController

package com.zyj.controller;

import com.zyj.bean.CacheTestBean;
import com.zyj.service.CacheTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.Cache;

/**
*@Description: 缓存测试控制器
*@Author: zyj 2018/5/26 18:51
*/
@RestController
@RequestMapping("/Cache")
public class CacheTestController {

    @Autowired
    CacheTestService cacheTestService;


    /**
    *@Description: 测试缓存
    *@param cacheTestBean
    *@return com.zyj.bean.CacheTestBean
    *@Author: zyj 2018/5/26 22:47
    */
    @RequestMapping("/add")
    public CacheTestBean testAdd(CacheTestBean cacheTestBean){
        return cacheTestService.add(cacheTestBean);
    }


    /**
     *@Description: 测试获取缓存
     *@param key
     *@return com.zyj.bean.CacheTestBean
     *@Author: zyj 2018/5/26 22:47
     */
    @RequestMapping("/get")
    public CacheTestBean testGet(String key){
        CacheTestBean current=cacheTestService.get(key);
        System.out.println("获得数据"+current);
        return current;
    }


    /**
     *@Description: 测试删除缓存
     *@param key
     *@return com.zyj.bean.CacheTestBean
     *@Author: zyj 2018/5/26 22:47
     */
    @RequestMapping("/del")
    public CacheTestBean testDel(String key){
        return cacheTestService.del(key);
    }

}

5.测试结果

存取数据,将进入数据已经缓存当中 命名格式以 缓存服务注释一致






读取数据  缓存已有则读取缓存数据  缓存失效后读取内存数据并再次缓存



备注:若不定义缓存key的规则,则使用CacheConfig中主键生成规则,亲测有效


祝你成功!

猜你喜欢

转载自blog.csdn.net/qq_22211217/article/details/80466050
今日推荐