一、简介
在开发过程中,往往需要对数据进行缓存。spring cache是spring的缓存管理方式,
默认的缓存实现是org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean,
其实也就是ConcurrentHashMap,也就是内存缓存。对数据量少且访问频繁的数据,可以采用这种方法进行数据缓存。
本文主要以默认缓存实现为例进行介绍。
二、缓存配置添加
缓存配置添加有两种,即xml方式和java注解方式,java注解方式与xml方式的内容是一样的,只是形式变了,同学们可二选一,
1、xml配置方式如下:
a) 在配置文件中添加注解驱动的配置,即
<cache:annotation-driven />b)添加缓存管理器,内部定义缓存实现方式,可指定多个,每种缓存方式可自定义名称,如
id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
name="caches">
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default" />
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="mycache" />
xml完整的配置如下:
xml version="1.0" encoding="UTF-8"?>2、java配置方式如下:xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd "> <context:component-scan base-package="com.dragon.study" /> <cache:annotation-driven /> id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> name="caches"> class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default" /> class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="mycache" />
@Configuration @ComponentScan("com.dragon.study") @EnableCaching public class SpringConfig { @Bean public SimpleCacheManager simpleCacheManager(){ SimpleCacheManager simpleCacheManager = new SimpleCacheManager(); Set三、缓存的使用cacheSet = new HashSet<>(); cacheSet.add(defaultCache().getObject()); cacheSet.add(myCache().getObject()); simpleCacheManager.setCaches(cacheSet); return simpleCacheManager; } @Bean("default") ConcurrentMapCacheFactoryBean defaultCache(){ return new ConcurrentMapCacheFactoryBean(); } @Bean("myCache") ConcurrentMapCacheFactoryBean myCache(){ return new ConcurrentMapCacheFactoryBean(); } }
1、添加缓存
在方法上,使用注解@Cacheable进行缓存,注解内的值有:
value: 缓存实现的名称,如上述定义的default;
key:缓存的key,可使用spring EL 表达式进行自定义,访问方法的参数;
condition:表示在指定条件下才缓存,同样可以使用spring EL 表达式;
实例如
@Cacheable(value = "default",key="'id_'+#id",condition = "#id<3") public Student getStudent(Integer id) {}
2、缓存更新
在方法,使用注解@CachePut进行缓存更新或者添加新值,注解内值 有:
value: 缓存实现的名称,如上述定义的default;
key:缓存的key,可使用spring EL 表达式进行自定义,访问方法的参数;
condition:表示在指定条件下才缓存更新,同样可以使用spring EL 表达式;
实例如:@CachePut(value = "default",key="'id_'+#stu.getId()") public Student updateStudent(Student stu){}3、缓存删除
在方法,使用注解@CacheEvict进行缓存更新,注解内值 有:
value: 缓存实现的名称,如上述定义的default;
key:缓存的key,可使用spring EL 表达式进行自定义,访问方法的参数;
condition:表示在指定条件下才缓存删除,同样可以使用spring EL 表达式;
allEntries:表示删除所有的缓存(指定的缓存实现),默认值为false, 其中true表示删除所有的,false表示不删除所有的;
beforeInvocation: 是否在方法执行前清空缓存,默认值为false;
实例如:
@CacheEvict(value = "default",key="'id_'+#id") public void deleteStudent(Integer id){}
@CacheEvict(value = "default",allEntries = true) public void deleteAllStudent(){}四、完整实例
1、添加maven依赖
2、服务实现org.springframework spring-core 4.3.4.RELEASE org.springframework spring-beans 4.3.4.RELEASE org.springframework spring-context 4.3.4.RELEASE org.springframework spring-context-support 4.3.4.RELEASE org.springframework spring-aop 4.3.4.RELEASE org.springframework spring-asm 3.1.4.RELEASE org.springframework spring-aspects 4.3.4.RELEASE org.springframework spring-expression 4.3.4.RELEASE cglib cglib 3.2.4
public interface StudentService { public Student getStudent(Integer id); public Student updateStudent(Student stu); public void deleteStudent(Integer id); public void deleteAllStudent(); }
@Service("studentService") public class StudentServiceImpl implements StudentService { @Cacheable(value = "default",key="'id_'+#id",condition = "#id<3") public Student getStudent(Integer id) { Student stu = new Student(); stu.setId(id); stu.setName("apple"); return stu; } @CachePut(value = "default",key="'id_'+#stu.getId()") public Student updateStudent(Student stu){ System.out.println("update stu"); return stu; } @CacheEvict(value = "default",key="'id_'+#id") public void deleteStudent(Integer id){ System.out.println("delete student "+id); } @CacheEvict(value = "default",allEntries = true) public void deleteAllStudent(){ System.out.println("delete all student "); } }3、测试
public class SpringAnnotationMain { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class); StudentService studentService = (StudentService) ac.getBean("studentService"); Integer id =1; Student stu = studentService.getStudent(id); //新建缓存 stu = studentService.getStudent(id); //从缓存中取 stu.setName("banana"); //重新设置值 studentService.updateStudent(stu); //更新缓存 stu = studentService.getStudent(id); //从缓存中取出新值 stu = new Student(); //新实例 stu.setId(0); studentService.updateStudent(stu); //用新建的实例进行更新,会新建缓存 stu = studentService.getStudent(0); //从缓存中取 studentService.deleteStudent(id); // 删除缓存 stu = studentService.getStudent(id); //再次新建缓存 id=2; stu = studentService.getStudent(id); //新建缓存 studentService.deleteAllStudent(); //删除所有缓存 id=1; stu = studentService.getStudent(id); //因所有缓存被前一步清除,会新建缓存 id=5; stu = studentService.getStudent(id); //不会新建缓存 因为设置了缓存条件必须小于3 stu = studentService.getStudent(id); //因没有缓存,不会从缓存中取 Assert.notNull(stu); } }
最后,提醒下,基于注解的spring cache开发,是基于spring aop基础上,内部调用仍需要进行相关处理,、
相关知识请查看本博客的spring aop开发。