Printemps cache @Cacheable méthode ignoré lorsqu'il est appelé à partir de l'intérieur de la même classe
Je suis en train d'appeler un @Cacheable
méthode à partir de l'intérieur de la même classe:
@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;
}
et en espérant que les résultats de findPersons
sont mis en cache, mais la @Cacheable
annotation est ignoré, et findPerson
méthode ont été exécutés à chaque fois.
Je fais quelque chose de mal ici, ou est-ce prévu?
- Question similaire: stackoverflow.com/questions/16899604/.... Voici une simple et bonne solution: stackoverflow.com/questions/16899604/...
Vous devez vous connecter pour publier un commentaire.
C'est à cause de la façon dont les procurations sont créés pour la manipulation de la mise en cache, de transaction liés à la fonctionnalité du Printemps. C'est une très bonne référence de comment le Printemps gère elle - Transactions, la mise en Cache et AOP: la compréhension de l'utilisation de proxy au Printemps
En bref, une auto d'appel ignore la dynamique de proxy et tout transversales qui concernent comme la mise en cache, transaction, etc, qui fait partie de la dynamique de procurations de la logique est également ignorés.
La solution est d'utiliser AspectJ moment de la compilation ou de temps de chargement de tissage.
((PersonService)AopContext.currentProxy())).findPerson(id)
proxy-target-class=true
ne fonctionnera pas, c'est juste les forces de la création de CGLIB en fonction des procurations, où la classe cible est sous-classé, mais encore s'enroule autour de l'objet traité par proxy - doncthis
dans le proxy de l'objet sera toujours résoudre le proxy de l'objet et de contourner le proxy. La seule solution est aspectj ou des appels via le proxy à travers((PersonService)AopContext.currentProxy())).findPerson(id)
Voici ce que je fais pour les petits projets de marginal, et l'utilisation de la méthode des appels au sein de la même classe. Dans le code de documentation est fortement advidsed, comme il peut sembler strage à des collègues. Mais il est facile de tester, simple, rapide à réaliser et de pièces de rechange moi la pleine soufflé AspectJ instrumentation. Cependant, pour plus d'utilisation intensive, je serais d'avis de la AspectJ solution.
@Cacheable
détails de mise en œuvre et les pièges... 🙂@Cacheable... find Person()
par@Autowired private PersonDao _personDao;
Pour toute personne utilisant la Graal Printemps Cache plugin, une solution de contournement décrite dans la documentation. J'ai eu ce problème sur un graal application, mais, malheureusement, l'on a accepté la réponse semble être inutilisable pour le Graal. La solution, c'est moche, à mon humble avis, mais il fonctionne.
L'exemple de code montre bien:
Il suffit de remplacer exampleService.cachedMethod() avec votre propre service et de la méthode.