Springboot中简单使用Ehcache

Springboot中简单使用Ehcache

一. Ehcache概述

	Ehcache is an open source, standards-based(基于标准) cache that boosts(提高) performance, offloads your database, and simplifies scalability(简化可扩展性). It's the most widely-used Java-based cache because it's robust(健壮), proven(久经考验), full-featured(功能齐全), and integrates with other popular libraries and frameworks. Ehcache scales(发音) from in-process(进程中) caching, all the way to mixed in-process/out-of-process deployments with terabyte-sized caches.

二. 开发步骤

2.1 pom文件

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
	<groupId>net.sf.ehcache</groupId>
	<artifactId>ehcache</artifactId>
</dependency>

2.2 application.properties配置

server.port=80
# Mysql 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=
# spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# mybatis配置
mybatis.type-aliases-package=cn.codesheep.springbt_ehcache.entity
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.map-underscore-to-camel-case=true

# ehcache配置
spring.cache.ehcache.config=classpath:ehcache.xml

2.3 Ehcache配置文件

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <diskStore path="java.io.tmpdir"/>

    <!-- 设定缓存的默认数据过期策略 -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>

    <cache name="user"
           maxElementsInMemory="1000"
           eternal="false"
           timeToIdleSeconds="10"/>
</ehcache>
  • defaultCache标签
    • maxElementsInMemory:内存中缓存最大个数
    • eternal:对象是否永久有效,一但设置了,timeout将不起作用。
    • timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
    • timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
    • overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
    • maxElementsOnDisk:硬盘最大缓存个数。
    • diskPersistent:是否持久化磁盘缓存,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名为cache名称,后缀名为index的文件
    • diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
    • memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少用)。
  • cache标签
    • name:缓存实例的名称
    • maxElementsInMemory:该缓存实例在内存中存储对象的最大个数
    • eternal:对象是否永久有效,一旦设置timeout将失效
    • timeToIdleSeconds:同上 (如果该属性值为10,那么该缓存对象中被缓存的数据在10s内没有被调用,那么该缓存会被清除)

三. 代码示例

  • 简单的curd操作,只是在某些发方法上将返回的结果缓存

3.1 实体对象类User

package cn.codesheep.springbt_ehcache.entity;

public class User {
    private Long userId;
    private String userName;
    private Integer userAge;

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getUserAge() {
        return userAge;
    }

    public void setUserAge(Integer userAge) {
        this.userAge = userAge;
    }
}

3.2 业务逻辑UserService

package cn.codesheep.springbt_ehcache.service;

import cn.codesheep.springbt_ehcache.entity.User;
import cn.codesheep.springbt_ehcache.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public List<User> getUsers() {
        return userMapper.getUsers();
    }

    public User addUser( User user ) {
        userMapper.addUser(user);
        return user;
    }

    @Cacheable(value = "user", key = "#userName")
    public User getUsersByName( String userName ) {
        User user = userMapper.getUsersByName(userName);
        System.out.println( "从数据库读取,而非读取缓存!" );
        return user;
    }

    @CachePut(value = "user", key = "#user.userName")
    public User addUserWithCache(User user){
        if (user == null){
            throw new IllegalArgumentException("addUserWithCache: user is null");
        }
        this.userMapper.addUser(user);
        System.out.println("向数据库中插入了一条新数据");
        return user;
    }

    @CacheEvict(value = "user", key = "#userName")
    public int deleteByName(String userName) {
        if (StringUtils.isEmpty(userName)){
            throw new IllegalArgumentException("");
        }
        return this.userMapper.delete(userName);

    }
}

3.3 数据访问层

package cn.codesheep.springbt_ehcache.mapper;

import cn.codesheep.springbt_ehcache.entity.User;

import java.util.List;

public interface UserMapper {

    List<User> getUsers();

    int addUser(User user);

    User getUsersByName( String userName );

    int delete(String userName);
}

3.4 控制层UserController

package cn.codesheep.springbt_ehcache.controller;

import cn.codesheep.springbt_ehcache.entity.User;
import cn.codesheep.springbt_ehcache.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    CacheManager cacheManager;

    @GetMapping("/users")
    public List<User> getUsers() {
        return userService.getUsers();
    }

    @PostMapping("/adduser")
    public User addSser() {
        User user = new User();
        user.setUserName("张三");
        user.setUserAge(36);
        return userService.addUser(user);
    }

    @PostMapping("/saveUser")
    public User saveUser() {
        User user = new User();
        user.setUserName("mark");
        user.setUserAge(20);
        return userService.addUserWithCache(user);
    }

    @RequestMapping(value = "/getusersbyname", method = RequestMethod.POST)
    public User geUsersByName(@RequestBody User user) {
        System.out.println("-------------------------------------------");
        System.out.println("call /getusersbyname");
        System.out.println(cacheManager.toString());
        user = userService.getUsersByName(user.getUserName());
        return user;
    }

    @PostMapping("/removeByName")
    public int removeByName(@RequestBody User user) {
        System.out.println("-------------------------------------------");
        System.out.println("call /removeByName");
        System.out.println(cacheManager.toString());
        return this.userService.deleteByName(user.getUserName());
    }
}

3.5 主类(程序入口)

package cn.codesheep.springbt_ehcache;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@MapperScan("cn.codesheep.springbt_ehcache")
@EnableCaching
public class SpringbtEhcacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbtEhcacheApplication.class, args);
    }
}

四. 分析

此处主要是来分析使用缓存和没有使用缓存时代码有什么不同

4.1 @EnableCaching

	Enables Spring's annotation-driven cache management capability, similar to the support found in Spring's <cache *> XML namespace. To be used together with (org.springframework.context.annotation.Configuration) Configuration	
  • EnableCaching该注解开启了Spring的注解驱动缓存管理能力,类似于支持Spring的cache的XML命名空间,该注解与Configuration注解一起使用
  • 猜测:开启解析cache.xml的功能

4.2 @Cacheable

4.2.1 源码原文

	Annotation indicating that the result of invoking a method (or all methods in a class) can be cached. Each time an advised method is invoked, caching behavior will be applied, checking whether the method has been already invoked for the given arguments.
	If no value is found in the cache for the computed key, the target method will be invoked and the returned value stored in the associated cache. 

4.2.2 解释

  • 注解@Cacheable可以用在类和方法上
  • 该注解表示当方法被调用时,该方法的返回数据会被缓存起来
  • 每一次被通知的方法被调用时,缓存行为将会发生,检查该方法是否已经调用过(猜测:根据方法名和参数值来判断该方法是否已经被调用)。
  • 根据被计算的key在缓存中没有发现对应的值(即方法并没有被调用过),则调用该方法,并将返回数据存入对应的缓存中。

4.3 @CachePut

4.3.1 源码原文

	Annotation indicating that a method (or all methods on a class) triggers a {@link org.springframework.cache.Cache#put(Object, Object) cache put} operation.
	In contrast to the {@link Cacheable @Cacheable} annotation, this annotation does not cause the advised method to be skipped. Rather, it always causes the method to be invoked and its result to be stored in the associated cache

4.3.2 解释

  • 注解@CachePut可以用在类和方法上。
  • 该注解表示一个方法或则时某个类上的所有方法触发一个缓存压入操作。
  • 与@Cacheable相反,@CachePut注解并不会造成被通知的方法放弃执行。反而,它会造成方法被执行并且它的结果会被存储在相关联的缓存中。
  • 该注解一般被用在对数据库的数据进行插入和修改的方法上。

4.3.3 注意

  • @Cacheable和@CachePut的key值必须相同。
  • @Cacheable和@CachePut所在方法的返回值必须相同。

4.4 @CacheEvict

4.4.1 源码原文

 	Annotation indicating that a method (or all methods on a class) triggers a {@link org.springframework.cache.Cache#evict(Object) cache evict} operation.

4.4.2 解释

  • 注解@CacheEvict可以用在类和方法上。(Evict:驱逐,赶出)。
  • 该注解表示一个方法或类上的所有方法触发缓存删除操作。
  • 该注解通过属性key,经过一系列操作,会在cache中将相对应的缓存删除。

五. 问题

  • 缓存cache中,存储数据时,key是如何计算出来的
  • 在@Cacheable使用过程中,如何判断被通知方法被已经被调用(看源码)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值