SpringBoot--Ehcache缓存

1. 创建项目,添加缓存依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</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-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

添加缓存配置文件

如果Ehcache的依赖存在,并且在classpath下有一个名为ehcache.xml的Ehcache配置文件,那么EhCacheCacheManager将会自动作为缓存的实现。因此,在resources目录下创建ehcache.xml文件作为Ehcache缓存的配置文件:

<ehcache>
    <diskStore path="java.io.tmpdir/cache" />

    <defaultCache
        maxElementsInmemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="false"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120" />

    <cache name="book_cache"
           maxElementsInMemory="10000"
           eternal="true"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="600" />


</ehcache>

提供了两个缓存策略,一个是默认的,另一个名为book_cache。

  • name:缓存名称
  • maxElementsInMemory:缓存最大个数
  • eternal:缓存对象是否永久有效,一旦设置了永久有效,timeout将不起作用
  • timeToIidleSeconds:缓存对象在失效前的允许闲置时间(单位:秒);当eternal=false时,该属性才生效
  • overflowToDisk表示当内存中的对象数量达到maxElementsInmemory时,Ehcache是否将对象写到磁盘中
  • diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔

如果想自定义配置文件的名称和位置,可以在application.properties中添加如下配置:

spring.cache.ehcache.config=classpath:config/another-config.xml

3. 开启缓存

@SpringBootApplication
@EnableCaching
public class DemoApplication {

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

}

4. 创建BookDao

@Repository
@CacheConfig(cacheNames = "book_cache")
public class BookDao {

    @Cacheable
    public Book getBookById(Integer id){
        System.out.println("getBookById");
        Book book = new Book();
        book.setId(id);
        book.setName("三国演义");
        book.setAuthor("罗贯中");
        return book;
    }

    @CachePut(key = "#book.id")
    public Book updateBookById(Book book){
        System.out.println("updateBookById");
        book.setName("三国演义2");
        return book;
    }

    @CacheEvict(key = "#id")
    public void deleteBookById(Integer id){
        System.out.println("deleteBookById");
    }
}

如果不想使用默认的key,可以使用Spring提供的root对象来生成key:

属性名称 属性描述 用法示例
methodName 当前方法名 #root.methodName
method 当前方法对象 #root.method.name
caches 当前方法使用的缓存 #root.caches[0].name
target 当前被调用的对象 #root.target
targetClass 当前被调用的对象的class #root.targetClass
args 当前方法参数数组 #root.args[0]

如果这些key不能满足开发需求,可也一自定义缓存key的生成器KeyGenerator:

@Component
public class MyKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object o, Method method, Object... objects) {
        return Arrays.toString(objects);
    }
}

5. 创建测试类

@SpringBootTest
@RunWith(SpringRunner.class)
class DemoApplicationTests {

    @Autowired
    BookDao bookDao;

    @Test
    void contextLoads() {
        bookDao.getBookById(1);
        bookDao.getBookById(1);
        bookDao.deleteBookById(1);

        Book b3 = bookDao.getBookById(1);
        System.out.println("b3:" + b3);
        Book b = new Book();
        b.setName("三国演义");
        b.setAuthor("罗贯中");
        b.setId(1);
        bookDao.updateBookById(b);

        Book b4 = bookDao.getBookById(1);
        System.out.println("b4:" + b4);
    }

}

执行方法,控制台打印如下:

getBookById
deleteBookById
getBookById
b3:Book{id=1, name='三国演义', author='罗贯中'}
updateBookById
b4:Book{id=1, name='三国演义2', author='罗贯中'}

一开始执行了两个查询,但是查询方法只打印了一次,因为第二次使用了缓存。接下来执行删除方法,删除方法执行完之后再次执行查询,查询方法又被执行了,因为在删除方法中缓存已经被删除了。再接下来执行更新方法,更新方法中不仅更新数据,也更新了缓存,所以在最后的查询方法中,查询方法日志没打印,说明该方法没执行,而是使用了缓存中的数据,而缓存中的数据已经被更新了。

发布了716 篇原创文章 · 获赞 2079 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/104192079