Se puede decir que el almacenamiento en caché es una forma muy efectiva y simple de acelerar la respuesta del servicio. En el campo de almacenamiento en caché, hay muchos marcos bien conocidos, como Ehcache, Guava, Hazelcast, etc. Como una base de datos clave de valor, Redis también se ha convertido en una herramienta de almacenamiento en caché de datos popular debido a su característica.
De la manera tradicional, el código de procesamiento de caché está muy hinchado.
Por ejemplo: necesitamos agregar una función de consulta a la función de caché, que requiere aproximadamente tres pasos.
1. Antes de ejecutar la función, debemos verificar si hay datos en el caché. Si existe, devuelva los datos en caché.
2. Si no existe, debe consultarse en los datos de la base de datos.
3. Finalmente, almacene los datos en el caché. Cuando se llama a esta función la próxima vez, puede usar los datos en caché directamente para reducir la presión en la base de datos.
Entonces, ¿cuánto código se requiere para implementar los tres pasos anteriores? Aquí hay un ejemplo:
La parte roja en la imagen de arriba es todo el código de plantilla, pero el código que realmente está relacionado con esta función solo representa 1/5. Para todas las funciones que necesitan implementar funciones de caché, se requiere código de plantilla infladado. Es una solución extremadamente inelegada.
Entonces, ¿cómo podemos recuperar el código hinchado en el momento más fresco?
¿No es AOP la mejor solución a este código de estilo plantilla? Afortunadamente, ya no necesitamos implementar las secciones por nosotros mismos. SpringCache nos ha proporcionado una buena sección. Solo necesitamos hacer configuraciones simples para volver al original, como lo siguiente:
Solo necesita agregar anotación. Ni siquiera necesita cambiar el código original. ¿Estás ansioso por probarlo?
Solo hay tres pasos para configurar SpringCache:
Paso 1: Agregar dependencias relevantes:
<Spendency> <ProupId> Redis.Clients </Groupid> <ArfactId> JEDIS </artifactid> <versión> 2.9.0 </versewers> </pendency> <pendency> <proupid> org.springframework.data </groupid> <artifactid> spring-data-redis </arifactid> <versers <MoupRid> org.apache.commons </groupid> <artifactid> commons-lang3 </artifactid> <versión> 3.3.2 </versión> </dependencia>
Paso 2: Configurar SpringCache, Redis Connection y otra información
ApplicationContext-Redis.xml
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" "" "" xmlns: p = "http://www.springframework.org/schema/p" xmlns: context = "http://www.springframework.org/schema/mvc" xmlns: cache = "http://www.springframework.org/schema/cathe" " xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/contextExt http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.2 http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd "> <!-Carga de archivo de configuración-> <context: Property-Propersholeholder Ubicación =" classpath:*. Propiedades " Cache-Manager = "Cachemanager" /> <!-Redis Connection Pool-> <Bean ID = "PoolConfig"> <Property Name = "Maxidle" valor = "$ {redis.maxidle}" /> <Property name = "maxwaitmillis" valor = "$ {redis.maxwait}" /> <name de propiedad = "testonborrow" " value = "$ {redis.testonborrow}"/> </bean> <!-Connection Factory-> <bean id = "jedisconnectionFactory" p: host-name = "$ {redis.host}" p: port = "$ {redis.port}" p: contraseña = "$ {redis.pass}" p: fool-config-ref = "patsenfig"/! Template-> <bean id = "redistemplate"> <property name = "ConnectionFactory" ref = "jedisconnectionFactory" /> </ bean> <bean id = "cachemanager"> <propiedad name = "caches"> <set> <! puede configurar múltiples redis aquí-> <bean> <nombre de propiedad = "redistemplate" reh = "redistemplate" />> <>> "nombre de propiedad =" nombre de propiedad = "nombre de propiedad =" nombre de propiedad = "nombre de propiedad =" nombre de propiedad = "nombre de propiedad =" nombre de propiedad = "nombre de propiedad =" Nombre de propiedad = "Nombre de la propiedad =" Nombre de la propiedad " /" Nombre de la propiedad = "Nombre de la propiedad" /"Nombre de la propiedad" /"Nombre" /"Nombre" /"Nombre" /"Nombre" /"Nombre" /"Nombre" /"Nombre" /"Nombre" /"Nombre" /"Nombre". value = "Content"/> <!-El nombre correspondiente al nombre debe usarse en la anotación de la clase o método-> </bean> </set> </property> </ bean> </ beans>archivo redis.properties:
# Configuración de redis # servidor ip ip redis.host = 192.168.100.55 # puerto de servidor redis.port = 6379 # servidor pase redis.pass = # use dbindex redis.database = 0 #max idel instancia de jedisredis.maxidle = 300 #if espera Instancia de Jedis, lo que obtienes instancia es todo útil.
El tercer paso es escribir la clase de implementación de la interfaz de caché
Spring solo proporciona una interfaz abstracta para caché y llama a las funciones a través de interfaces. No existe una clase de implementación específica, por lo que necesitamos implementar operaciones específicas nosotros mismos.
En la configuración anterior, podemos ver que cada clase de implementación inyectará una instancia de plantilla redista, y podemos operar redis a través de redistemplate
paquete com.cky.rest.utils; import java.io.serializable; import org.apache.commons.lang3.serializationUtils; import org.springframework.cache.cache; import og.springframework.cache.support.simplevaluewrapper; import orge.springframeward.dataSes org.springframework.data.redis.connection.redisconnection; import org.springframework.data.redis.core.redisCallback; import org.springframework.data.redis.core.redistemplate; clase pública rediscache implementa el caché {redistemplate privado <cadena> redistemplate; nombre de cadena privada; @Override public void clear () {System.out.println ("---------------"); redistemplate.execute (new Rediscallback <String> () {@Override String public doinredis (Redisconnection Connection) lanza DataAccessException {Connection.FlushDB (); return "OK";}}); } @Override public void Evict (clave de objeto) {System.out.println ("-----------------"); Cadena final KeyF = Key.ToString (); redistemplate.execute (new Rediscallback <Angn> () {@Override público Long doinredis (Redisconnection Connection) lanza DataAccessException {return Connection.del (Keyf.getBytes ());}}); } @Override public ValueWrapper get (clave de objeto) {System.out.println ("-----------------------"+Key.ToString ()); Cadena final KeyF = Key.ToString (); Objeto objeto = nulo; object = redistemplate.ExeCute (new RedIsCallback <Sect> () {@Override Public Object doinredis (redisConnection Connection) lanza DataAccessException {byte [] key = keyf.getBytes (); byte [] valor = conexión.get (key); if (value == null) {system.pintln ("-----------------"; SerializationUtils.deSerialize (valor); Valuewrapper obj = (object! = Null? New SimpleValueWrapper (objeto): nulo); System.out.println ("-------------------------------------"+obj); regresar obj; } @Override public void put (clave de objeto, valor de objeto) {system.out.println ("-----------------------"); System.out.println ("Key ----:"+Key); System.out.println ("Key ----:"+valor); String final keyString = key.ToString (); valor del objeto final = valor; Long Livetime final = 86400; redistemplate.exCute (new Rediscallback <Rong> () {@Override public Long doinredis (redisnection Connection) lanza dataAccessException {byte [] keyb = keyString.getBytes (); byte [] valueB = seroializationUtils.serialize ((serializable) value); connection.set (keyb, valueb); Connection.EXPIRE (KeyB, LiveTime); } @Override public <T> t get (object arg0, clase <t> arg1) {// tODO Método automático de método return NULL; } @Override public String getName () {return this.name; } @Override Public Object getNativecache () {return this.redistemplate; } @Override public ValueWrapper Putifabsent (Object Arg0, Object Arg1) {// TODO Método Generado automático return NULL; } public redistemplate <string, object> getredistEmplate () {return redistemplate; } public void setRedistEmplate (redistemplate <string, object> redistemplate) {this.redistemplate = redistemplate; } public void setName (nombre de cadena) {this.name = name; }}Ha habido dos errores durante el proceso de configuración:
1.xxxx.ClassNotFoundException Finalmente, descubrí que la descarga de JAR está incompleta. Simplemente elimine la carpeta del paquete JAR correspondiente del repositorio local de Maven y descargue nuevamente.
2.xxxx.methodnotFoundException Esta situación es la versión incorrecta, solo cambia a la versión en el primer paso.
Uso de anotaciones comunes en SpringCache:
@Anotación en cacheable
La anotación más utilizada almacenará en caché el valor de retorno del método anotado. Cómo funciona es: Primero busque en el caché, si no se ejecuta ningún método y el resultado se almacena en caché, y luego se devuelven los datos. El nombre de caché de esta anotación debe especificarse y corresponde al valor del nombre de un caché en cachés en cachemanager. Se puede especificar usando valor o nombres cachenes.
Si no se especifica ningún atributo de clave, Spring utilizará el generador de claves primario predeterminado para generar claves primarias. También puede personalizar la clave principal, y las expresiones de Spel se pueden usar en la clave. como sigue:
@Cacheable (cachenames = "content", key = "#user.userid") Public User GetUser (usuario de usuario) {xxxxx}Puede usar el atributo de condición para agregar condiciones al caché, de la siguiente manera:
@Cacheable (cachenames = "content", key = "#user.userid", condición = "#user.age <40") Public User GetUser (usuario de usuario) {xxxxx}@Cacheput Anotación
Ejecute el método primero y luego vuelva a colocar el valor de retorno en el caché. Se puede usar como actualizaciones en caché.
@CacheEvict Annotation
Esta anotación es responsable de eliminar explícitamente los datos del caché. Por lo general, los datos en caché tienen una fecha de vencimiento y los datos también se eliminarán cuando expire.
Esta anotación tiene dos atributos adicionales:
Si AllEnentries elimina todas las entradas de caché.
antes de la invocación: complete la operación de eliminación antes o después de que se llame al método. verdadero/falso
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.