Ir al contenido principal

Buscar en CooLWJ

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

Idioma

Introducción al uso de Spring Cache

Uno. Solución de caché basada en SpringCache

1.1 Introducción a SpringCache

springcache se publicó con la versión spring3.1 y encapsula y abstrae el uso de la caché; basta con utilizar anotaciones en los métodos para obtener resultados de la caché. Precisamente por utilizar anotaciones, resuelve el problema del acoplamiento entre el código de negocio y el código de caché, permitiendo que el código existente admita caché de inmediato sin invadir el código de negocio, de modo que los desarrolladores puedan utilizarla de forma transparente.

1.2 Descripción general de SpringCache

Existen muchos sistemas de caché, cada uno con sus propias ventajas, como Redis, Memcached, Guava, Caffeine, etc.
Si nuestro programa quiere utilizar una caché, tiene que acoplarse a estos frameworks. Los arquitectos más hábiles ya utilizan interfaces para reducir ese acoplamiento y, mediante la abstracción y el polimorfismo de la orientación a objetos, separar el código de negocio del framework concreto.
Sin embargo, todavía tenemos que llamar explícitamente en el código a las interfaces y los métodos relacionados con la caché, introducir datos en ella en el momento adecuado y recuperarlos cuando corresponda. Piensa en 「AOP」 como escenario de aplicación, ¿no es precisamente algo que debería hacer AOP por naturaleza?
Desde Spring 3.1, se ofrece soporte de caché mediante anotaciones, similar al soporte de transacciones con la anotación [@Transactional](/Transactional ), además de una abstracción de caché; antes, esto solía implementarse mediante AOP.
Ventajas de utilizar Spring Cache:

  • Proporciona una abstracción básica de Cache que facilita cambiar entre distintas implementaciones subyacentes de caché;

  • La anotación Cache permite aplicar la lógica de caché de forma transparente a nuestro código de negocio, de manera similar a las transacciones, y requiere menos código para hacerlo;

  • Permite revertir automáticamente también la caché al revertir una transacción;

  • Admite una lógica de caché relativamente compleja;

Identificador de la tecnología Spring Cache

1.3 Diseño central de Spring Cache

A partir de Spring 3.1 se introdujo Spring Cache, la abstracción de caché de Spring. Mediante la definición de org.springframework.cache.Cache y org.springframework.cache.CacheManager una interfaz para unificar distintas tecnologías de caché y permitir el uso de anotaciones JCache para simplificar el desarrollo.
La interfaz Cache define las especificaciones de los componentes de caché e incluye el conjunto de sus distintas operaciones. Spring proporciona diversas xxxCache implementación de: RedisCache , EhCacheCache , ConcurrentMapCache etc.
Veamos la interfaz Cache y a través de parte del código fuente CacheManager interfaz.

Interfaz 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();     } }

Como puede verse, la interfaz Cache abstrae las operaciones de caché como get, put y evict.

Clase abstracta 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;     } }

Clase abstracta AbstractValueAdaptingCache implementa la interfaz Cache y abstrae principalmente la lógica de tratamiento de los valores NULL.

  • allowNullValues El atributo indica si se permite almacenar valores NULL en la caché

  • fromStoreValue del método para tratar los valores NULL get operación, en la propiedad allowNullValues cuando es true, tratar NullValue como NULL

  • toStoreValue método para tratar los valores NULL put operación, en la propiedad allowNullValues si es true, trata NULL como NullValue; de lo contrario, lanza una excepción

  • toValueWrapper El método proporciona Cache en la interfaz get la implementación predeterminada del método, que lee el valor de la caché y después, mediante fromStoreValue se transforma y, finalmente, se encapsula como SimpleValueWrapper Devuelve

  • ValueWrapper get(Object key) y T get(Object key, @Nullable Classtype) el método se implementa sobre la base del método anterior

  • ValueWrapper get(Object key) y @Nullable Classtype) el método se implementa sobre la base del método anterior

  • lookup El método abstracto permite que las subclases obtengan el valor real de la caché

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 Hereda de la clase abstracta AbstractValueAdaptingCache , es la implementación de caché predeterminada de Spring. Permite almacenar copias de los objetos en caché; SerializationDelegate serialization se encarga de la serialización y su valor predeterminado es null, lo que implica una caché basada en referencias. Las operaciones de caché se basan en la clase base AbstractValueAdaptingCache tratamiento de los valores null, que se permiten de forma predeterminada.

CacheManager

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

CacheManager Gestiona un conjunto de objetos Cache basándose en name. Por supuesto, CacheManager también tiene muchas clases de implementación, como ConcurrentMapCacheManager 、 AbstractCacheManager y SimpleCacheManager ,estos xxxCacheManager Estas clases sirven para establecer las reglas de gestión de Cache, por lo que no profundizaremos más aquí.

II Uso de SpringCache

2.1 Cómo utilizarlo

Spring Cache es precisamente un marco de este tipo. Utiliza AOP para implementar funciones de caché basadas en anotaciones y proporciona una abstracción adecuada: el código de negocio no necesita preocuparse por el marco de caché subyacente; basta con añadir una anotación para disponer de esta funcionalidad.

Añadir dependencias

<!--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>

Configurar Cache

Añade la anotación @EnableCaching a la clase de inicio Application

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

Configura el tipo de caché de cache; aquí nos centraremos en la caché 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以及其他的方式,这里主要介绍以上两种方式

Implementar la caché de una interfaz

//控制器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 Explicación detallada de las anotaciones de SpringCache

Anotación @Cacheable

Si no está en la caché: consultar la base de datos, guardar en la caché, devolver el resultado,
Si está en la caché: devolver directamente el resultado

Parámetros Explicación ejemplo
value Nombre de la caché, definido en el archivo de configuración de spring ; debe especificarse al menos uno Por ejemplo:
@Cacheable(value=”mycache”)
@Cacheable(value={”cache1”,”cache2”}
key La key de la caché puede dejarse vacía; si se especifica, debe escribirse como una expresión SpEL; si no se especifica, se combinan por defecto todos los parámetros del método @Cacheable(value=”testcache”,key=”#userName”)
condición Condición para almacenar en caché, puede estar vacía y se escribe con SpEL; devuelve true o false, y solo se almacena en caché cuando es true @Cacheable(value=”testcache”,condition=”#userName.length()>2”)

Función: permite escribir en la caché y almacenar el resultado para que, en llamadas posteriores, se pueda devolver directamente el valor guardado sin tener que ejecutar de nuevo el método real. La forma más sencilla de uso, nombre de la anotación=nombre de la caché, se muestra en el siguiente ejemplo:

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

Anotación @CacheEvict

@CacheEvict:anotación para eliminar datos de la caché, muy útil para borrar datos antiguos e innecesarios. Aquí también hay un parámetro adicional (allEntries); al establecer allEntries=true, se pueden eliminar todas las entradas de forma masiva

Parámetros Explicación ejemplo
value Nombre de la caché, definido en el archivo de configuración de spring ; debe especificarse al menos uno @CacheEvict(value=”my cache”)
key La key de la caché puede dejarse vacía; si se especifica, debe escribirse como una expresión SpEL; si no se especifica, se combinan por defecto todos los parámetros del método @CacheEvict(value=”testcache”,key=”#userName”)
condición Condición para almacenar en caché, puede estar vacía y se escribe con SpEL; devuelve true o false, y solo se almacena en caché cuando es true @CacheEvict(value=”testcache”,condition=”#userName.length()>2”)
allEntries Indica si se debe vaciar todo el contenido de la caché, con valor predeterminado false;si se establece en true, toda la caché se vaciará inmediatamente después de invocar el método @CachEvict(value=”testcache”,allEntries=true)
beforeInvocation Indica si se vacía la caché antes de ejecutar el método, el valor predeterminado es false, si se establece en true, la caché se vacía antes de que se ejecute el método, de forma predeterminada, si la ejecución del método lanza una excepción, la caché no se vacía @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);  }

Anotación @CachePut

@CachePut: esta anotación puede utilizarse cuando se necesita actualizar la caché sin interferir en la ejecución del método. Es decir, el método siempre se ejecuta y su resultado se guarda en la caché;

Parámetros Explicación ejemplo
value Nombre de la caché, definido en el archivo de configuración de spring ; debe especificarse al menos uno @CachePut(value=”my cache”)
key La key de la caché puede dejarse vacía; si se especifica, debe escribirse como una expresión SpEL; si no se especifica, se combinan por defecto todos los parámetros del método @CachePut(value=”testcache”,key=”#userName”)
condición Condición para almacenar en caché, puede estar vacía y se escribe con SpEL; devuelve true o false, y solo se almacena en caché cuando es true @CachePut(value=”testcache”,condition=”#userName.length()>2”)

la anotación @CachePut, que garantiza que se ejecute el método y que su valor de retorno también se guarde en la caché, permitiendo actualizar de forma sincronizada la caché y la base de datos.

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

Anotación @Caching

Al utilizar la caché, es posible que se realicen actualizaciones y eliminaciones a la vez, lo que puede requerir varias anotaciones simultáneas.Y @Caching permite hacerlo

//添加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

Todas las anotaciones @Cacheable() contienen un atributo value=“xxx”. Evidentemente, si hay muchos métodos, escribirlo resulta bastante tedioso; sería más cómodo poder declararlo todo de una vez. Para eso existe la configuración @CacheConfig: @CacheConfig es una anotación de clase que permite compartir los nombres de las cachés. Si especificas otro nombre en un método, seguirá prevaleciendo el nombre indicado en ese método.

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

Almacenamiento condicional en caché
A continuación se presentan algunos casos habituales de almacenamiento condicional en caché

//@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)

Anotaciones de caché personalizadas

Por ejemplo, la combinación anterior de @Caching hace que las anotaciones del método den al código un aspecto bastante desordenado; en ese caso, se puede utilizar una anotación personalizada para reunirlas en una sola, como se muestra a continuación:

@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 { }

Así, basta con utilizar el siguiente código en el método, y el código en su conjunto queda bastante limpio.

@UserSaveCache public User save(User user)

Ampliación
Por ejemplo, al ejecutar findByUsername, no debería almacenarse solo username–>user, sino también id—>user y email—>user;así, la próxima vez que se busque por id, se obtendrá directamente un acierto de caché

@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 realidad, para: id—>user;username—->user;email—>user;quizá una opción mejor sea: id—>user;username—>id;email—>id;garantizando que user solo se almacene una vez;por ejemplo:

@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)

Datos del contexto de SpEL
Spring Cache proporciona algunos datos de contexto de SpEL que podemos utilizar; la siguiente tabla está extraída directamente de la documentación oficial de Spring:

Nombre Ubicación Descripción Ejemplo
methodName Objeto root Nombre del método que se está invocando root.methodName
método Objeto root Método que se está invocando actualmente root.method.name
target Objeto root Objeto de destino que se está invocando root.target
targetClass Objeto root Clase del objeto de destino que se está invocando root.targetClass
args Objeto root Lista de parámetros del método que se está invocando root.args[0]
caches Objeto root La lista de cachés utilizada por la invocación del método actual (por ejemplo, @Cacheable(value={“cache1”, “cache2”})), en cuyo caso hay dos cachés root.caches[0].name
nombre del argumento Contexto de ejecución Los parámetros del método que se está invocando, como findById(Long id); podemos obtener el parámetro mediante #id user.id
resultado Contexto de ejecución Valor devuelto tras ejecutar el método (solo válido para condiciones evaluadas después de la ejecución del método, como ‘unless', o 'cache evict' con beforeInvocation=false) resultado
@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)

Resumen

Para declarar el almacenamiento en caché, Spring proporciona un conjunto de anotaciones de Java:
· @Cacheable
o Función: activa la escritura en caché; si el dato no está en caché, consulta la base de datos, lo almacena en caché y devuelve el resultado; si ya está en caché, devuelve directamente el resultado
o Aplicaciones:Consultar la base de datos Método
· @CacheEvict
o Función:activar el vaciado de la caché
o Aplicaciones:Eliminar o modificar la base de datos Método
· @CachePut
o Función: escritura en caché (no afecta a la ejecución del método).
o Aplicaciones:Añadir a la base de datos Método
· @Almacenamiento en caché
o Función: reagrupar varias operaciones de caché que se aplicarán a un método
o Aplicación:uso combinado de las anotaciones anteriores


Comentarios

Enviando

Elige tu tema

El tema se aplica a todo el sitio.