1 Introducción a Ehcache
Ehcache es un marco de almacenamiento en caché en proceso de Java puro, con características rápidas y Lean, y es el CacheProvider predeterminado en Hibernate.
Ehcache es un caché distribuido Java de código abierto ampliamente utilizado. Principalmente dirigido a la caché Universal, Java EE y contenedores livianos. Tiene las características del almacenamiento de memoria y disco, cargador de caché, extensión de caché, manejador de excepciones de caché, un filtro de servlet de caché GZIP y admite API REST y SOAP.
Ehcache fue desarrollado originalmente por Greg Luck en 2003. En 2009, el proyecto fue comprado por Terracotta. El software aún es de código abierto, pero algunas características principales (por ejemplo, la consistencia entre la reinicabilidad rápida) solo se pueden usar en productos comerciales, como Enterprise Ehcache y BigMemory. Wikimedia FoundationAnEnUnced utiliza actualmente la tecnología Ehcache.
En resumen, Ehcache sigue siendo una buena tecnología de almacenamiento en caché. Echemos un vistazo a cómo se implementa Spring con Ehcache.
2 primavera con ehcache
Los resultados del sistema son los siguientes:
3 Introducción de configuración específica
Hay combinaciones de estas partes:
SRC: código Java, incluido el interceptor, interfaz de llamada, clase de prueba
src/cache-bean.xml: configure el bean correspondiente a las clases de ehcache, interceptor y de prueba, etc.
src/ehcache.xml: información de configuración de caché de ehcache
Webroot/lib: biblioteca
4 Introducción al contenido detallado
4.1 SRC
4.1.1 Interceptor
Dos interceptores se configuran primero en el código:
El primer interceptor es:
com.test.ehcache.cachemethodinterceptor
El contenido es el siguiente:
paquete com.test.ehcache; import java.io.Serializable; import net.sf.ehcache.cache; import net.sf.ehcache.element; import oopalliance.intercept.methodinterceptor; org.springframework.util.assert; public class Cachemethodinterceptor implementa MethodInterceptor, InicializandoBean {caché de caché privado; public void setCache (caché cache) {this.cache = cache; } public cachemethodinterceptor () {super (); } /*** Intercepe el método ServiceManager y descubra si existe el resultado. Si existe, devuelva el valor en el caché. * De lo contrario, devuelva el resultado de la consulta de la base de datos y coloque el resultado de la consulta en el caché */public object Invoke (MethodInVocation Invocation) lanza lando {// Obtener el nombre de TargetName de cadena de clase para ser interceptado = Invocation.getThis (). GetClass (). GetName (); // Obtener el método de la clase a interceptarse String MethodName = Invocation.getMethod (). GetName (); // Obtener los parámetros del método de la clase para ser interceptado objeto [] argumentos = invocation.getArGuments (); Resultado del objeto; // Crear una cadena para hacer la clave en la cadena de caché cachekey = getCachekey (targetName, metodName, argumentos); // Obtener datos del elemento cache elemento = cache.get (cachekey); if (element == null) {// Si no hay datos en el caché, busque no dolor, como la base de datos, y coloque los encontrados en el resultado de caché = invocation.proced (); // Generar la clave y el valor que se almacenará en el elemento caché = nuevo elemento (cachekey, (serializable) resultado); System.out.println ("---- Ingrese la búsqueda sin dolor, como buscar la base de datos directamente, colocarla en el caché después de buscar"); // almacenar la clave y el valor en caché cache.put (elemento); } else {// Si hay datos en el caché, busque caché system.out.println ("--- Ingrese la búsqueda de caché, no busque la base de datos, aliviando la presión en la base de datos"); } return element.getValue (); } /*** Método para obtener la tecla Cache. La tecla Cache es el identificador único de un elemento en el caché. * Incluyendo el nombre del paquete + nombre de clase + nombre del método, como: com.test.service.testserviceImpl.getObject */ private string getCachekey (String TargetName, String MethodName, Object [] Arguments) {StringBuffer sb = new StringBuffer (); sb.append (TargetName) .Append ("."). Append (MethodName); if ((argumentos! = nulo) && (argumentos.length! = 0)) {for (int i = 0; i <arguments.length; i ++) {sb.append ("."). append (argumentos [i]); }} return sb.ToString (); } / ** * Implementar InitializingBean, verifique si el caché está vacío 70 * / public void AfterPropertIesset () lanza la excepción {afirmo.notnull (caché, "necesita un caché. Use setCache (caché) creala"); }}Cachemethodinterceptor se usa para interceptar métodos que comienzan con "Get". Tenga en cuenta que este interceptor primero intercepta y luego ejecuta la interfaz de llamada original.
También hay un interceptor:
com.test.ehcache.cacheradterreturningAdvice
Contenido específico:
paquete com.test.ehcache; import java.lang.reflect.method; import java.util.list; import net.sf.ehcache.cache; import org.springframework.aop.afterreturningAdvice; import. CacheadterreturningAdvice implementa después de la salida de suministro, inicializando a Bean {caché de caché privado; public void setCache (caché cache) {this.cache = cache; } public CacheAftterReturningAdVice () {super (); } public void Afterreturning (Object arg0, método arg1, objeto [] arg2, object arg3) lanza lanzable {string className = arg3.getClass (). getName (); List list = cache.getKeys (); for (int i = 0; i <list.size (); i ++) {string cachekey = string.valueOf (list.get (i)); if (cachekey.startswith (classname)) {cache.remove (cachekey); System.out.println ("----- claro caché"); }}} public void AfterPropertIesset () lanza la excepción {afirmo.notnull (caché, "necesita un caché. Use setcache (caché) creala"); }}CacherTterReturningAdvice se utiliza para interceptar métodos que comienzan con "actualización". Tenga en cuenta que este interceptor ejecuta primero la interfaz de llamada original y luego se intercepta.
4.1.2 Llamando a la interfaz
El nombre de la interfaz es:
com.test.service.serviceManager
El contenido específico es el siguiente:
paquete com.test.service; import java.util.list; Public Interface ServiceManager {public List getObject (); public void UpdateObject (objeto objeto); }El nombre de la clase de implementación es:
com.test.service.serviceManagerImpl
El contenido específico es el siguiente:
paquete com.test.service; import java.util.arrayList; import java.util.list; public class ServiceManagerImpl implementa ServiceManager {@Override public List getObject () {System.out.println ("----- ServiceManager: Este elemento no existe en la cache Cache, mira el database, y ponga el cache!"); ");" regresar nulo; } @Override public void updateObject (objeto objeto) {System.out.println ("---- ServiceManager: el objeto se actualiza, y todos los cachés generados por esta clase se eliminarán!"); }}4.1.3 Clase de prueba
El nombre de la clase de prueba es:
com.test.service.testmain
El contenido específico es:
paquete com.test.service; import org.springframework.context.applicationContext; import org.springframework.context.support.classpathxmlaPplicationContext; public class testMain {public static void main (string [] args) {string cachestring = "/cache-bean.xml"; APLEicleContext context = new ClassPathXMLApPlicationContext (Cachestring); // Obtenga el bean generado por la fábrica proxy proxyFactory para generar un efecto interceptivo ServiceManager testService = (ServiceManager) context.getBean ("proxyFactory"); // la primera vez que busca System.out.println ("===== Primera búsqueda"); testService.getObject (); // la segunda vez que busca System.out.println ("===== Segunda búsqueda"); testService.getObject (); // la segunda vez que busca System.out.println ("====== la tercera vez que busca"); testService.UpdateObject (nulo); // la tercera vez buscando sistema.out.println ("====== la tercera vez que busca"); testService.getObject (); }}Tenga en cuenta aquí que la obtención de frijoles es producido por la fábrica proxy proxyFactory, para que haya un efecto de intercepción.
Se puede ver que se establecen cuatro llamadas en la clase de prueba, y la orden de ejecución es:
Primera búsqueda Segunda búsqueda Primera actualización tercera búsqueda
4.2 src/cache-bean.xml
Cache-Bean.xml se usa para configurar los frijoles correspondientes a las clases de Ehcache, Interceptor y Test. El contenido es el siguiente:
<? xml versión = "1.0" encoding = "utf-8"?> <! Doctype Beans public "-// spring // dtd bean // en" http://www.springframework.org/dtd/spring-beanss.dtdd "> <behons> <!-cotización de la configuración de ehcache-> <<r Bean Id" name = "configlocation"> <alon> ehcache.xml </value> </property> </ bean> <!-Defina la fábrica de ehcache y establece el nombre del caché utilizado, es decir, "com.tt"-> <bean id = "ehcache"> <nombre de propiedad = "cachemanager"> <ref local = "cohaldacachemanager"/> </propiedad> <!-el nombre del nombre de cache = "cachemanager"> <ref local = "cohalt-coachemanager"/> </propiedad> <? name = "Cachename"> <value> com.tt </value> </property> </bean> <!-El interceptor para crear caché y consulta caché-> <bean id = "cachemethodinterceptor"> <Property name = "cache"> <ref local = "ehcache"/> </propers> </ bean> <! id = "CacheadterReturningAdVice"> <Property Name = "Cache"> <ref Local = "Ehcache" /> </property> < /bean> <!-Llame a la interfaz, el objeto interceptado-> <bean id = "ServiceManager" /> <!-Inserte el interceptor para confirmar qué se llama, el nombre del método y las características del interceptor interceptor, etc., llame aquí el interceptor interceptor para confirmar el interceptor del interceptor aquí interceptor del interceptor interceptor, etc.. com.test.ehcache.cachemethodinterceptor-> <bean id = "cachepointcut"> <!-Agregar una sección, la sección es la sección que se agrega después de ejecutar el método de impresión-> <name de propiedad = "asesoramiento"> <ref local = "Cachemethodinterceptor" />> </propiedad> <Nombre de propiedad = "patrones"> <List> <!-###. conforme al personaje anterior una o varias veces ###* significa conformarse con el carácter anterior cero o varias veces ###/escapar cualquier símbolo utilizado en la expresión regular-> <!-.* Significa el prefijo anterior (incluido el nombre del paquete), que significa el método getObject-> <valor>.* get.* </value> </list> </ behor> <! Interceptor Nombre del método de interceptación, etc., llame al interceptor com.test.ehcache.cacherTterReturningAdVice-<bean id = "cachePointCutAdVice"> <name de propiedad = "asesoramiento"> <ref local = "cachaFerReturningAdvice" /> </propiedad> <nombre de propiedad = "patrones"> <lista> <!-.*. Método-> <valor>.*Update.*</valor> </list> </property> </bean> <!-agente fábrica-> <bean id = "proxyFactory"> <!-Descripción Nombre de la interfaz de la interfaz de llamada-> <Property Name = "Target"> <Ref local = "ServiceManager"/> </Property> <!-Descripción Nombre de interptor Bean Nombre-<Nombre de propiedad = "InterceptorNeames"> <LIST> <List> <value> CachePointCut </value> <value> CachePointCuTAdVice </value> </list> </property> </beans>
El contenido de cada frijol se ha comentado y señalado que no se olvidan de los frijoles de fábrica de agentes.
4.3 src/ehcache.xml
ehcache.xml almacena información detallada sobre la configuración de caché de ehcache, de la siguiente manera:
<? xml versión = "1.0" encoding = "utf-8"?> <ehcache xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xsi: nonamespaceschemalocation = "http://ehcache.org/ehcache.xsd" <diskstore path = "d: // temp // cache"/> <defaultcache maxelementsInmemory = "1000" eternal = "falso" timetoidleseConds = "120" timetoliveseConds = "120" overflowTodisk = "true"/> <! name = "com.tt" maxelementsInmemory = "10000" eternal = "false" timetoidleseConds = "300000" TimetoliveSeconds = "600000" OverflowTodisk = "True" /> < /ehcache>
Puede ver que la ubicación de almacenamiento del almacenamiento en caché se establece en "d:/temp/cache", y el nombre de la caché se establece en "com.tt", como se muestra en la figura:
4.4 Webroot/lib
Para la biblioteca Java requerida, consulte la imagen de la estructura del sistema al principio, omitida aquí.
5 Prueba
Ejecutar la clase de prueba, y los resultados de la prueba son los siguientes:
A través de los resultados de ejecución podemos ver:
Después de interceptar la primera búsqueda , se encuentra que es la primera intersección y el caché no se ha almacenado en caché. Por lo tanto, primero ejecute la clase de interfaz original para que se consulten los datos. Se puede obtener a través de la consulta de la base de datos, y luego generar el caché y colocar los datos consultados en el caché.
Después de interceptar la segunda búsqueda , se descubrió que el caché ya existe, por lo que la clase de interfaz original ya no se ejecuta, es decir, la base de datos ya no se consulta y los datos de consulta se obtienen directamente a través del caché. Por supuesto, es solo una impresión simple aquí.
Luego está la primera actualización . La operación realizada después de ser interceptada es almacenar todos los datos en la memoria caché en la base de datos y eliminar el caché.
Finalmente, está la tercera consulta . Después de ser interceptado, se encuentra que el sistema no tiene un caché, por lo que la base de datos de consulta de clase de interfaz original, crea un caché y coloca los datos obtenidos de la nueva consulta en el caché. El mismo método que la primera consulta.
Hasta ahora hemos implementado lo que debe hacer por Spring con Ehcache.
6 Código fuente de adjunto
El código fuente de archivos adjuntos se puede obtener de mi sitio web de GitHub.
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.