赞
踩
SpringBoot 3.1中开始对缓存提供支持,核心思想是对方法的缓存,当开发者调用一个方法是,将方法的数和返回值作为Key/Value形式缓存起来。再次调用该方法时,如果缓存中有数据,就从缓存中直接拿取数据,否则再去执行该方法,但是,SpringBoot并未提供缓存的实现,而是提供一套缓存的API,使开发者可以自由的选择选择缓存的实现方法,SpringBoot支持的缓存有一下几种:
JCache(JSP-107)
EhCahe 2.x
Hazelcast
Infinispan
Couchbase
Redis
Caffeine
Simple
本章我们将介绍EhCahe 2.x 和 Redis,由于Spring早已将缓存领域统一,因此无论使用哪种缓存实现,不同的只是缓存配置,一般使用的缓存注解都是一致的(Spring的缓存注解和各种缓存实现的关系就像JDBC和各种数据库驱动的关系一样)
EhCahe 2.x 缓存在java开发领域早已久负盛名,在SpringBoot中,值需要一个配置文件就可以将EhCahe集成到项目中,EhCahe 2.x 操作步骤如下:
1. 创建项目添加缓存依赖
创建SpringBoot项目,添加spring-boot-starter-cache 依赖以及EhCahe 依赖,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. 添加缓存配置文件
如果EhCahe的缓存存在,并且classpath下有一个名为ehcache.xml的EhCahe文件,那么EhCacheCacheManager将会自动作为缓存的实现,因此,在resources目录下创建ehcache.xml文件作为EhCahe缓存的配置文件,代码如下:
<eacache> <diskStore path="java.io.temdir/cache"/> <defaultCache maxElemensInMemory="10000" eternal="false" timeToIdleSeconds="120" timeLiveleSeconds="120" overflowTpDisk="false" diskPersistent="false" diskExpirtyThreadIntervalSeconds="120"/> <cache name="book_cache" maxElemensInMemory="10000" eternal="true" timeToIdleSeconds="120" timeLiveleSeconds="120" overflowTpDisk="true" diskPersistent="true" diskExpirtyThreadIntervalSeconds="600"/> <eacache>
这是一个常规的EhCahe配置文件,提供了两个缓存策略一个是默认的,另一个则是book_cache。其中,name表示缓存名称;maxElemensInMemory 表示缓存的最大个数;eternal表示缓存对象师傅永久有效,一旦设置了永久有效,timeoyt将不起作用;timeToIdleSeconds 表示缓存对象在失效前的闲置时间(单位:秒) 当eternal=false 对象不是永久有效时该属性才会生效;timeLiveleSeconds 表示缓存对象在失效前允许存活的时间(单位:秒),当eternal=false 对象不是永久有效,该属性才会生效;overflowTpDisk标书内存中的数量达到maxElemensInMemory时,EhCahe是否将数据写到磁盘中;diskExpirtyThreadIntervalSeconds表示磁盘失效的运行时间隔,还有好多的属性,这里就不一一介绍了,另外,如果开发者想自定义EhCahe配置文件的名称和位置,可以在application.properties中配置:
spring.cache.ehcache.config=classpath:config/another-config.xml
3. 开启缓存
在项目的入口类上添加上@EnableCaching注解开启缓存,代码如下:
@Spring BootApplication
@EnableCaching
public class CacheApplicatiion{
public static void main (String[] args){
SpringApplication.run(CacheApplication.class, args);
}
}
4. 创建BookDao
创建Book实体类,代码如下:
public class Book implements Serializable{
private Integer id;
private String name;
private String auyhor;
// 省略get/set
}
5. 创建BookService
创建BookService类和BookDao,代码如下:
@Repository @CacheConfig(cacheNames = "book_cache") public class BookDao{ @Cacheable public Book getBookById(Integer id){ System.out.println(getBookBuId); Book book = new Book(); book,setid(id); book.setName("肖申克的救赎"); book.author("斯蒂芬·埃德温·金"); return book; } @CachePut(key = "#book.id") public Book updateBookById(Book book){ System.out.println(updateBookBuId); book.setName("肖申克的救赎2"); return book; } @CacheEvict(key = "#id") public void deleteBookById(Integer id){ System.out.println(deleteBookBuId); } }
以上的实体类和Dao层以及Service层不多做解释;
使用root对象生成key,见下表:
| 属性名称 | 属性描述 | 用法实例 | methodName | 当前方法名 | #root.methodName | method | 当前方法对象 | #root.method.name | cache | 当前方法使用的缓存 | #root.cache[0].name | target | 当前被调用的对象 | #root.target | targetClass | 当前被调用对象的class | #root.targetClass | args | 当前方法参数数据 | #root.args[0]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
如果这些key不能满足开发需求,也可以自定义缓存key的生成器KeyCenerator 代码如下:
@Component
public class MyKeyCenerator implements KeyCenerator{
@Override
public Object generate(Object target, Methor methor, Object... params){
return Arrays.toString(params);
}
}
@Service @CacheConfig(cacheName = "book_cache") public class BookDao{ @Autowired MyKeyCenerator myKeyCenerator; @Cacheable(keyCenerator = "myKeyCenerator") public Book getBookById(Integer id){ System.out.println(getBookBuId); Book book = new Book(); book,setid(id); book.setName("肖申克的救赎3"); book.author("斯蒂芬·埃德温·金"); return book; } }
代码解释
自定义MyKeyCenerator实现KeyCenerator接口,当然实现该接口中的generate方法,该方法的三个参数分别是当前对象,当前请求的方法以及方法的参数,也可以根据这些信息组成一个新的key返回返回值就是缓存的key,第13行在@Cacheable注解中引用MyKeyCenerator即可;
第13行@CachePut 注解般用 于数据更新方法上, 与@Cacheable注解不同,添加了第13行@CachePut 注解般用 于数据更新方法上, 与@Cacheable注解不同,添加了后将方法的执行结果缓存起来,如果该key对应的数据已经被缓存起来了,就会覆盖之前的数据,这样可以避免再次加载数据时获取到脏數据.同时,@CachePut具有和Cacheable类似的属性,这里不再赘述。
第19行@CacheEvict注解-般用于删除方法上,表示移除一个她y对应的缓存CatheErie注解有两个特殊的属性: alEntries和bfrelnvocation,其中lnlries表示是否将所有的缓存数据都移除,默认为false, beforeInvocation表示是否在方法执行之前移除缓存中的数据,默认为false, 即在方法执行之后移除缓存中的数据。
6. 创建测试类
创建测试类,对service层的代码进行测试,代码如下:
@RunWith(SpringRunner.class) @Spring BootTest public class CacheApplicationTeats{ @Autowired BookDao bookDao; @Text public void contextLoads(){ bookDao.getBookById(1); bookDao.getBookById(1); bookDao.deleteBookById(1); Book book = bookDao.getBookById(1); System.out.println("book:" + book); Book book1 = new Book(); book1.setName("肖申克的救赎"); book1.setauthor("斯蒂芬·埃德温·金"); book1.setId(1); bookDao.updateBookById(book1); Book book2 = bookDao.getBookById(1); System.out.println("book2:" + book2); } }
执行会在控制台将你在方法里存储的值输出
一开始执行 了两个查询,但是查询方法只打印了一次,因为第二次使用了缓存。接下来执行了删除方法,删除方法执行完之后再次执行查询,查询方法又被执行了,因为在删除方法中缓存已经被删除了。再接下来执行更新方法,更新方法中不仅更新数据,也更新了缓存,所以在最后的查询方法中,查询方法日志没打印,说明该方法没执行,而是使用了缓存中的数据,而缓存中的数据已经被更新了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。