Análisis de requisitos del Capítulo 1
Está planeado agregar Redis para implementar el procesamiento de caché en el proyecto de código abierto del equipo. Debido a que las funciones comerciales se han implementado en parte, escribiendo clases de herramientas Redis y luego referiéndose a ellas, la cantidad de cambios es grande y el desacoplamiento no se puede lograr, por lo que pensé en la AOP (programación orientada a la sección) del marco de primavera.
Proyecto de código abierto: https://github.com/u014427391/Jeepatform
Capítulo 2 Introducción a Springboot
Como un marco de código abierto importante en el campo del marco Javaee, Spring Framework juega un papel importante en el desarrollo de aplicaciones empresariales. Al mismo tiempo, el marco de primavera y sus subtramas son mucho, por lo que la cantidad de conocimiento es muy amplia.
SpringBoot: una subtrama de Spring Framework, también llamada MicroFramework, es un marco lanzado en 2014 que facilita el desarrollo del marco de Spring. Después de aprender todo el conocimiento de los marcos de primavera, los marcos de primavera inevitablemente requieren mucho XML. Si usa SpringBoot Frameworks, puede usar el desarrollo de anotaciones para simplificar en gran medida el desarrollo en función de los marcos de primavera. SpringBoot hace un uso completo del modo de configuración de Javaconfig y el concepto de "Convención es mejor que la configuración", que puede simplificar enormemente el desarrollo de aplicaciones web y servicios de descanso basados en SpringMVC.
Capítulo 3 Introducción a Redis
3.1 Instalación e implementación de Redis (Linux)
Para la instalación e implementación de Redis, consulte mi blog (Redis está escrito en base a C, así que instale el compilador GCC antes de la instalación): //www.vevb.com/article/79096.htm
3.2 Introducción a Redis
Redis ahora se ha convertido en una de las bases de datos en memoria más populares en la comunidad de desarrollo web. Con el rápido desarrollo de Web2.0 y el aumento en la proporción de datos semiestructurados, los sitios web tienen cada vez más demandas de rendimiento eficiente.
Además, los sitios web grandes generalmente tienen cientos o más servidores Redis. Como un sistema poderoso, Redis tiene su propio uso, ya sea el almacenamiento, la cola o el sistema de caché.
Para comenzar con SpringBoot Framework, consulte el artículo anterior: http://www.vevb.com/article/111197.htm
Capítulo 4 Redis Cache Implementación
4.1 El siguiente diagrama de estructura
Diagrama de estructura del proyecto:
4.2 Configuración del archivo YML de SpringBoot
Agregue el recurso de configuración de aplicación.ML a continuación, donde se configuran principalmente MySQL, Druid y Redis
Primavera: DataSource: # Principal fuente de datos Tienda: URL: JDBC: MySQL: //127.0.0.1: 3306/jeepatform? Autoreconnect = true & useUnicode = true & caracteresCoding = utf8 & caracteresetResults = utf8 & ussl = falso useName: raíz contraseña: root controlador-class-name: com.mysql.jdbc.dbc.dbc. com.alibaba.druid.pool.druiddataSource # Configuración del grupo de conexión Configure el tiempo mínimo para sobrevivir en la piscina, en milisegundos min-evicibles-idle-tiempo-Millis: 300000 # oracle, use seleccionar 1 de validación dual-quiry: seleccione 'x' test-whip-idle: verdadero test-on-borrow: false prueba-on-return: false # abre pscache y especificar el tamaño de pscache en cada conexión a los estacatos de la conexión-preparado MAX-POOL Preparado-Estatement por condición de tamaño: 20 # Configurar filtros para la intercepción de estadísticas de monitoreo. Después de eliminar la interfaz de monitoreo que SQL no se puede contar, 'Wall' se utiliza para filtros de firewall: STAT, MALL, SLF4J # Abrir la función MergesQL a través de la propiedad ConnectProperties; Registros de SQL SQL SQL Conexiones: Druid.stat.mergesql = true; Druid.stat.Slowsqlmillis = 5000 # Datos de monitoreo de fusión de múltiples DruidDataSource use-global-data-fuente-stat: true jpa: dataBase: mysql hibernate: show_sql: verdadero format_sql: true ddl Estrategia física: org.hibernate.boot.model.naming.physicalnamingstrategyStandardImpl mvc: Ver: prefix:/web-inf/jsp/sufix: .jsp #jedis configuración jedis: grupo: host: 127.0.0.1 puerto: 6379 Contraseña: contraseña Timeout: 0 config: maxtotal: 100 maxidle: 10 moxwaitm 100000
Escriba una clase de configuración para iniciar la configuración jedisconfig.java:
paquete org.muses.Jeepatform.config; import org.springframework.beans.factory.annotation.auTowired; importar org.springframework.beans.factory.annotation.Qalifier; importar org.springframework.beans.annotation.value; importación; org.springframework.boot.autoconfigure.condition.conditionOnMissingBean; import org.springframework.boot.context.properties.configurationProperties; importación de la importación; Redis.clients.jedis.jedispool; import Redis.clients.jedis.jedispoolconfig; @configuration //@configurationProperties (prefix = jedisconfig.jedis_prefix) clase pública jedisconfig {// public final string jedis_prefix = "jedis"; "; @Bean (name = "jedispool") @aUtowired public jedispool jedispool (@Qualifier ("jedispoolconfig") jedispoolconfig config, @value ("$ {spring.jedis.pool.host}") String Host, @value ("$ {spring.jedis.pool.port}") intorto, ") @Value ("$ {spring.jedis.pool.timeout}") int timeOut, @Value ("$ {spring.jedis.pool.password}") String Password) {return New Jedispool (config, host, puerto, tiempo de espera, contraseña); } @Bean (name = "Jediscoolconfig") public JedispoolConfig JedispoolConfig (@Value ("$ {spring.jedis.pool.config.maxtotal}") int maxtotal, @Value ("$ {spring.jedis.pool.config.maxidle}") int maxidle, @Value ("$ {spring.jedis.pool.config.maxwaitmillis}") int maxwaitmillis) {jedispoolconfig config = new JediscoolConfig (); config.setMaxtotal (Maxtotal); config.setMaxidle (maxidle); config.setMaxWaitMillis (maxWaitMillis); return config; }}4.3 Escritura de clase de metaanotación
Escribe una clase de meta anotación rediscache.java. Todas las clases definidas por la anotación modificada se implementan automáticamente en el procesamiento de caché AOP.
paquete org.muses.Jeepatform.annotation; import org.muses.Jeepatform.common.Rediscachenamespace; import java.lang.annotation.*;/***meta annotation se usa para identificar el método utilizado para consultar la dataBase*/@documented@objetivo {// Rediscachenamespace Namespace ();} Además de la retención, hay otras tres anotaciones proporcionadas por JDK 5, a saber, Target, heredado y documentado. Según esto, podemos implementar meta anotaciones personalizadas
Establecemos redisCache en referencia en función del nivel de método del método.
1.CretentionPolicy. Fuente Este tipo de anotaciones solo se reserva en el nivel del código fuente y se ignorará durante la compilación.
2. RetentionPolicy.Class Este tipo de anotaciones se conserva durante la compilación y existe en el archivo de clase, pero el JVM lo ignorará.
3. RetentionPolicy.
4.4 Llamar a Jedispool para implementar el procesamiento de caché de Redis
paquete org.muses.jeepatform.cache; import org.springframework.beans.factory.annotation.aUtowired; import org.springframework.stereotype.component; importar org.springframework.stereotype.service; import redis.clients.jediDis; import; import javax.annotation.resource; @Component ("Rediscache") Public Class Rediscache {@aUtowired privado Jedispool Jedispool; privado Jedispool getJedispool () {return jedispool; } public void setJedispool (Jedispool Jedispool) {this.jedispool = jedispool; } / ** * Obtenga datos de Redis Cache * @param Rediskey * @return * / Public Object getDataFromredis (String Rediskey) {JEDIS JEDIS = JEDISPOOL.GETRESOURCE (); byte [] byteArray = jedis.get (rediskey.getBytes ()); if (byteArray! = null) {return serializeUtil.unserialize (bytearray); } return null; } / ** * Guardar datos en Redis * @param Rediskey * / public String SaveDatatoredis (String RedisKey, Object obj) {byte [] bytes = serializeUtil.serialize (obj); JEDIS JEDIS = JEDISPOOL.GETRESOURCE (); Código de cadena = jedis.set (rediskey.getBytes (), bytes); código de retorno; }}Clase de herramienta de serialización de objetos:
paquete org.muses.Jeepatform.cache; import java.io.*; public class SerializeUtil { / *** Object serialized* @param obj* @return* / public static byte [] serialize (object obj) {objectOutputStream oos = null; BytearRayOutputStream baos = null; intente {baos = new byteArRaReOutputStream (); oos = nuevo ObjectOutputStream (Baos); oos.writeObject (obj); byte [] byteArray = baos.tobytearray (); regresar bytearray; } catch (ioException e) {E.PrintStackTrace (); } return null; } / ** * Deserialize Object * @param bytearray * @return * / public static object Unserialize (byte [] bytearray) {bytearrayInputStream bais = null; intente {// deserializar a object BAIS = new ByteArrayInputStream (byteArray); ObjectInputStream OIS = new ObjectInputStream (BAIS); return ois.readObject (); } catch (Exception e) {E.PrintStackTrace (); } return null; }} Aquí recuerdo que las clases de VO deben implementar serializables
Por ejemplo, la clase de información del menú Vo, esta es una clase de entidad de mapeo de JPA
paquete org.muses.Jeepatform.core.entity.admin; import javax.persistence.*; import java.io.Serializable; import java.util.list;/*** @Description Información de la información del menú* @author nicky* @Date 17 de marzo de 2017*/ @name = "sys_menu") @entity sertements menú " / ** ID de menú ** / Private int Menuid; / ** ID Superior **/ Private int ParentId; / ** Nombre del menú **/ String private Menuname; / ** icono de menú **/ String private Menuicon; / ** URL de menú **/ String private MenuUrl; / ** Tipo de menú **/ Private String Menutype; / ** Menú orden **/ private String menuOrder; / ** Estado del menú **/ String private Menustatus; Lista privada <Menen> submenu; objetivo de cadena privada; Private Boolean Hassubmenu = falso; Menú público () {super (); } @Id @GeneratedValue (estrategia = generaciónType.identity) public int getMenuid () {return this.Menuid; } public void setMenuid (int menuid) {this.menuid = menuid; } @Column (longitud = 100) public int getParentId () {return parentId; } public void setParentId (int } @Column (longitud = 100) cadena pública getMenUname () {return this.MenUname; } public void setMenUname (String Menuname) {this.MenUname = MenUname; } @Column (longitud = 30) cadena pública getMenuiCon () {return this.MenuiCon; } public void setMenuiCon (String Menuicon) {this.MenuiCon = Menuicon; } @Column (longitud = 100) cadena pública getMenuurl () {return this.Menuurl; } public void setMenuUrl (String MenuUrl) {this.MenuUrl = MenuUrl; } @Column (longitud = 100) cadena pública getMenutype () {return this.menutype; } public void setMenutype (String Menutype) {this.Menutype = Menutype; } @Column (longitud = 10) cadena pública getMenuorder () {return MenuOrder; } public void setMenUorder (String MenuOrder) {this.MenUorder = MenuOrder; } @Column (longitud = 10) cadena pública getMenustatus () {return masustatus; } public void setMenustatus (String Menustatus) {this.Menustatus = Menustatus; } @Transient Public List <Sen> getSubMenu () {return Submenu; } public void setSubMenu (list <sen> submenu) {this.submenu = submenu; } public void settarget (Target de cadena) {this.target = target; } @Transient public String getTarget () {return Target; } public void sethassubmenu (boolean Hassubmenu) {this.hassubmenu = Hassubmenu; } @Transient public boolean gethassubmenu () {return Hassubmenu; }}4.5 Spring AOP implementa el caché de método que monitorea todo anotado por @Rediscache
Primero obtenga el caché de Redis. Si no puede consultarlo, consulte la base de datos MySQL y luego guárdela en el caché Redis. La próxima vez que consulte, llame directamente al caché de Redis.
paquete org.muses.jeepatform.cache; import org.aspectj.lang.procedingjoinpoint; import org.spectj.lang.annotation.around; import org.aspectj.lang.annotation.aspect; import org.aspectj.lang.annotation.pointcut; import org.slf4j.logger; import; import org.slf4j.loggerFactory; import org.springframework.beans.factory.annotation.aUtowired; import org.springframework.beanss.factory.annotation.qualifier; import org.springframework.sterotype.component;/*** aop implements redis cache process processing*/@componente@componente@componente@componente@componente@componente@componente Final logger logger = loggerFactory.getLogger (rediseSpect.class); @AUTOWIRED @QUALIFIER ("Rediscache") Rediscache Rediscache; /*** Métodos para interceptar todas las meta annotaciones Rediscache Annotations* /@PointCut (" @annotation (org.muses.Jeepatform.annotation.Rediscache)") public void PointCutMethod () {} /*** Para el procesamiento envolvente, primero obtenga el caché de Redis. Si no puede consultar, consulta la base de datos MySQL, * luego guárdelo en el caché redis * @param unkenpoint * @return */@around ("PointCutMethod ()") Objeto público en torno a (procedimiento de unión unión) {// anterior: Obtenga el caché de Redis // Primer parámetro de método de destino Long Tiempo de inicio = System.CurrentTimillis (););;;; String Applid = null; Objeto [] args = uniónPoint.getArgs (); if (args! = null && args.length> 0) {aplic = string.valueOf (args [0]); } // Obtenga la clase donde el método de destino se encuentra String Target Target = UnidPoint.GetTarget (). ToString className = Target.split ("@") [0]; // Obtener el nombre del método del método de destino String MethodName = unkenPoint.getSignature (). GetName (); // Formato de tecla Redis: Applid: Método Nombre String Rediskey = Applid + ":" + ClassName + "." + MethodName; Object obj = redisCache.getDataFromredis (rediskey); if (obj! = null) {logger.info ("************** Datos encontrados desde redis ****************"); Logger.info ("Redis Key Value:"+Rediskey); Logger.info ("Valor Redis Value:"+obj.ToString ()); regresar obj; } Long EndTime = System.CurrentTimemillis (); Logger.info ("Redis Cache AOP Tiempo de procesamiento:"+(Endtime-starttime)); Logger.info ("*************** No se encuentran datos en Redis ****************"); intente {obj = unkePoint.proced (); } catch (Throwable E) {E.PrintStackTrace (); } Logger.info ("*************** Comience a consultar datos de mysql ***************"); // Post-set: Guarde los datos encontrados en la base de datos a redis String Code = Rediscache.SavedatatorEdis (RedisKey, OBJ); if (code.equals ("ok")) {logger.info ("************** Los datos se guardaron correctamente en Redis Cache !!! ************"); Logger.info ("Redis Key Value:"+Rediskey); Logger.info ("Valor Redis Value:"+obj.ToString ()); } return obj; }}Luego llame a @rediscache para implementar caché
/ ** * Obtener información de menú a través de ID de menú * @param ID * @return */ @transactional @rediscache público público hindMenubyid (@redisCachekey int }
Los métodos que inician sesión en el sistema y luego agregan la anotación @Rediscache implementarán el procesamiento de caché redis
Puedes ver que Redis se guarda en caché
Código del proyecto: https://github.com/u014427391/Jeepatform
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.