Esiste un modo semplice per utilizzare l'annotazione Spring @Cacheable
con un bean non singleton (ad esempio con ambito sessione) e avere la cache con lo stesso ambito di detto bean?L'annotazione @Cacheable di Spring può avere lo stesso ambito del bean del metodo annotato?
Esempio:
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.context.SecurityContextHolder;
@Named
@Scope("session")
public class UserNameRetriever {
@Inject private UserDao userDao;
@Cacheable("userName")
public String getUserName() {
return userDao.getUserByLogin((String)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getName();
}
}
Idealmente, UserNameRetriever.getUserName()
sarebbe prendere il nome utente dal UserDao
una volta per sessione, ma questo codice in realtà memorizza nella cache di applicazione a livello.
Questo funziona, ma ha una perdita di memoria, senza ( \t \ @CacheEvict (value = "username", key = "# root.target") \t \ @PreDestroy \t pubblico cleanup void() {} \t Inoltre, ho deciso di non utilizzare @Cacheable dopo tutto, poiché non garantisce che il valore verrà calcolato una sola volta. –
Cosa intendi per perdita di memoria? Forse la tua cache è troppo grande. @Cacheable cercherà prima nella cache, quindi garantisce che il valore non verrà calcolato mentre è ancora nella cache. – sinuhepop
Si tratta di una perdita di memoria perché una volta terminata la sessione, il valore è ancora nella cache, ma non è possibile accedervi. @PreDestroy garantisce che il valore memorizzato nella cache venga rimosso quando termina la sessione. –