2023-02-20  阅读(2)
原文作者:方志鹏 原文地址:https://blog.csdn.net/forezp/category_6830966.html

本文介绍如何在springboot中使用默认的spring cache,

声明式缓存

Spring 定义 CacheManager 和 Cache 接口用来统一不同的缓存技术。例如 JCache、 EhCache、 Hazelcast、 Guava、 Redis 等。在使用 Spring 集成 Cache 的时候,我们需要注册实现的 CacheManager 的 Bean。

Spring Boot 为我们自动配置了 JcacheCacheConfiguration、 EhCacheCacheConfiguration、HazelcastCacheConfiguration、GuavaCacheConfiguration、RedisCacheConfiguration、SimpleCacheConfiguration 等。

默认使用 ConcurrenMapCacheManager

在我们不使用其他第三方缓存依赖的时候,springboot自动采用ConcurrenMapCacheManager作为缓存管理器。

环境依赖

在pom文件引入spring-boot-starter-cache环境依赖:

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

创建一个book数据访问层

先创建一个实体类

    
    public class Book {
    
       private String isbn;
       private String title;
    
       public Book(String isbn, String title) {
           this.isbn = isbn;
           this.title = title;
       }
     ....getter
     ....setter  
    
    }

创建一个数据访问接口

    
    public interface BookRepository {
    
        Book getByIsbn(String isbn);
    
    }

这个你可以写一个很复杂的数据查询操作,比如操作mysql、nosql等等。为了演示这个栗子,我只做了一下线程的延迟操作,当作是查询数据库的时间。

实现接口类:

    @Component
    public class SimpleBookRepository implements BookRepository {
    
        @Override
        
        public Book getByIsbn(String isbn) {
            simulateSlowService();
            return new Book(isbn, "Some book");
        }
    
        // Don't do this at home
        private void simulateSlowService() {
            try {
                long time = 3000L;
                Thread.sleep(time);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
        }
    
    }

测试类

    @Component
    public class AppRunner implements CommandLineRunner {
    
        private static final Logger logger = LoggerFactory.getLogger(AppRunner.class);
    
        private final BookRepository bookRepository;
    
        public AppRunner(BookRepository bookRepository) {
            this.bookRepository = bookRepository;
        }
    
        @Override
        public void run(String... args) throws Exception {
            logger.info(".... Fetching books");
            logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
            logger.info("isbn-4567 -->" + bookRepository.getByIsbn("isbn-4567"));
            logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
            logger.info("isbn-4567 -->" + bookRepository.getByIsbn("isbn-4567"));
            logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
            logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
        }
    
    }

启动程序,你会发现程序在控制台依次打印了:

2014-06-05 12:15:35.783 … : … Fetching books

2014-06-05 12:15:40.783 … : isbn-1234 --> >Book{isbn=‘isbn-1234’, title=‘Some book’}

2014-06-05 12:15:43.784 … : isbn-1234 -->Book{isbn=‘isbn-1234’, title=‘Some book’}

2014-06-05 12:15:46.786 … : isbn-1234 -->Book{isbn=‘isbn-1234’, title=‘Some book’}

你会发现程序依次3s打印一行日志。这时还没开启缓存技术。

开启缓存技术

在程序的入口中加入@ EnableCaching开启缓存技术:

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

在需要缓存的地方加入@Cacheable注解,比如在getByIsbn()方法上加入@Cacheable(“books”),这个方法就开启了缓存策略,当缓存有这个数据的时候,会直接返回数据,不会等待去查询数据库。

    @Component
    public class SimpleBookRepository implements BookRepository {
    
        @Override
        @Cacheable("books")
        public Book getByIsbn(String isbn) {
            simulateSlowService();
            return new Book(isbn, "Some book");
        }
    
        // Don't do this at home
        private void simulateSlowService() {
            try {
                long time = 3000L;
                Thread.sleep(time);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
        }
    
    }

这时再启动程序,你会发现程序打印:

isbn-1234 -->Book{isbn=‘isbn-1234’, title=‘Some book’}
2017-04-23 18:17:09.479 INFO 8054 — [ main] forezp.AppRunner : isbn-4567 -->Book{isbn=‘isbn-4567’, title=‘Some book’}
2017-04-23 18:17:09.480 INFO 8054 — [ main] forezp.AppRunner : isbn-1234 -->Book{isbn=‘isbn-1234’, title=‘Some book’}
2017-04-23 18:17:09.480 INFO 8054 — [ main] forezp.AppRunner : isbn-4567 -->Book{isbn=‘isbn-4567’, title=‘Some book’}
2017-04-23 18:17:09.481 INFO 8054 — [ main] forezp.AppRunner : isbn-1234 -->Book{isbn=‘isbn-1234’, title=‘Some book’}
2017-04-23 18:17:09.481 INFO 8054 — [ main] forezp.AppRunner : isbn-1234 -->Book{isbn=‘isbn-1234’, title=‘Some book’}

只有打印前面2个数据,程序等了3s,之后的数据瞬间打印在控制台上了,这说明缓存起了作用。

源码下载:https://github.com/forezp/SpringBootLearning

参考资料

caching

Spring Boot 揭秘与实战(二) 数据缓存篇 - 快速入门


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文