本地缓存,之前一直用Guava Cache,最近spring-boot推荐使用Caffeine Cache。
主要的三种本地缓存性能对比:
简单几步,就可以在spring-boot中配置和使用Caffeine Cache:
1、引入依赖:
- <!-- local cache -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-cache</artifactId>
- </dependency>
- <dependency>
- <groupId>com.github.ben-manes.caffeine</groupId>
- <artifactId>caffeine</artifactId>
- </dependency>
2、配置:
有两种方法:
- application.yml配置文件中配置:
- 优点:简单
- 缺点:无法针对每个cache配置不同的参数,比如过期时长、最大容量
- 配置类中配置
- 优点:可以针对每个cache配置不同的参数,比如过期时长、最大容量
- 缺点:要写一点代码
2.1、配置文件中直接配置:
- spring:
- cache:
- type: CAFFEINE
- cache-names:
- - getPersonById
- - name2
- caffeine:
- spec: maximumSize=500,expireAfterWrite=5s
然后还要在主类中加上@EnableCaching注解:
- @SpringBootApplication
- @EnableScheduling
- @EnableCaching
- public class MySpringBootApplication
2.2、另外一种更灵活的方法是在配置类中配置:
- package com.xjj.config;
-
- import java.util.ArrayList;
- import java.util.concurrent.TimeUnit;
-
- import org.springframework.cache.CacheManager;
- import org.springframework.cache.annotation.EnableCaching;
- import org.springframework.cache.caffeine.CaffeineCache;
- import org.springframework.cache.support.SimpleCacheManager;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Primary;
-
- import com.github.benmanes.caffeine.cache.Caffeine;
-
-
- /**
- * Cache配置類,用于缓存数据
- * @author XuJijun
- *
- */
- @Configuration
- @EnableCaching
- public class CacheConfig {
-
- public static final int DEFAULT_MAXSIZE = 50000;
- public static final int DEFAULT_TTL = 10;
-
- /**
- * 定義cache名稱、超時時長(秒)、最大容量
- * 每个cache缺省:10秒超时、最多缓存50000条数据,需要修改可以在构造方法的参数中指定。
- */
- public enum Caches{
- getPersonById(5), //有效期5秒
- getSomething, //缺省10秒
- getOtherthing(300, 1000), //5分钟,最大容量1000
- ;
-
- Caches() {
- }
-
- Caches(int ttl) {
- this.ttl = ttl;
- }
-
- Caches(int ttl, int maxSize) {
- this.ttl = ttl;
- this.maxSize = maxSize;
- }
-
- private int maxSize=DEFAULT_MAXSIZE; //最大數量
- private int ttl=DEFAULT_TTL; //过期时间(秒)
-
- public int getMaxSize() {
- return maxSize;
- }
- public int getTtl() {
- return ttl;
- }
- }
-
- /**
- * 创建基于Caffeine的Cache Manager
- * @return
- */
- @Bean
- @Primary
- public CacheManager caffeineCacheManager() {
- SimpleCacheManager cacheManager = new SimpleCacheManager();
-
- ArrayList<CaffeineCache> caches = new ArrayList<CaffeineCache>();
- for(Caches c : Caches.values()){
- caches.add(new CaffeineCache(c.name(),
- Caffeine.newBuilder().recordStats()
- .expireAfterWrite(c.getTtl(), TimeUnit.SECONDS)
- .maximumSize(c.getMaxSize())
- .build())
- );
- }
-
- cacheManager.setCaches(caches);
-
- return cacheManager;
- }
-
- }
3、代码中使用:
- package com.xjj.service;
-
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.cache.annotation.Cacheable;
- import org.springframework.stereotype.Service;
-
- import com.xjj.dao.PersonDAO;
- import com.xjj.entity.Person;
-
- @Service
- public class PersonService {
- protected final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- @Autowired
- private PersonDAO personDao;
-
-
- /**
- * 根据id获取Person对象,使用缓存
- * @param id
- * @return Person对象
- */
- @Cacheable(value="getPersonById", sync=true)
- public Person getPersonById(int id){
- logger.debug("getting data from database, personId={}", id);
- return personDao.getPersonById(id);
- }
-
- }
4、测试:
- @Autowired
- PersonService personService;
-
- @Test
- public void localCacheTest() throws JsonProcessingException, InterruptedException{
- System.out.println("第一次:"); //从数据库中获取
- Person p = personService.getPersonById(2);
- logger.info("1st time: {}", objectMapper.writeValueAsString(p));
-
- System.out.println("第二次:"); //从缓存中获取
- p = personService.getPersonById(2);
- logger.info("2nd time: {}", objectMapper.writeValueAsString(p));
-
- Thread.sleep(5000);
-
- System.out.println("第三次:"); //5秒钟超时后,从数据库中获取
- p = personService.getPersonById(2);
- logger.info("3rd time: {}", objectMapper.writeValueAsString(p));
-
- System.out.println("第四次:"); //从缓存中获取
- p = personService.getPersonById(2);
- logger.info("4th time: {}", objectMapper.writeValueAsString(p));
-
- }
测试结果:
- 第一次:
- 2016-11-02 17:11:13,105:DEBUG main (PersonService.java:27) - getting data from database, personId=2
- 2016-11-02 17:11:13,150:INFO main (HikariDataSource.java:93) - HikariPool-1 - Started.
- 2016-11-02 17:11:13,523:DEBUG main (BaseJdbcLogger.java:145) - ==> Preparing: SELECT id, first_name AS firstName, last_name AS lastName, birth_date AS birthDate, sex, phone_no AS phoneNo FROM test.t_person WHERE id=?;
- 2016-11-02 17:11:13,554:DEBUG main (BaseJdbcLogger.java:145) - ==> Parameters: 2(Integer)
- 2016-11-02 17:11:13,572:TRACE main (BaseJdbcLogger.java:151) - <== Columns: id, firstName, lastName, birthDate, sex, phoneNo
- 2016-11-02 17:11:13,573:TRACE main (BaseJdbcLogger.java:151) - <== Row: 2, 八, 李, 2015-08-07, F, 13625896321
- 2016-11-02 17:11:13,582:DEBUG main (BaseJdbcLogger.java:145) - <== Total: 1
- 2016-11-02 17:11:13,665:INFO main (MySpringBootApplicationTests.java:149) - 1st time: {"id":2,"firstName":"八","lastName":"李","birthDate":1438876800000,"sex":"F","phoneNo":"13625896321"}
- 第二次:
- 2016-11-02 17:11:13,666:INFO main (MySpringBootApplicationTests.java:153) - 2nd time: {"id":2,"firstName":"八","lastName":"李","birthDate":1438876800000,"sex":"F","phoneNo":"13625896321"}
- 第三次:
- 2016-11-02 17:11:18,668:DEBUG main (PersonService.java:27) - getting data from database, personId=2
- 2016-11-02 17:11:18,669:DEBUG main (BaseJdbcLogger.java:145) - ==> Preparing: SELECT id, first_name AS firstName, last_name AS lastName, birth_date AS birthDate, sex, phone_no AS phoneNo FROM test.t_person WHERE id=?;
- 2016-11-02 17:11:18,670:DEBUG main (BaseJdbcLogger.java:145) - ==> Parameters: 2(Integer)
- 2016-11-02 17:11:18,671:TRACE main (BaseJdbcLogger.java:151) - <== Columns: id, firstName, lastName, birthDate, sex, phoneNo
- 2016-11-02 17:11:18,672:TRACE main (BaseJdbcLogger.java:151) - <== Row: 2, 八, 李, 2015-08-07, F, 13625896321
- 2016-11-02 17:11:18,672:DEBUG main (BaseJdbcLogger.java:145) - <== Total: 1
- 2016-11-02 17:11:18,673:INFO main (MySpringBootApplicationTests.java:159) - 3rd time: {"id":2,"firstName":"八","lastName":"李","birthDate":1438876800000,"sex":"F","phoneNo":"13625896321"}
- 第四次:
- 2016-11-02 17:11:18,674:INFO main (MySpringBootApplicationTests.java:163) - 4th time: {"id":2,"firstName":"八","lastName":"李","birthDate":1438876800000,"sex":"F","phoneNo":"13625896321"}
Perfect!!!
完整的源代码:https://github.com/xujijun/my-spring-boot
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。