service 层两个查询方法:
@Cacheable(value = "space", key = "#id", unless = "#result==null")
public Space searchOne(long id) {
return repository.findById(id).orElse(null);
}
public Space searchOneWithUser(long id) {
Space space = searchOne(id);
space.setCreator(userService.searchOne(space.getUserId()));
return space;
}
为什么调用第二个方法不走缓存? 缓存有数据还是从数据库里查,缓存没有数据,查出来后也不写到缓存里面。
1
CoderGeek 2020-08-27 10:30:01 +08:00 2
这个是基于 AOP 的动态代理实现,你内部引用不生效
1.放到外部的类调用 2.用 ApplicationContext.getBean 在调用 searchOne(id) |
2
wysnylc 2020-08-27 10:38:52 +08:00 2
https://www.jianshu.com/p/6534945eb3b5
JDK Dynamic Proxy 无法拦截 this,Spring 默认使用 JDK Dynamic Proxy,所以 Spring AOP 无法代理 this 所以 Spring Cache 缓存注解无效.解决方案为注入当前类的 bean 进行使用(但是有可能造成循环调用)或者拆分逻辑到另一个 services 题外话:你这不是 JPA 二级缓存而是 Spring Cache 自定义缓存,二级缓存是基于表的缓存 |
4
ixx 2020-08-27 10:49:17 +08:00
多说一句,有一道关于事务的面试题就是你这么写的,把缓存注解换成事务注解 原理是一样的 ,调用第二个不走事务
|
5
NULL2020 OP @wysnylc #2 我的理解,二级缓存就是查询缓存,你说的 [基于表的缓存] 好像第一次听说,有没有技术文章可以分享一下?
|
7
aragakiyuii 2020-08-27 10:52:42 +08:00
|
8
aragakiyuii 2020-08-27 10:57:04 +08:00
@aragakiyuii #7 extend -> extends
|
9
wysnylc 2020-08-27 12:17:04 +08:00
|
10
leafre 2020-08-27 15:21:25 +08:00
Space space = this.searchOne(id);
<aop:aspectj-autoproxy expose-proxy="true"/> |