我试图调用@Cacheable
从同一个类中的方法:
@Cacheable(value = "defaultCache", key = "#id")
public Person findPerson(int id) {
return getSession().getPerson(id);
}
public List<Person> findPersons(int[] ids) {
List<Person> list = new ArrayList<Person>();
for (int id : ids) {
list.add(findPerson(id));
}
return list;
}
并希望从结果findPersons
缓存为好,但@Cacheable
注释被忽略,并且findPerson
得到了每次执行的方法。
我在这里做得不对,或这是故意的吗?
这是因为代理是在春季处理缓存,交易相关功能创建的方式。 这是Spring是如何处理它一个很好的参考- 交易,缓存和AOP:在春天的了解代理的使用
简言之,自呼叫绕过动态代理和任何横切关注点像缓存,交易等,这是动态代理逻辑的一部分也被绕过。
解决方法是使用AspectJ的编译时间或加载时编织。
下面是同一类的我的小项目做的唯一方法边际使用什么叫。 在代码文档强烈advidsed,因为它可能看起来strage给同事。 但它容易测试,简单,快速的实现和备件我完全成熟的AspectJ仪器。 然而,对于更大量使用我劝告AspectJ的解决方案。
@Service
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
class PersonDao {
private final PersonDao _personDao;
@Autowired
public PersonDao(PersonDao personDao) {
_personDao = personDao;
}
@Cacheable(value = "defaultCache", key = "#id")
public Person findPerson(int id) {
return getSession().getPerson(id);
}
public List<Person> findPersons(int[] ids) {
List<Person> list = new ArrayList<Person>();
for (int id : ids) {
list.add(_personDao.findPerson(id));
}
return list;
}
}
对于使用Grails的弹簧缓存插件任何人, 一种解决方法是在文档中的描述 。 我有一个Grails应用这个问题,但不幸的是公认的答案似乎是不可用于Grails的。 该解决方案是丑陋的,恕我直言,但它的作品。
该代码示例演示得好:
class ExampleService {
def grailsApplication
def nonCachedMethod() {
grailsApplication.mainContext.exampleService.cachedMethod()
}
@Cacheable('cachedMethodCache')
def cachedMethod() {
// do some expensive stuff
}
}
只需用自己的服务和方法取代exampleService.cachedMethod()。
文章来源: Spring cache @Cacheable method ignored when called from within the same class