Chapitre 1 Analyse des exigences
Il est prévu d'ajouter Redis pour implémenter le traitement du cache dans le projet open source de l'équipe. Étant donné que les fonctions commerciales ont été mises en œuvre en partie, en écrivant des classes d'outils Redis, puis en les référant, la quantité de modifications est importante et le découplage ne peut pas être réalisé, j'ai donc pensé à l'AOP (programmation orientée sectionnelle) du cadre de printemps.
Projet open source: https://github.com/u014427391/jeepatform
Chapitre 2 Introduction à Springboot
En tant que cadre open source important dans le domaine de Javaee Framework, Spring Framework joue un rôle important dans le développement d'applications d'entreprise. Dans le même temps, Spring Framework et ses sous-trames sont beaucoup, donc la quantité de connaissances est très large.
Springboot: Un sous-trame de Spring Framework, également appelé Microframework, est un framework lancé en 2014 qui facilite le développement de Spring Framework. Après avoir appris toutes les connaissances des cadres de printemps, les cadres de printemps nécessitent inévitablement beaucoup de XML. Si vous utilisez Springboot Frameworks, vous pouvez utiliser le développement d'annotation pour simplifier considérablement le développement en fonction des frameworks de printemps. Springboot utilise pleinement le mode de configuration de Javaconfig et le concept de "Convention est meilleur que la configuration", ce qui peut simplifier considérablement le développement d'applications Web et de services de repos basés sur SpringMVC.
Chapitre 3 Introduction à Redis
3.1 Installation et déploiement Redis (Linux)
Pour l'installation et le déploiement de Redis, veuillez vous référer à mon blog (Redis est écrit en fonction de C, alors installez le compilateur GCC avant l'installation): //www.vevb.com/article/79096.htm
3.2 Introduction à Redis
Redis est maintenant devenu l'une des bases de données en mémoire les plus populaires de la communauté du développement Web. Avec le développement rapide de Web2.0 et l'augmentation de la proportion de données semi-structurées, les sites Web ont de plus en plus de demandes de performances efficaces.
De plus, les grands sites Web ont généralement des centaines ou plus de serveurs Redis. En tant que système puissant, Redis a son propre usage, qu'il s'agisse d'un système de stockage, de file d'attente ou de cache.
Pour commencer avec Springboot Framework, veuillez vous référer à l'article précédent: http://www.vevb.com/article/111197.htm
Chapitre 4 Implémentation de Redis Cache
4.1 Le diagramme de structure suivant
Diagramme de structure du projet:
4.2 Configuration du fichier YML de Springboot
Ajoutez la configuration application.yml sous la ressource, où MySQL, Druid et Redis sont principalement configurés
Spring: DataSource: # Boutique de source de données principale: URL: jdbc: mysql: //127.0.0.1: 3306 / jeepaTform? com.alibaba.druid.pool.druiddatasource # Paramètres de pool de connexion druid: taille initiale: 5 min-idle: 5 max-active: 20 # configurer le temps pour obtenir le temps d'attente de connexion en attente max-wait: 60000 # # Configurer la façon dont il faut pour effectuer un intervalle de détection pour détecter les connexions de ralenti qui doivent être fermées, dans Milliseond Configurez le temps minimum pour survivre dans la piscine, en millisecondes min-exictable-idle-time-millis: 300000 # Oracle Veuillez utiliser Sélectionner 1 parmi la double validation-Queery: Sélectionnez 'x' Test-while-idle: True Test-on-Brow MAX-POOL-PRÉPARADET-STATATION-PERCONNEMENT-MIDE: 20 # Configurez les filtres pour la surveillance des statistiques interceptées. Après avoir supprimé l'interface de surveillance, SQL ne peut pas être compté, «Wall» est utilisé pour les filtres à pare-feu: stat, mur, slf4j # Open Mergesql Fonction via la propriété ConnectProperties; Slow SQL Records Connection-Properties: druid.stat.Mergesql = true; druid.stat.slowsqlmillis = 5000 # Merge Surveillant Données de plusieurs druiddatasource use-global-data-source-stat: true jpa: database: mysql HIBERNAT: show_sql: true format_sql: true ddl-aUto: show_sql: true format_sql: true ddl-aUt: Show_sql: true format_sql: true ddl-aUto: NAMING: Physical-Strategy: org.hibernate.boot.model.naming.physicalnamingsstrategystandImpl MVC: View: Prefix: / web-inf / jsp / suffixe: .jsp #JeDis Configuration jedis: pool: host: 127.0.0.0.1 Port: 6379 Mot de passe: Mot de passe MaxwaitMillis: 100000
Écrivez une classe de configuration pour démarrer la configuration Jedisconfig.java:
package org.ruses.jeepatform.config; import org.springframework.beans.factory.annotation.autowired; import org.springframework.beans.factory.annotation.qualifier; import org.springframework.beans.factory.annotation.value; importation; org.springframework.boot.autoconfigure.condition.conditionalonMissingBean; import org.springframework.boot.context.properties.configurationproperties; import org.springframework.contex redis.clients.jedis.jedispool; import redis.clients.jedis.jedispoolconfig; @configuration // @ configurationProperties (prefix = jedisconfig.jedis_prefix) public jedisconfig {// public static final string jedis_prefix = "jedis"; @Bean (name = "Jedispool") @autowired public Jedispool jedispool (@qualifier ("jedispoolconfig") jedispoolconfig config, @value ("$ {printemps.jedis.pool.host}") string host, @value ("$ {printemps.jedis.pool. @Value ("$ {printemps.jedis.pool.timeout}") int timeout, @value ("$ {printemps.jedis.pool.password}") Mot de passe de chaîne) {return new Jedispool (config, host, port, timeout, mot de passe); } @Bean (name = "Jedispoolconfig") public Jedispoolconfig jedispoolconfig (@value ("$ {printemps.jedis.pool.config.mextotal}") int maxtotal, @value ("$ {printemps.Jedis.pool.config.Maxidle}") int maxidle, @Value ("$ {printemps.jedis.pool.config.maxwaitmilis}") int maxwaitmilis) {JedispoolConfig config = new JedispoolConfig (); config.setMextotal (maxtotal); config.setMaxidle (maxidle); config.setMaxWaitMillis (MaxwaitMillis); return config; }}4.3 Écriture de classe de méta-annotation
Écrivez une classe d'annotation de méta rediscache.java. Toutes les classes définies par l'annotation modifiée sont automatiquement implémentées dans le traitement du cache AOP.
package org.ruses.jeepatform.annotation; import org.muses.jeepatform.common.recachenamespace; import java.lang.annotation. *; / ** * meta annotation est utilisé pour identifier la méthode utilisée pour interroger la base de données * / @ documentée @ cible (élémentTonce.Method) @retention {// rediscachenamespace namespace ();} En plus de la rétention, il y a trois autres annotations fournies par JDK 5, à savoir cible, héritée et documentée. Sur cette base, nous pouvons implémenter des annotations de méta personnalisées
Nous définissons Rediscache sur référence en fonction du niveau de méthode de la méthode.
1.RetentionPolicy.Source Ce type d'annotations n'est réservé qu'au niveau du code source et sera ignoré pendant la compilation.
2. RetentionPolicy.classe Ce type d'annotations est conservé pendant la compilation et existe dans le fichier de classe, mais le JVM l'ignorera.
3. RetentionPolicy.runtime Ce type d'annotations sera réservé par le JVM, afin qu'ils puissent être lus et utilisés par le JVM ou un autre code qui utilise des mécanismes de réflexion lors de l'exécution.
4.4 Appel Jedispool pour implémenter le traitement Redis Cache
package org.ruses.jeepatform.cache; import org.springframework.beans.factory.annotation.autowired; import org.springframework.sterreotype.component; import org.springframework.sterreteotype.service; import redis.client.jedis.jedis; import redeis.clients.Jedis.Jedispool; import; javax.annotation.resource; @Component ("rediscache") classe publique Rediscache {@autowired private jedispool jedispool; Jedispool privé getjeDispool () {return jedispool; } public void setJedispool (Jedispool jedispool) {this.jedispool = jedispool; } / ** * Obtenez les données de Redis Cache * @param rediskey * @return * / objet public getDataFromRedis (String rediskey) {Jedis Jedis = jedispool.getResource (); byte [] bytearray = jedis.get (rediskey.getBytes ()); if (bytearray! = null) {return serializeUtil.unserialize (bytearray); } return null; } / ** * Enregistrer les données sur redis * @param rediskey * / public String SavedatatorEdis (String rediskey, objet obj) {byte [] bytes = serializeUtil.serialize (obj); Jedis Jedis = jedispool.getResource (); String code = jedis.set (rediskey.getBytes (), bytes); code de retour; }}Classe d'outils de sérialisation des objets:
package org.muses.jeepaTform.cache; import java.io. *; public class serializeUtil {/ ** * objet sérialisé * @param obj * @return * / public static byte [] serialize (objet obj) {objectOutputStream oos = null; ByteArrayOutputStream baos = null; essayez {baos = new bytearrayoutputStream (); OOS = new ObjectOutputStream (BAOS); oos.writeObject (obj); Byte [] bytearray = baos.toByteArray (); retour bytearray; } catch (ioException e) {e.printStackTrace (); } return null; } / ** * désérialiser objet * @param bytearray * @return * / public static objet Unserialize (byte [] bytearray) {bytearrayInputStream bais = null; essayez {// désérialiser pour objet bais = new bytearrayInputStream (bytearray); ObjectInputStream oiS = new ObjectInputStream (bais); return ois.readObject (); } catch (exception e) {e.printStackTrace (); } return null; }} Ici, je me souviens que les classes VO doivent mettre en œuvre des sérialisables
Par exemple, les informations de menu VO Classe, il s'agit d'une classe d'entité de cartographie JPA
Package org.ruses.jeepatform.core.entity.admin; import javax.persistence. *; import java.io.serializable; import java.util.list; / ** * @description menu Information entity * @Author Nicky * @date marse 17, 2017 * / @ table (namelizer @ menu @ menu @ table @ trentepublic menu Menuil Iplules = "sys_menu") @ tarity / ** ID de menu ** / private int menuID; / ** ID supérieur ** / private int parentid; / ** Nom du menu ** / private String menuname; / ** Icône du menu ** / String privé menuIcon; / ** URL de menu ** / chaîne privée menuUrl; / ** Type de menu ** / menutype de chaîne privée; / ** Sort de menu ** / Menu de chaîne privée; / ** État du menu ** / chaîne privée Menustatus; LISTE PRIVATE <UNAY> SOMMENU; cible de chaîne privée; booléen privé hassubmenu = false; Menu public () {super (); } @Id @GeneratedValue (Strategy = GenerationType.Identity) public int getMenuid () {return this.menuid; } public void setMenuid (int menuID) {this.menuid = menuID; } @Column (longueur = 100) public int getParentId () {return parentid; } public void setParentId (int parentid) {this.parentid = parentid; } @Column (longueur = 100) String public getMenuname () {return this.menuname; } public void setMenuname (String menuname) {this.menuname = menuname; } @Column (longueur = 30) String public getMenuiCon () {return this.MenuiCon; } public void setMenuiCon (String menuIcon) {this.MenuiCon = menuIcon; } @Column (longueur = 100) String public getMenuurl () {return this.menuurl; } public void setMenuurl (String menuUrl) {this.menuurl = menuUrl; } @Column (longueur = 100) String public getMenutype () {return this.Menutype; } public void setMenutype (menutype de chaîne) {this.meutype = menutype; } @Column (longueur = 10) String public getMenuorder () {return menuder; } public void setMenuOrder (String menuOrder) {this.MenOrder = menuOrder; } @Column (Longueur = 10) String public getMenUstatus () {return Menustatus; } public void SetMenUstatus (String Menustatus) {this.menustatus = Menustatus; } @Transient Public List <ennu> getSubMenu () {return SubMenu; } public void setSubMenu (list <ennu> subMenu) {this.subMenu = subMenu; } public void Settarget (String Target) {this.target = cible; } @Transient Public String getTarget () {return Target; } public void sethassubmenu (booléen hassubmenu) {this.hassubmenu = hassubmenu; } @Transient Public Boolean GethassubMenu () {return hassubmenu; }}4.5 Spring AOP implémente le cache de méthode qui surveille tous annoté par @rediscache
Obtenez d'abord le cache de Redis. Si vous ne pouvez pas l'interroger, interrogez la base de données MySQL, puis enregistrez-la dans le cache Redis. La prochaine fois que vous interrogerez, appelez directement le cache Redis.
package org.muses.jeepatform.cache; import org.aspectj.lang.proceedingjoinpoint; import org.aspectj.lang.annotation.around; import org.aspectj.lang.annotation.aspect; import org.aspectj.lang.annotation.point; org.slf4j.loggerfactory; import org.springframework.beans.factory.annotation.autowired; import org.springframework.beans.factory.annotation.qualifier; import org.springframework.stereteoType.Cononent; / ** * aop implémente reded cache Process {private static final logger logger = loggerfactory.getLogger (redisaspect.class); @Autowired @Qualifier ("Rediscache") Rediscache privé Rediscache; / ** * Méthodes pour intercepter toutes les annotations de méta annotations rediscache * / @pointcut ("@ annotation (org.muses.jeepatform.annotation.rediscache)") public void PointCutMethod () {} / ** * Pour le traitement surround, obtenez d'abord le cache de redis. Si vous ne pouvez pas vous interroger, vous interrogez la base de données MySQL, * Enregistrez-la dans le cache redis * @param joinpoint * @return * / @around ("PointCutMethod ()") Objet public autour (ProcedingJoinpoint JOINPPOINT) {// Précédent: Obtenez le cache de redis // d'abord obtenir le paramètre de la méthode cible Long StartTime = System.Currenttimemillis (); String applid = null; Objet [] args = joinpoint.getArgs (); if (args! = null && args.length> 0) {applid = string.valueof (args [0]); } // Obtenez la classe où la méthode cible est située à la chaîne cible cible = joinpoint.getTarget (). ToString className = cible.split ("@") [0]; // Obtenez le nom de la méthode de la méthode cible Méthode Methodname = joinpoint.getSignature (). GetName (); // Reded Key Format: Applid: Method Name String rediskey = applid + ":" + classname + "." + méthodename; Objet obj = rediscache.getDataFromredis (rediskey); if (obj! = null) {logger.info ("************ Data trouvés à partir de redis ******************"); Logger.info ("Redis Key Value:" + Rediskey); Logger.info ("Redis Value Value:" + Obj.ToString ()); retour obj; } Long EndTime = System.CurrentTimeMillis (); Logger.info ("Redis Cache AOP Time Time:" + (Budtime Starttime)); Logger.info ("*************** Aucune donnée trouvée à partir de redis ****************"); try {obj = joinpoint.proceed (); } catch (throwable e) {e.printStackTrace (); } Logger.info ("*************** Démarrer les données de l'interrogation de MySQL *************"); // Post-set: Enregistrez les données trouvées dans la base de données pour redis String code = rediscache.savedatatorEdis (rediskey, obj); if (code.equals ("ok")) {logger.info ("************ Les données ont été enregistrées avec succès sur redis cache !!! ************"); Logger.info ("Redis Key Value:" + Rediskey); Logger.info ("Redis Value Value:" + Obj.ToString ()); } return obj; }}Puis appelez @rediscache pour implémenter le cache
/ ** * Obtenez des informations sur le menu via ID de menu * @param id * @return * / @Transactional @rediscache Menu public findMenuByid (@rediscachekey int id) {return menurepository.findMenubyMenuid (id); }Les méthodes qui se connectent au système puis ajouteront l'annotation @rediscache implémenteront le traitement du cache redis
Vous pouvez voir que redis est enregistré pour cache
Code du projet: https://github.com/u014427391/jeepatform
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.