Caffeine和Spring Boot集成
Caffeine是使用Java8對Guava緩存的重寫版本,在Spring Boot 2.0中將取代Guava。如果出現(xiàn)Caffeine溪北,CaffeineCacheManager將會自動配置。使用spring.cache.cache-names屬性可以在啟動時創(chuàng)建緩存,并可以通過以下配置進行自定義(按順序):
spring.cache.caffeine.spec: 定義的特殊緩存
com.github.benmanes.caffeine.cache.CaffeineSpec: bean定義
com.github.benmanes.caffeine.cache.Caffeine: bean定義
例如盲泛,以下配置創(chuàng)建一個foo和bar緩存,最大數(shù)量為500键耕,存活時間為10分鐘:
spring.cache.cache-names=foo,bar
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s
除此之外寺滚,如果定義了com.github.benmanes.caffeine.cache.CacheLoader,它會自動關(guān)聯(lián)到CaffeineCacheManager屈雄。由于該CacheLoader將關(guān)聯(lián)被該緩存管理器管理的所有緩存村视,所以它必須定義為CacheLoader<Object, Object>,自動配置將忽略所有泛型類型酒奶。
引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.6.0</version>
</dependency>
開啟緩存的支持
使用@EnableCaching注解讓Spring Boot開啟對緩存的支持
@SpringBootApplication
@EnableCaching// 開啟緩存蚁孔,需要顯示的指定
public class SpringBootStudentCacheCaffeineApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootStudentCacheCaffeineApplication.class, args);
}
}
配置文件
新增對緩存的特殊配置奶赔,如最大容量、過期時間等
spring.cache.cache-names=people
spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=10s,refreshAfterWrite=5s
如果使用了refreshAfterWrite配置還必須指定一個CacheLoader杠氢,如:
/**
* 必須要指定這個Bean站刑,refreshAfterWrite=5s這個配置屬性才生效
*
* @return
*/
@Bean
public CacheLoader<Object, Object> cacheLoader() {
CacheLoader<Object, Object> cacheLoader = new CacheLoader<Object, Object>() {
@Override
public Object load(Object key) throws Exception {
return null;
}
// 重寫這個方法將oldValue值返回回去,進而刷新緩存
@Override
public Object reload(Object key, Object oldValue) throws Exception {
return oldValue;
}
};
return cacheLoader;
}
Caffeine配置說明:
initialCapacity=[integer]: 初始的緩存空間大小
maximumSize=[long]: 緩存的最大條數(shù)
maximumWeight=[long]: 緩存的最大權(quán)重
expireAfterAccess=[duration]: 最后一次寫入或訪問后經(jīng)過固定時間過期
expireAfterWrite=[duration]: 最后一次寫入后經(jīng)過固定時間過期
refreshAfterWrite=[duration]: 創(chuàng)建緩存或者最近一次更新緩存后經(jīng)過固定的時間間隔鼻百,刷新緩存
weakKeys: 打開key的弱引用
weakValues:打開value的弱引用
softValues:打開value的軟引用
recordStats:開發(fā)統(tǒng)計功能
注意:
expireAfterWrite和expireAfterAccess同事存在時绞旅,以expireAfterWrite為準。
maximumSize和maximumWeight不可以同時使用
weakValues和softValues不可以同時使用
示例代碼
/**
* @author yuhao.wang
*/
@Service
public class PersonServiceImpl implements PersonService {
private static final Logger logger = LoggerFactory.getLogger(PersonServiceImpl.class);
@Autowired
PersonRepository personRepository;
@Override
@CachePut(value = "people", key = "#person.id")
public Person save(Person person) {
Person p = personRepository.save(person);
logger.info("為id温艇、key為:" + p.getId() + "數(shù)據(jù)做了緩存");
return p;
}
@Override
@CacheEvict(value = "people")//2
public void remove(Long id) {
logger.info("刪除了id因悲、key為" + id + "的數(shù)據(jù)緩存");
//這里不做實際刪除操作
}
/**
* Cacheable
* value:緩存key的前綴。
* key:緩存key的后綴勺爱。
* sync:設(shè)置如果緩存過期是不是只放一個請求去請求數(shù)據(jù)庫晃琳,其他請求阻塞,默認是false琐鲁。
*/
@Override
@Cacheable(value = "people", key = "#person.id", sync = true)
public Person findOne(Person person, String a, String[] b, List<Long> c) {
Person p = personRepository.findOne(person.getId());
logger.info("為id卫旱、key為:" + p.getId() + "數(shù)據(jù)做了緩存");
return p;
}
@Override
@Cacheable(value = "people1")//3
public Person findOne1() {
Person p = personRepository.findOne(2L);
logger.info("為id、key為:" + p.getId() + "數(shù)據(jù)做了緩存");
return p;
}
@Override
@Cacheable(value = "people2")//3
public Person findOne2(Person person) {
Person p = personRepository.findOne(person.getId());
logger.info("為id绣否、key為:" + p.getId() + "數(shù)據(jù)做了緩存");
return p;
}
}