1. 程式人生 > >spring cache快取配置

spring cache快取配置

本文介紹如何在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);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在需要快取的地方加入@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,之後的資料瞬間列印在控制檯上了,這說明快取起了作用。