Aller au contenu principal

Rechercher sur CooLWJ

选择搜索范围,输入关键词后按回车。

Langue

Présentation de l’utilisation de Spring Cache

I. Solution de mise en cache fondée sur SpringCache

1.1 Présentation de SpringCache

springcache a été introduit avec la version spring3.1. Il encapsule et abstrait l’utilisation du cache : il suffit d’ajouter des annotations aux méthodes pour obtenir les résultats mis en cache. C’est précisément grâce aux annotations qu’il résout le problème du couplage entre le code métier et le code de gestion du cache : le code existant peut ainsi prendre immédiatement en charge le cache sans modification intrusive du code métier, ce qui permet aux développeurs d’utiliser le cache de façon transparente.

1.2 Présentation de SpringCache

Il existe de nombreux frameworks de cache, chacun ayant ses avantages, comme Redis, Memcached, Guava, Caffeine, etc.
Si notre programme veut utiliser le cache, il doit se coupler à ces frameworks. Des architectes avisés utilisent déjà les interfaces pour réduire ce couplage : grâce à l’abstraction et au polymorphisme de la programmation orientée objet, ils séparent le code métier des frameworks concrets.
Mais nous devons toujours appeler explicitement dans le code les interfaces et les méthodes liées au cache, y insérer des données au bon moment et y lire des données au bon moment. Réfléchissons「AOP」comme cas d’utilisation, n’est-ce pas précisément une tâche naturellement faite pour l’AOP ?
Depuis Spring 3.1, la prise en charge du cache par annotations est proposée, à l’image de la gestion des transactions avec l’annotation [@Transactional](/Transactional ), ainsi qu’une abstraction du cache ; auparavant, cela était généralement réalisé au moyen de l’AOP.
Avantages de Spring Cache :

  • Fournir une abstraction de base du cache pour faciliter le passage d’une implémentation sous-jacente de cache à une autre;

  • L’annotation Cache permet, à la manière des transactions, d’appliquer de façon transparente la logique de cache à notre code métier, tout en nécessitant moins de code ;

  • Permet également d’annuler automatiquement les modifications du cache lors de l’annulation d’une transaction ;

  • Prend en charge une logique de cache relativement complexe ;

Identifiant technique de Spring Cache

1.3 Conception fondamentale de Spring Cache

Depuis Spring 3.1, Spring Cache, l’abstraction de cache de Spring, a été introduit. En définissant org.springframework.cache.Cache et org.springframework.cache.CacheManager interface pour unifier les différentes technologies de cache et prend en charge les annotations JCache afin de simplifier le développement.
L’interface Cache définit le contrat des composants de cache et regroupe les différentes opérations sur le cache. Spring propose pour cette interface diverses xxxCache implémentation de : RedisCache , EhCacheCache , ConcurrentMapCache etc.
Examinons une partie du code source pour comprendre l’interface Cache et CacheManager interface.

Interface Cache

public interface Cache {     //Cache名称     String getName();      //Cache负责缓存的对象     Object getNativeCache();      /**      * 获取key对应的ValueWrapper      * 没有对应的key,则返回null      * key对应的value是null,则返回null对应的ValueWrapper      */     @Nullable     Cache.ValueWrapper get(Object key);      //返回key对应type类型的value     @Nullable     <T> T get(Object key, @Nullable Class<T> type);      //返回key对应的value,没有则缓存Callable::call,并返回     @Nullable     <T> T get(Object key, Callable<T> valueLoader);      //缓存目标key-value(替换旧值),不保证实时性     void put(Object key, @Nullable Object value);      //插入缓存,并返回该key对应的value;先调用get,不存在则用put实现     @Nullable     default Cache.ValueWrapper putIfAbsent(Object key, @Nullable Object value) {         Cache.ValueWrapper existingValue = this.get(key);         if (existingValue == null) {             this.put(key, value);         }          return existingValue;     }      //删除缓存,不保证实时性     void evict(Object key);      //立即删除缓存:返回false表示剔除前不存在制定key活不确定是否存在;返回true,表示该key之前存在     default boolean evictIfPresent(Object key) {         this.evict(key);         return false;     }      //清除所有缓存,不保证实时性     void clear();      //立即清楚所有缓存,返回false表示清除前没有缓存或不能确定是否有;返回true表示清除前有缓存     default boolean invalidate() {         this.clear();         return false;     }      public static class ValueRetrievalException extends RuntimeException {         @Nullable         private final Object key;          public ValueRetrievalException(@Nullable Object key, Callable<?> loader, Throwable ex) {             super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex);             this.key = key;         }          @Nullable         public Object getKey() {             return this.key;         }     }      //缓存值的一个包装器接口,实现类为SimpleValueWrapper     @FunctionalInterface     public interface ValueWrapper {         @Nullable         Object get();     } }

On constate que l’interface Cache abstrait les opérations de cache telles que get, put et evict.

Classe abstraite AbstractValueAdaptingCache

public abstract class AbstractValueAdaptingCache implements Cache {      //是否允许Null值     private final boolean allowNullValues;      protected AbstractValueAdaptingCache(boolean allowNullValues) {         this.allowNullValues = allowNullValues;     }      public final boolean isAllowNullValues() {         return this.allowNullValues;     }      @Nullable     public ValueWrapper get(Object key) {         return this.toValueWrapper(this.lookup(key));     }      @Nullable     public <T> T get(Object key, @Nullable Class<T> type) {         //查询到的缓存值做fromStoreValue转换         Object value = this.fromStoreValue(this.lookup(key));         //转换后非null值且无法转换为type类型则抛出异常         if (value != null && type != null && !type.isInstance(value)) {             throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value);         } else {             return value;         }     }      //从缓存中获取key对应的value,子类实现     @Nullable     protected abstract Object lookup(Object key);      //对于从缓存中获取的值,允许为空且值为NullValue时,处理为null     @Nullable     protected Object fromStoreValue(@Nullable Object storeValue) {         return this.allowNullValues && storeValue == NullValue.INSTANCE ? null : storeValue;     }      //对于要插入缓存的null值,在允许null值的情况下处理为NullValue;否则抛出异常IllegalArgumentException     protected Object toStoreValue(@Nullable Object userValue) {         if (userValue == null) {             if (this.allowNullValues) {                 return NullValue.INSTANCE;             } else {                 throw new IllegalArgumentException("Cache '" + this.getName() + "' is configured to not allow null values but null was provided");             }         } else {             return userValue;         }     }      //get操作依据,查询到缓存值非null,则fromStoreValue转换后包装成SimpleValueWrapper返回     @Nullable     protected ValueWrapper toValueWrapper(@Nullable Object storeValue) {         return storeValue != null ? new SimpleValueWrapper(this.fromStoreValue(storeValue)) : null;     } }

Classe abstraite AbstractValueAdaptingCache implémente l’interface Cache et abstrait principalement la logique de traitement des valeurs NULL.

  • allowNullValues L’attribut indique si la mise en cache des valeurs NULL est autorisée

  • fromStoreValue de la méthode pour traiter les valeurs NULL get opération, dans la propriété allowNullValues Lorsque la valeur est true, traiter NullValue comme NULL

  • toStoreValue méthode pour traiter les valeurs NULL put opération, dans la propriété allowNullValues vaut true, traiter NULL comme NullValue ; sinon, lever une exception

  • toValueWrapper la méthode fournit Cache dans l’interface get l’implémentation par défaut de la méthode lit la valeur dans le cache, puis passe par fromStoreValue converti, puis finalement encapsulé sous forme de SimpleValueWrapper Retour

  • ValueWrapper get(Object key) et T get(Object key, @Nullable Classtype) méthode implémentée à partir de la méthode ci-dessus

  • ValueWrapper get(Object key) et @Nullable Classtype) méthode implémentée à partir de la méthode ci-dessus

  • lookup La méthode abstraite permet aux sous-classes d’obtenir la véritable valeur mise en cache

ConcurrentMapCache

public class ConcurrentMapCache extends AbstractValueAdaptingCache {     private final String name;     //定义ConcurrentMap缓存     private final ConcurrentMap<Object, Object> store;     //如果要缓存的是值对象的copy,则由此序列化代理类处理     @Nullable     private final SerializationDelegate serialization;      public ConcurrentMapCache(String name) {         this(name, new ConcurrentHashMap(256), true);     }      //默认允许处理null     public ConcurrentMapCache(String name, boolean allowNullValues) {         this(name, new ConcurrentHashMap(256), allowNullValues);     }      //默认serialization = null     public ConcurrentMapCache(String name, ConcurrentMap<Object, Object> store, boolean allowNullValues) {         this(name, store, allowNullValues, (SerializationDelegate)null);     }      protected ConcurrentMapCache(String name, ConcurrentMap<Object, Object> store, boolean allowNullValues, @Nullable SerializationDelegate serialization) {         super(allowNullValues);         Assert.notNull(name, "Name must not be null");         Assert.notNull(store, "Store must not be null");         this.name = name;         this.store = store;         this.serialization = serialization;     }      //serialization不为空,缓存值对象的copy     public final boolean isStoreByValue() {         return this.serialization != null;     }      public final String getName() {         return this.name;     }      public final ConcurrentMap<Object, Object> getNativeCache() {         return this.store;     }      //实现lookup:store#get     @Nullable     protected Object lookup(Object key) {         return this.store.get(key);     }      //基于ConcurrentMap::computeIfAbsent方法实现;get和put的值由fromStoreValue和toStoreValue处理Null     @Nullable     public <T> T get(Object key, Callable<T> valueLoader) {         return this.fromStoreValue(this.store.computeIfAbsent(key, (k) -> {             try {                 return this.toStoreValue(valueLoader.call());             } catch (Throwable var5) {                 throw new ValueRetrievalException(key, valueLoader, var5);             }         }));     }      public void put(Object key, @Nullable Object value) {         this.store.put(key, this.toStoreValue(value));     }      @Nullable     public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {         Object existing = this.store.putIfAbsent(key, this.toStoreValue(value));         return this.toValueWrapper(existing);     }      public void evict(Object key) {         this.store.remove(key);     }      public boolean evictIfPresent(Object key) {         return this.store.remove(key) != null;     }      public void clear() {         this.store.clear();     }      public boolean invalidate() {         boolean notEmpty = !this.store.isEmpty();         this.store.clear();         return notEmpty;     }      protected Object toStoreValue(@Nullable Object userValue) {         Object storeValue = super.toStoreValue(userValue);         if (this.serialization != null) {             try {                 return this.serialization.serializeToByteArray(storeValue);             } catch (Throwable var4) {                 throw new IllegalArgumentException("Failed to serialize cache value '" + userValue + "'. Does it implement Serializable?", var4);             }         } else {             return storeValue;         }     }      protected Object fromStoreValue(@Nullable Object storeValue) {         if (storeValue != null && this.serialization != null) {             try {                 return super.fromStoreValue(this.serialization.deserializeFromByteArray((byte[])((byte[])storeValue)));             } catch (Throwable var3) {                 throw new IllegalArgumentException("Failed to deserialize cache value '" + storeValue + "'", var3);             }         } else {             return super.fromStoreValue(storeValue);         }     } }

ConcurrentMapCache hérite de la classe abstraite AbstractValueAdaptingCache ,est l’implémentation de cache par défaut de Spring. Elle permet de mettre en cache des copies des objets, la sérialisation étant assurée par SerializationDelegate serialization ; sa valeur par défaut est null, ce qui correspond à une mise en cache par référence. Les opérations de cache reposent sur la classe de base AbstractValueAdaptingCache pour la gestion des valeurs null, qui sont autorisées par défaut.

CacheManager

public interface CacheManager {     @Nullable     //获取指定name的Cache,可能延迟创建     Cache getCache(String name);      //获取当前CacheManager下的Cache name集合     Collection<String> getCacheNames(); }

CacheManager Gère un ensemble de Cache selon name. Bien entendu, CacheManager possède également de nombreuses classes d’implémentation, comme ConcurrentMapCacheManager 、 AbstractCacheManager et SimpleCacheManager ,ces xxxCacheManager Ces classes servent toutes à définir les règles de gestion du cache ; nous n’approfondirons donc pas ce sujet ici.

II Utilisation de SpringCache

2.1 Comment l’utiliser

Spring Cache est précisément un tel cadre. Il s’appuie sur l’AOP pour proposer une mise en cache fondée sur des annotations et fournit une abstraction adaptée : le code métier n’a pas à se préoccuper du système de cache sous-jacent. Il suffit d’ajouter une annotation pour activer la mise en cache.

Ajouter les dépendances

<!--springboot的cache支持--> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-cache</artifactId> </dependency>  <!--配置拓展还需添加的依赖--> <dependency>   <groupId>com.github.ben-manes.caffeine</groupId>   <artifactId>caffeine</artifactId>   <version>2.9.2</version> </dependency>

Configuration du cache

Ajouter l’annotation @EnableCaching à la classe de démarrage Application

@SpringBootApplication     @MapperScan("com.xxxx.dao")     @EnableCaching     public class AxxxxApplication {          public static void main(String[] args) {             SpringApplication.run(AxxxxApplication.class, args);         }      }

Configurer le type de cache ; nous présentons ici principalement le cache local

//方式一:ConcurrentMapCache (不好设置过期时间) @Configuration public class SpringCachingConfig {        @Bean      public CacheManager cacheManager() {           SimpleCacheManager cacheManager = new SimpleCacheManager();           Set<ConcurrentMapCache> mapCaches=new HashSet<>();           //配置cache类型与目录           mapCaches.add(new ConcurrentMapCache("cacheNames1"));           mapCaches.add(new ConcurrentMapCache("cacheNames2"));           mapCaches.add(new ConcurrentMapCache("cacheNames3"));           mapCaches.add(new ConcurrentMapCache("cacheNames4"));           cacheManager.setCaches(mapCaches);           cacheManager.afterPropertiesSet();           return cacheManager;      }   }     //方式二:CaffeineCache (可设置过期时间) @Configuration public class SpringCachingConfig {        @Bean     public CacheManager cacheManager() {         SimpleCacheManager cacheManager = new SimpleCacheManager();           List<CaffeineCache> caffeineCaches = new ArrayList<>();           //SysConstants.CACHE_NAMES=new ArrayList(         //Arrays.asList("cacheNames1","cacheNames2","cacheNames3","cacheNames4")         //);         for (String  cacheName: SysConstants.CACHE_NAMES) {             caffeineCaches.add(new CaffeineCache(cacheName,                     Caffeine.newBuilder()                             .initialCapacity(50)                             .maximumSize(30000)//最大存储数量                             .expireAfterWrite(2, TimeUnit.HOURS)//过期时间2 小时                             .build()));         }         cacheManager.setCaches(caffeineCaches);         return cacheManager;     }   }     //方式三。。。。还可以配置redis以及其他的方式,这里主要介绍以上两种方式

Implémenter l’interface de cache

//控制器1 @RestController @RequestMapping("/path1") @Cacheable(cacheNames = "cacheNames1" ,key="#root.methodName+#a0" ) public class Controller1 {   }   //控制器2 @RestController @RequestMapping("/path2") @Cacheable(cacheNames = "cacheNames2" ,key="#root.methodName+#a0" ) public class Controller2 {   }   //控制器3 @RestController @RequestMapping("/path3") @Cacheable(cacheNames = "cacheNames3" ,key="#root.methodName+#a0" ) public class Controller3 {   }   //控制器4 @RestController @RequestMapping("/path4") @Cacheable(cacheNames = "cacheNames4" ,key="#root.methodName+#a0" ) public class Controller4 {   }

2.2 Explication détaillée des annotations SpringCache

Annotation @Cacheable

Si la donnée est absente du cache:interroger la base de données, la stocker dans le cache, renvoyer le résultat,
Si le cache contient le résultat : le renvoyer directement

Paramètres Explication exemple
value Noms des caches, définis dans le fichier de configuration spring ; il faut en spécifier au moins un Par exemple :
@Cacheable(value=”mycache”)
@Cacheable(value={”cache1”,”cache2”}
key Clé du cache, qui peut être vide. Si elle est définie, elle doit être écrite sous forme d’expression SpEL ; sinon, elle est construite par défaut en combinant tous les paramètres de la méthode @Cacheable(value=”testcache”,key=”#userName”)
condition Condition de mise en cache, facultative, écrite en SpEL, renvoyant true ou false ; la mise en cache n’a lieu que si elle renvoie true @Cacheable(value=”testcache”,condition=”#userName.length()>2”)

Rôle : permet d’écrire dans le cache en y stockant le résultat, afin que les appels ultérieurs puissent renvoyer directement la valeur mise en cache sans exécuter de nouveau la méthode réelle. Utilisation la plus simple, nom de l’annotation=nom du cache, exemple d’utilisation ci-dessous :

@Cacheable(value="accountCache")// 使用了一个缓存名叫 accountCache  public Account getAccountByName(String userName) {    // 方法内部实现不考虑缓存逻辑,直接实现业务    System.out.println("real query account."+userName);     return getFromDB(userName);  }

Annotation @CacheEvict

@CacheEvict : annotation permettant de supprimer des données du cache, très utile pour supprimer les données anciennes ou inutiles. Elle comporte aussi un paramètre supplémentaire (allEntries) ; lorsque allEntries=true, toutes les entrées peuvent être supprimées en bloc

Paramètres Explication exemple
value Noms des caches, définis dans le fichier de configuration spring ; il faut en spécifier au moins un @CacheEvict(value=”my cache”)
key Clé du cache, qui peut être vide. Si elle est définie, elle doit être écrite sous forme d’expression SpEL ; sinon, elle est construite par défaut en combinant tous les paramètres de la méthode @CacheEvict(value=”testcache”,key=”#userName”)
condition Condition de mise en cache, facultative, écrite en SpEL, renvoyant true ou false ; la mise en cache n’a lieu que si elle renvoie true @CacheEvict(value=”testcache”,condition=”#userName.length()>2”)
allEntries Indique s’il faut vider tout le contenu du cache ; la valeur par défaut est false. Si true est spécifié, tout le cache sera vidé immédiatement après l’appel de la méthode @CachEvict(value=”testcache”,allEntries=true)
beforeInvocation Indique si le cache doit être vidé avant l’exécution de la méthode ; la valeur par défaut est false. Si true est spécifié, le cache est vidé avant même que la méthode ne s’exécute. Par défaut, si l’exécution de la méthode lève une exception, le cache n’est pas vidé @CachEvict(value=”testcache”,beforeInvocation=true)

 

@CacheEvict(value="accountCache",key="#account.getName()")// 清空accountCache 缓存  public void updateAccount(Account account) {    updateDB(account);  }   @CacheEvict(value="accountCache",allEntries=true)// 清空accountCache 缓存 public void reload() {    reloadAll() }  @Cacheable(value="accountCache",condition="#userName.length() <=4")// 缓存名叫 accountCache  public Account getAccountByName(String userName) {   // 方法内部实现不考虑缓存逻辑,直接实现业务  return getFromDB(userName);  }

Annotation @CachePut

@CachePut : cette annotation permet de mettre à jour le cache sans perturber l’exécution de la méthode. Autrement dit, la méthode est toujours exécutée et son résultat est placé dans le cache ;

Paramètres Explication exemple
value Noms des caches, définis dans le fichier de configuration spring ; il faut en spécifier au moins un @CachePut(value=”my cache”)
key Clé du cache, qui peut être vide. Si elle est définie, elle doit être écrite sous forme d’expression SpEL ; sinon, elle est construite par défaut en combinant tous les paramètres de la méthode @CachePut(value=”testcache”,key=”#userName”)
condition Condition de mise en cache, facultative, écrite en SpEL, renvoyant true ou false ; la mise en cache n’a lieu que si elle renvoie true @CachePut(value=”testcache”,condition=”#userName.length()>2”)

L’annotation @CachePut garantit l’exécution de la méthode tout en enregistrant sa valeur de retour dans le cache, ce qui permet de mettre à jour simultanément le cache et la base de données.

@CachePut(value="accountCache",key="#account.getName()")// 更新accountCache 缓存 public Account updateAccount(Account account) {    return updateDB(account);  }

Annotation @Caching

Lors de l’utilisation du cache, des mises à jour et des suppressions peuvent avoir lieu simultanément, ce qui peut nécessiter plusieurs annotations à la fois. @Caching permet de réaliser cela

//添加user缓存的同时,移除userPage的缓存 @Caching(     put =@CachePut(value = "user",key ="#userVo.id"), evict = @CacheEvict(value = "userPage",allEntries = true) )
@Caching(put = { @CachePut(value = "user", key = "#user.id"), @CachePut(value = "user", key = "#user.username"), @CachePut(value = "user", key = "#user.email") }) public User save(User user) {

@CacheConfig

Toutes les annotations @Cacheable()contiennent un attribut value=“xxx”. Évidemment, lorsque les méthodes sont nombreuses, cela devient assez fastidieux à écrire. Pouvoir tout déclarer en une seule fois simplifierait les choses. C’est pour cela qu’existe la configuration @CacheConfig : @CacheConfig est une annotation au niveau de la classe qui permet de partager les noms de cache ; si vous indiquez un autre nom dans l’annotation de votre méthode, c’est toujours le nom spécifié au niveau de la méthode qui prévaut.

@CacheConfig("books") public class BookRepositoryImpl implements BookRepository {    @Cacheable   public Book findBook(ISBN isbn) {...} }

Mise en cache conditionnelle
Voici quelques exemples courants de mise en cache conditionnelle

//@Cacheable将在执行方法之前( #result还拿不到返回值)判断condition,如果返回true,则查缓存;  @Cacheable(value = "user", key = "#id", condition = "#id lt 10") public User conditionFindById(final Long id)   //@CachePut将在执行完方法后(#result就能拿到返回值了)判断condition,如果返回true,则放入缓存;  @CachePut(value = "user", key = "#id", condition = "#result.username ne 'zhang'")  public User conditionSave(final User user)    //@CachePut将在执行完方法后(#result就能拿到返回值了)判断unless,如果返回false,则放入缓存;(即跟condition相反) @CachePut(value = "user", key = "#user.id", unless = "#result.username eq 'zhang'") public User conditionSave2(final User user)    //@CacheEvict, beforeInvocation=false表示在方法执行之后调用(#result能拿到返回值了);且判断condition,如果返回true,则移除缓存; @CacheEvict(value = "user", key = "#user.id", beforeInvocation = false, condition = "#result.username ne 'zhang'")  public User conditionDelete(final User user)

Annotations de cache personnalisées

Par exemple, la combinaison @Caching présentée précédemment peut rendre le code assez confus en multipliant les annotations sur une méthode. On peut alors utiliser une annotation personnalisée pour regrouper toutes ces annotations en une seule, comme ceci :

@Caching(put = { @CachePut(value = "user", key = "#user.id"), @CachePut(value = "user", key = "#user.username"), @CachePut(value = "user", key = "#user.email") }) @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface UserSaveCache { }

Il nous suffit alors d’utiliser le code suivant sur la méthode, ce qui rend l’ensemble du code assez épuré.

@UserSaveCache public User save(User user)

Extension
Par exemple, lors d’un findByUsername, il ne faut pas seulement placer username–>user dans le cache, mais aussi id—>user et email—>user ; ainsi, lors d’une recherche ultérieure par id, le résultat sera directement trouvé dans le cache

@Caching(   cacheable = {     @Cacheable(value = "user", key = "#username")   },   put = {     @CachePut(value = "user", key = "#result.id", condition = "#result != null"),     @CachePut(value = "user", key = "#result.email", condition = "#result != null")   } ) public User findByUsername(final String username) {   System.out.println("cache miss, invoke find by username, username:" + username);   for (User user : users) {     if (user.getUsername().equals(username)) {       return user;     }   }   return null; }

En réalité, pour : id—>user;username—->user;email—>user;une meilleure approche serait peut-être : id—>user;username—>id;email—>id;afin de ne conserver qu’un seul exemplaire de user;par exemple :

@CachePut(value="cacheName", key="#user.username", cacheValue="#user.username")  public void save(User user)     @Cacheable(value="cacheName", key="#user.username", cacheValue="#caches[0].get(#caches[0].get(#username).get())")  public User findByUsername(String username)

Données du contexte SpEL
Spring Cache met à notre disposition certaines données de contexte SpEL. Le tableau suivant est directement extrait de la documentation officielle de Spring :

Nom Emplacement Description Exemple
methodName objet root Nom de la méthode actuellement appelée root.methodName
method objet root La méthode actuellement appelée root.method.name
target objet root Objet cible actuellement appelé root.target
targetClass objet root Classe de l’objet cible actuellement appelé root.targetClass
args objet root La liste des paramètres de la méthode actuellement appelée root.args[0]
caches objet root La liste des caches utilisés par l’appel de méthode actuel (par exemple @Cacheable(value={“cache1”, “cache2”})), qui comporte alors deux caches root.caches[0].name
nom de l’argument Contexte d’exécution Les paramètres de la méthode actuellement appelée, par exemple findById(Long id) : on peut récupérer le paramètre avec #id user.id
résultat Contexte d’exécution Valeur renvoyée après l’exécution de la méthode(uniquement pour les conditions évaluées après son exécution, comme ‘unless', ou 'cache evict' avec beforeInvocation=false) résultat
@CacheEvict(value = "user", key = "#user.id", condition = "#root.target.canCache() and #root.caches[0].get(#user.id).get().username ne #user.username", beforeInvocation = true)  public void conditionUpdate(User user)

Bilan

Pour les déclarations de cache, le mécanisme de cache de Spring fournit un ensemble d’annotations Java:
· @Cacheable
o Fonction : déclencher l’écriture dans le cache ; si la donnée est absente du cache, interroger la base de données, la stocker dans le cache et renvoyer le résultat ; si elle est présente dans le cache, renvoyer directement le résultat
o Applications :Interroger la base de données Méthode
· @CacheEvict
o Fonction : déclencher la suppression du cache
o Applications :Supprimer ou modifier la base de données Méthode
· @CachePut
o Fonction : écriture dans le cache (sans affecter l’exécution de la méthode).
o Applications :Ajouter à la base de données Méthode
· @Mise en cache
o Fonction : regrouper plusieurs opérations de cache à appliquer à une méthode
o Application : utilisation combinée des annotations ci-dessus


Commentaires

Envoi en cours

Choisissez votre thème

Le thème s’applique à tout le site.