Springboot integrated Redis for cache processing (Spring AOP implementation)

Source: Internet
Author: User
Tags object serialization

Chapter One Requirements Analysis

Plan to add Redis to the team's open source project for cache processing because the business functions have been partially implemented, by writing the Redis tool class, then referencing, altering the volume, and not decoupling, so think of the spring framework AOP (aspect-oriented programming).
Open Source project: Https://github.com/u014427391/jeeplatform
Welcome to Star (collection)

Chapter II Introduction to Springboot

Spring Framework, as an important open-source framework in Java EE Framework, plays an important role in enterprise application development, and the spring framework and its sub-frameworks are many, so the amount of knowledge is very wide.
Springboot: The sub-framework of a spring framework, also known as a micro-framework, is a framework that was introduced in 2014 to make the spring framework easier to develop. Having learned the knowledge of the spring framework, it is difficult to avoid the need to configure a lot of XML, and with the Springboot framework, annotation development can be used to greatly simplify the development of spring-based frameworks. Springboot leverages the Javaconfig configuration model and the concept of "contract better than configuration" to greatly simplify the development of SPRINGMVC-based Web applications and rest services.

Chapter III Redis Introduction 3.1 Redis Installation Deployment (Linux)

Redis installation Deployment can refer to my blog (Redis is written based on C, so install the GCC compiler before installing): http://blog.csdn.net/u014427391/article/details/71210989

About 3.2 Redis

Redis is now one of the hottest memory databases in the Web development community, and with the rapid development of Web2.0, coupled with the increased proportion of semi-structured data, there is a growing demand for high-performance Web sites.
And large websites typically have hundreds of or more Redis servers. As a powerful system, Redis has its own niche, whether it's a storage, queue, or cache system.

Springboot Framework Primer can refer to my previous blog: http://blog.csdn.net/u014427391/article/details/70655332

Fourth Redis cache implementation 4.1 The following structure diagram

Project Structure diagram:

4.2 Springboot's Yml file configuration

Add resource below the APPLICATION.YML configuration, here the main configuration Mysql,druid,redis

Spring:datasource: # main Data source Shop:url:jdbc:mysql://127.0.0.1:3306/jeeplatform?autoreconnect=true&useunicod    E=true&characterencoding=utf8&charactersetresults=utf8&usessl=false Username:root Password:root Driver-class-name:com.mysql.jdbc.driver Type:com.alibaba.druid.pool.DruidDataSource # Connection Pool settings Druid:initia L-size:5 min-idle:5 max-active:20 # Configuration Get connection Wait time out max-wait:60000 # configuration interval How often do you check for idle connections that need to be closed? The unit is in milliseconds time-between-eviction-runs-millis:60000 # configures the minimum lifetime of a connection in the pool, in milliseconds min-evictable-idle-time-millis:300 Oracle please use SELECT 1 from dual validation-query:select ' x ' test-while-idle:true test-on-borrow:f Alse Test-on-return:false # Open Pscache, and specify the Pscache size on each connection pool-prepared-statements:true Max-pool-pre      PARED-STATEMENT-PER-CONNECTION-SIZE:20 # Configure monitoring Statistics intercept filters, remove post-monitoring interface SQL cannot be counted, ' wall ' for firewalls filters:stat,wall,slf4j # by ConnectpropertieS property to open Mergesql function; Slow SQL record connection-properties:druid.stat.mergesql=true;druid.stat.slowsqlmillis=5000 # merge multiple Drui Ddatasource monitoring data use-global-data-source-stat:true jpa:database:mysql hibernate:show_sql:true fo Rmat_sql:true Ddl-auto:none Naming:physical-strategy:org.hibernate.boot.model.naming.physicalnamingst Rategystandardimpl mvc:view:prefix:/web-inf/jsp/suffix:. JSP #Jedis配置 Jedis:pool:host:12         7.0.0.1 port:6379 Password:password timeout:0 config:maxtotal:100 maxidle:10 maxwaitmillis:100000

Write a configuration class startup configuration Jedisconfig.java:

Package Org.muses.jeeplatform.config;import Org.springframework.beans.factory.annotation.autowired;import Org.springframework.beans.factory.annotation.qualifier;import Org.springframework.beans.factory.annotation.value;import Org.springframework.boot.autoconfigure.condition.conditionalonmissingbean;import Org.springframework.boot.context.properties.configurationproperties;import Org.springframework.context.annotation.bean;import Org.springframework.context.annotation.configuration;import Redis.clients.jedis.jedispool;import redis.clients.jedis.JedisPoolConfig; @Configuration//@ Configurationproperties (prefix = jedisconfig.jedis_prefix) public class Jedisconfig {//public static final String JEDI    S_prefix = "Jedis";                                    @Bean (name= "Jedispool") @Autowired public Jedispool Jedispool (@Qualifier ("jedispoolconfig") jedispoolconfig config, @Value ("${spring.jedis.pool.host}") String host, @Valu E ("${spring.jedis.pool.port}") int port, @Value (" ${spring.jedis.pool.timeout} ") int timeout, @Value ("${spring.jedis.pool.password}") String password) {return new Jedispool (config, host, port,time    Out,password); } @Bean (name= "Jedispoolconfig") 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 Jedispoolconfig ();            Config.setmaxtotal (maxtotal);            Config.setmaxidle (Maxidle);            Config.setmaxwaitmillis (Maxwaitmillis);        return config; }}
4.3 USD annotation class writing

Write a meta-annotation class Rediscache.java, the classes defined by the annotation are automatically implemented with AOP caching

package org.muses.jeeplatform.annotation;import org.muses.jeeplatform.common.RedisCacheNamespace;import java.lang.annotation.*;/** * 元注解 用来标识查询数据库的方法 */@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface RedisCache {//    RedisCacheNamespace nameSpace();}

The annotations provided by JDK 5, in addition to retention, have three other, target, inherited, and documented. Based on this, we can implement the custom meta-annotations
We set Rediscache based on method-level references.

1.retentionpolicy.source This type of annotations is preserved only at the source level and is ignored at compile time
2.retentionpolicy.class This type of annotations is preserved at compile time and exists in the CLASS file, but the JVM ignores
3.retentionpolicy.runtime This type of annotations will be retained by the JVM, so they can be read and used by the JVM or other code that uses the reflection mechanism at runtime.

4.4 Calling Jedispool for Redis cache processing
Package Org.muses.jeeplatform.cache;import Org.springframework.beans.factory.annotation.autowired;import Org.springframework.stereotype.component;import Org.springframework.stereotype.service;import Redis.clients.jedis.jedis;import redis.clients.jedis.jedispool;import Javax.annotation.Resource; @Component ("        Rediscache ") public class Rediscache {@Autowired private jedispool jedispool;    Private Jedispool Getjedispool () {return jedispool;    } public void Setjedispool (Jedispool jedispool) {this.jedispool = Jedispool; /** * Get data from Redis cache * @param rediskey * @return */public Object Getdatafromredis (String redisk        EY) {Jedis Jedis = Jedispool.getresource ();                byte[] ByteArray = Jedis.get (Rediskey.getbytes ());        if (ByteArray! = null) {return serializeutil.unserialize (ByteArray);    } return null; /** * Save data to Redis * @param rediskey */public String SavedatatOredis (String rediskey,object obj) {byte[] bytes = serializeutil.serialize (obj);                Jedis Jedis = Jedispool.getresource ();                String code = Jedis.set (rediskey.getbytes (), bytes);    return code; }    }

Tool class for object serialization:

Package Org.muses.jeeplatform.cache;import java.io.*;p ublic class Serializeutil {/** * Serialized object * @param obj        * @return */public static byte[] Serialize (Object obj) {ObjectOutputStream oos = null;        Bytearrayoutputstream BAOs = null;            try{BAOs = new Bytearrayoutputstream ();                        Oos = new ObjectOutputStream (BAOs);            Oos.writeobject (obj);            byte[] ByteArray = Baos.tobytearray ();                    return byteArray;        }catch (IOException e) {e.printstacktrace ();    } return null; }/** * Deserialize object * @param byteArray * @return * * * public static object Unserialize (byte[] ByteArray        ) {Bytearrayinputstream Bais = null;            try {//Deserialize to Object Bais = new Bytearrayinputstream (ByteArray);            ObjectInputStream ois = new ObjectInputStream (Bais);                    return Ois.readobject (); } catch (Exception E) {e.printstacktrace ();    } return null; }    }

Here remember that VO classes are implemented serializable
such as menu information Vo class, which is a JPA-mapped entity class

Package Org.muses.jeeplatform.core.entity.admin;import Javax.persistence.*;import Java.io.serializable;import java.util.list;/** * @description Menu Information Entity * @author Nicky * @date March 17, 2017 * * @Table (name= "Sys_menu") @Entitypublic class M        ENU implements Serializable {/** menu id**/private int menuId;        /** Superior id**/private int parentid;        /** Menu Name **/private String menuName;        /** menu icon **/private String Menuicon;        /** Menu url**/private String menuurl;        /** Menu Type **/private String menutype;    /** Menu Sort **/private String menuorder;    /** Menu State **/private String menustatus;    Private List<menu> submenu;    Private String target;    Private Boolean hassubmenu = false;    Public Menu () {super (); } @Id @GeneratedValue (strategy=generationtype.identity) public int getmenuid () {return this.menuid    ;    } public void Setmenuid (int menuId) {this.menuid = MenuId; } @Column (length=100) public INT Getparentid () {return parentid;    } public void Setparentid (int parentid) {this.parentid = ParentID;    } @Column (length=100) public String getmenuname () {return this.menuname;    } public void Setmenuname (String menuName) {this.menuname = MenuName;    } @Column (length=30) public String Getmenuicon () {return this.menuicon;    } public void Setmenuicon (String menuicon) {This.menuicon = Menuicon;    } @Column (length=100) public String Getmenuurl () {return this.menuurl;    } public void Setmenuurl (String menuurl) {this.menuurl = Menuurl;    } @Column (length=100) public String Getmenutype () {return this.menutype;    } public void Setmenutype (String menutype) {this.menutype = Menutype;    } @Column (length=10) public String Getmenuorder () {return menuorder; } public void Setmenuorder (String menuorder) {This.menuorder = MenUorder;    } @Column (length=10) public String getmenustatus () {return menustatus;    } public void Setmenustatus (String menustatus) {this.menustatus = Menustatus;    } @Transient Public list<menu> GetSubMenu () {return submenu;    } public void Setsubmenu (List<menu> submenu) {this.submenu = submenu;    The public void Settarget (String target) {this.target = target;    } @Transient Public String Gettarget () {return target;    The public void Sethassubmenu (Boolean hassubmenu) {this.hassubmenu = Hassubmenu;    } @Transient public Boolean gethassubmenu () {return hassubmenu; }}
4.5 Spring AOP implements a method cache that monitors all @rediscache annotations

Get the cache from Redis first, query the MySQL database, and then save it to the Redis cache, and call the Redis cache at the next query

Package Org.muses.jeeplatform.cache;import Org.aspectj.lang.proceedingjoinpoint;import Org.aspectj.lang.annotation.around;import Org.aspectj.lang.annotation.aspect;import Org.aspectj.lang.annotation.pointcut;import Org.slf4j.logger;import Org.slf4j.loggerfactory;import Org.springframework.beans.factory.annotation.autowired;import Org.springframework.beans.factory.annotation.qualifier;import org.springframework.stereotype.component;/** * AOP implements REDIS Cache processing */@Component @aspectpublic class Redisaspect {private static final Logger Logger = Loggerfactory.getlogg    ER (redisaspect.class);    @Autowired @Qualifier ("Rediscache") private Rediscache Rediscache;  /** * method of intercepting all meta annotations rediscache annotations */@Pointcut ("@annotation (Org.muses.jeeplatform.annotation.RedisCache)") public     void Pointcutmethod () {}/** * surround processing, get the cache from Redis first, query the MySQL database, and then save it in the Redis cache * @param joinpoint * @return */@Around ("Pointcutmethod ()") Public Object Around (PROCEEDINGJOINPOint joinpoint) {//Front: Get cache from Redis//Get target method parameter long StartTime = System.currenttimemillis ();        String applid = null;        object[] args = Joinpoint.getargs ();        if (args! = null && args.length > 0) {applid = string.valueof (Args[0]);        }//Gets the target method in the same class as String target = Joinpoint.gettarget (). toString ();        String className = Target.split ("@") [0];        Gets the method name of the target method String MethodName = Joinpoint.getsignature (). GetName ();        Redis in key format: Applid: Method name String Rediskey = applid + ":" + ClassName + "." + MethodName;        Object obj = Rediscache.getdatafromredis (Rediskey);            if (obj!=null) {logger.info ("********** found data ********** from Redis");            Logger.info ("Key value for Redis:" +rediskey);            Logger.info ("Value for Redis:" +obj.tostring ());        return obj;        } Long EndTime = System.currenttimemillis ();  Logger.info ("Redis Cache AOP Processing Time:" + (Endtime-starttime));      Logger.info ("********** did not find data ********** from Redis");        try{obj = Joinpoint.proceed ();        }catch (Throwable e) {e.printstacktrace ();        } logger.info ("********** start querying data from MySQL **********");        Post: Save data from database to Redis String code = Rediscache.savedatatoredis (rediskey,obj); if (Code.equals ("OK")) {Logger.info ("********** data was successfully saved to the REDIS cache!!!            **********");            Logger.info ("Key value for Redis:" +rediskey);        Logger.info ("Value for Redis:" +obj.tostring ());    } return obj; }}

Then call @rediscache to implement the cache

/**     * 通过菜单Id获取菜单信息     * @param id     * @return     */    @Transactional    @RedisCache    public Menu findMenuById(@RedisCacheKey int id){        return menuRepository.findMenuByMenuId(id);    }

The method of logging in to the system and then adding @rediscache annotations will implement Redis cache processing

You can see that the Redis is saved to the cache

Project code: Https://github.com/u014427391/jeeplatform, Welcome to GitHub on Star (collection)

Springboot integrated Redis for cache processing (Spring AOP implementation)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.