关于springboot使用ehcache的几点说明
昨晚在研究Spring对mybatis的二级缓存实现时,做到了对同一个方法中多次调用同一个sqlSession进行缓存.
但是今天突发奇想,做了一个测试,发现缓存失效了.
模拟测试背景:
Class A中两个方法fun1(),fun2().其中fun2()进行了缓存控制,在fun1()中调用fun2(),发现缓存失效.
在ehcache.xml中配置缓存:
<cache name="folder" maxElementsInMemory="1000" timeToLiveSeconds="5" timeToIdleSeconds="10" />
代码如下:
Service
public String getCloudList(long timeStamp, String folderId) { test(folderId); LocalDateTime now = LocalDateTime.now();//当前时间2018-04-27T10:37:04.412 System.out.println("1方法调用一次接口"+now); test(folderId); LocalDateTime now2 = LocalDateTime.now();//当前时间2018-04-27T10:37:04.412 System.out.println("2方法调用一次接口"+now2); return "s"; } @Cacheable(value = "folder",key = "#folderId") public void test(String folderId){ System.out.println("test"); }
Controlelr:
@GetMapping("/getAllCloudList")
public JSONObject getAllCloudList(HttpServletRequest request){
JSONObject json = new JSONObject();
long timeStamp = 1524798540;
String folderId = request.getParameter("folderId");
String res = userService.getCloudList(timeStamp, folderId);
json.put("data",res);
// JSONObject json = JSON.parseObject(res);
return json;
}
使用postman伪装请求,控制台打印结果入下:
test
1方法调用一次接口2018-04-27T13:33:59.725
test
2方法调用一次接口2018-04-27T13:33:59.725
test
1方法调用一次接口2018-04-27T13:34:00.438
test
2方法调用一次接口2018-04-27T13:34:00.438
test
1方法调用一次接口2018-04-27T13:34:01.752
test
2方法调用一次接口2018-04-27T13:34:01.752
可以发现每次请求,都执行设置了缓存的test方法.缓存失效.
原因:
Spring使用ehcache是利用了aop的动态代理.在同一个类中,fun1()调用fun2()仅仅是方法的内部调用,根本就没有走动态代理.
解决方法:
把test这个方法放在另一个类中,然后把这个类交给spring进行管理,使用自动注入,调用这个方法,就能让动态代理生效.
代码如下:
@Component public class EOUtil { @Cacheable(value = "folder", key = "#folderId") public void test(String folderId) { System.out.println("test"); } }
@Service("userService")
public class UserServiceImpl implements IUserService {
@Autowired
private EOUtil eoUtil;
@Override
public String getCloudList(long timeStamp, String folderId) {
eoUtil.test(folderId);
LocalDateTime now = LocalDateTime.now();//当前时间2018-04-27T10:37:04.412
System.out.println("1方法调用一次接口" + now);
eoUtil.test(folderId);
LocalDateTime now2 = LocalDateTime.now();//当前时间2018-04-27T10:37:04.412
System.out.println("2方法调用一次接口" + now2);
return "s";
}
}
再次伪装请求,查看执行结果:
test
1方法调用一次接口2018-04-27T13:48:42.199
2方法调用一次接口2018-04-27T13:48:42.200
1方法调用一次接口2018-04-27T13:48:43.215
2方法调用一次接口2018-04-27T13:48:43.215
1方法调用一次接口2018-04-27T13:48:44.090
2方法调用一次接口2018-04-27T13:48:44.090
1方法调用一次接口2018-04-27T13:48:45.005
2方法调用一次接口2018-04-27T13:48:45.005
在十秒内,多次调用,test方法只执行了一次,缓存是有效的.

浙公网安备 33010602011771号