上一篇自定义了缓存的实现,不用任何第三方的组件来实现某种对象的内存缓存,这一篇结合结合上一篇的例子,简单的实现了spring cache,cache使用了spring缺醒的实现,包括缓存的查询、缓存的清空等。源码下载
首先,引入spring需要的jar包。如下图所示:
实体类既是上一篇中的user类,服务类:
package com.spricache.service; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import com.spricache.entity.User; public class UserService { // 使用了一个缓存名叫 userCache ,value是user对象,key是userName @Cacheable(value="userCache") public User getUserByName(String userName) { // 方法内部实现不考虑缓存逻辑,直接实现业务 System.out.println("数据库查询"+userName); return getFromDB(userName); } // 清空 userCache 缓存 public void updateAccount(Account account) //以这里还需要从参数 user 对象中获取 name 的值来作为 key,前面的 # 号代表这是一个 SpEL 表达式,此表达式可以遍历方法的参数对象 @CacheEvict(value="userCache",key="#user.getUserName()") public void updateUser(User user) { updateDB(user); } // 清空 accountCache 缓存 @CacheEvict(value="userCache",allEntries=true) public void reload() { } private void updateDB(User user) { System.out.println("更新数据库"+user.getUserName()); } //模拟数据库查询 private User getFromDB(String acctName) { System.out.println("正在从数据库查询"+acctName); return new User(acctName); } }
spring.xml的配置内容
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!--支持缓存的配置项 ,这个配置项缺省使用了一个名字叫 cacheManager 的缓存管理器--> <cache:annotation-driven /> <!--配置service变量 --> <bean id="userService" class="com.spricache.service.UserService"/> <!-- generic cache manager --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default" /> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="userCache" /> </set> </property> </bean> </beans>
下边是测试类:
package com.spricache.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spricache.entity.User; import com.spricache.service.UserService; public class Test { public static void main(String args[]){ // 加载 spring 配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("com/spricache/config/spring-cache.xml"); UserService userService = (UserService) context.getBean("userService"); // 第一次查询,应该走数据库 System.out.println("第一次查询"); userService.getUserByName("helloSpringCache"); // 第二次查询,应该不查数据库,直接返回缓存的值 System.out.println("第二次查询"); userService.getUserByName("helloSpringCache"); System.out.println(); //更新某个记录的缓存,首先构造两个账号记录,然后记录到缓存中 System.out.println("开始测试清空缓存"); User user1 = userService.getUserByName("cache1"); User user2 = userService.getUserByName("cache2"); //开始更新其中一个 user1.setId(1212); userService.updateUser(user1); // 因为被更新了,所以会查询数据库 userService.getUserByName("cache1"); // 没有更新过,应该走缓存 userService.getUserByName("cache1"); // 再次查询,应该走缓存 userService.getUserByName("cache1"); // 更新所有缓存 userService.reload(); // 应该会查询数据库 userService.getUserByName("cache2"); // 应该会查询数据库 userService.getUserByName("cache1"); // 应该走缓存 userService.getUserByName("cache2"); // 应该走缓存 userService.getUserByName("cache1"); } }