Redis Series three-Spring boot how to use Redis to do caching and cache annotations Usage Summary __redis

Source: Internet
Author: User
Tags delete key delete cache redis server
1. Overview

This article describes how spring boot uses Redis for caching, how to customize the Redis cache (such as key expiration), and how spring boot initializes redis cache. Use specific code to introduce annotations such as @cacheable, @CacheEvict, @CachePut, @CacheConfig, and their properties. 2. Spring Boot integration Redis 2.1. Application.properties

Configuration Application.properties, contains the following information: Specify the type of cache Redis Server information please do not configure the Spring.cache.cache-names value, after which

# # Cache
# Spring.cache.cache-names=book1,book2
spring.cache.type=redis

# Redis (redisproperties)  
Spring.redis.database=0
spring.redis.host=192.168.188.7
spring.redis.password=
spring.redis.port= 6379
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0  
spring.redis.pool.max-active=100 
Spring.redis.pool.max-wait=-1
2.2. Configure startup Classes@EnableCaching: Start the cache reconfiguration Rediscachemanager, using the new configured values
@SpringBootApplication
@EnableCaching//Start cache public
class Cacheapplication {
    private static final Logger Log = Loggerfactory.getlogger (Cacheapplication.class);

    public static void Main (string[] args) {
        log.info ("Start cacheapplication ...");
        Springapplication.run (Cacheapplication.class, args);

    }

    /**
     * Reconfigure Rediscachemanager
     * @param rd
    /@Autowired public
    void Configrediscachemanger ( Rediscachemanager Rd) {
        rd.setdefaultexpiration (100L);
    }
}

After the above configuration, the Redis cache management object has been generated. The following is a brief description of how spring boot initializes the Redis cache. 2.3. Spring boot How to initialize Redis cache

Cache management Interface Org.springframework.cache.cachemanager,spring boot is the management of caching through this class. Redis the implementation class corresponding to this interface is Org.springframework.data.redis.cache.RedisCacheManager. The following describes how this class is generated.

First, after we configure the Application.properties spring.redis.* property @enablecaching, Spring executes the redisautoconfiguration, Initializing Redistemplate and Stringredistemplate

@Configuration @ConditionalOnClass ({jedisconnection.class, Redisoperations.class, jedis.class}) @ Enableconfigurationproperties (redisproperties.class) public class Redisautoconfiguration {/** * Standard Redis
 Configuration. * * @Configuration protected static class Redisconfiguration {... @Bean @ConditionalOnMissingBean (name = "Redis Template ") public Redistemplate<object, object> redistemplate (redisconnectionfactory REDISCONNECTIONFAC Tory) throws Unknownhostexception {redistemplate<object, object> template = new REDISTEMPLATE&L
        T;object, object> ();
        Template.setconnectionfactory (redisconnectionfactory);
    return template;
        @Bean @ConditionalOnMissingBean (stringredistemplate.class) public stringredistemplate stringredistemplate ( Redisconnectionfactory redisconnectionfactory) throws Unknownhostexception {Stringredistempla
     Te template = new stringredistemplate ();   Template.setconnectionfactory (redisconnectionfactory);
    return template;
 }

}

}

The

Then rediscacheconfiguration generates Rediscachemanager after the Redistemplate injection method generated by redisautoconfiguration.

@Configuration @AutoConfigureAfter (Redisautoconfiguration.class) @ConditionalOnBean (Redistemplate.class) @

    Conditionalonmissingbean (Cachemanager.class) @Conditional (Cachecondition.class) class Rediscacheconfiguration {

    Private final cacheproperties cacheproperties;

    Private final cachemanagercustomizers Customizerinvoker; Rediscacheconfiguration (cacheproperties cacheproperties, cachemanagercustomizers customizerInvoker) {This
        . cacheproperties = cacheproperties;
    This.customizerinvoker = Customizerinvoker; @Bean public Rediscachemanager CacheManager (Redistemplate<object, object> redistemplate) {RedisC
        Achemanager CacheManager = new Rediscachemanager (redistemplate);
        Cachemanager.setuseprefix (TRUE);
        list<string> cachenames = This.cacheProperties.getCacheNames ();
        if (!cachenames.isempty ()) {cachemanager.setcachenames (cachenames); Return This.customizerInvoker.customIze (CacheManager);
 }

}

Based on the above analysis, we know that spring has helped us build a Rediscachemanager and configured it.
Finally, we can configure this Rediscachemanager two times, only to list the validity period of the configuration key.

         /**
     * Reconfigure Rediscachemanager
     * @param rd
    /@Autowired public
    void Configrediscachemanger ( Rediscachemanager Rd) {
        rd.setdefaultexpiration (100L);
    }

Attention:
Please do not configure in Applicaion.properties: Spring.cache.cache-names=book1,book2, otherwise our new configuration will not function on the cache of these configurations. This is because rediscacheconfiguration initializes the Rediscachemanager and immediately invokes the Rediscacheconfiguration's initialization cache. At this point, Configrediscachemanger has not yet implemented this method, so that our configuration cannot be restarted. Conversely, if not configured, then the cache will be created, using our configuration. 3. Use of spring cache annotations

The previous section describes how to configure caching, which describes how to use caching. 3.1 Auxiliary Classes

Auxiliary classes to be used below

Book:

public class Book implements Serializable {
    private static final long serialversionuid = 2629983876059197650L;

    Private String ID;
    private String name; Title
    Private Integer Price//Prices
    Private Date Update//Public book 

    (string ID, string name, integer value, Date update) {
        super ();
        This.id = ID;
        this.name = name;
        This.price = Price;
        this.update = update;
    }
    Set/get
}

Bookqry: Encapsulation Request Class

public class Bookqry {
    private String ID;
    private String name; Title

    //Set/get

Abstractservice
Abstract class: Initializes the Repositorybook value and simulates the database data. Both Bookservice and BookService2 inherit this class

Public abstract class Abstractservice {

    protected static map<string, book> Repositorybook = new hashmap<> ();

    Public Abstractservice () {
        super ();
    }

    @PostConstruct public
    void init () {
        //1 The book
        Book1 = new book ("1", "Name_1", One, New Date ());
        Repositorybook.put (Book1.getid (), Book1);
        2 book
        book2 = new book ("2", "name_2", One, New Date ());
        Repositorybook.put (Book2.getid (), book2);
        3 book
        book3 = new book ("3", "Name_3", One, New Date ());
        Repositorybook.put (Book3.getid (), BOOK3);
        4 book
        book4 = new book ("4", "Name_4", One, New Date ());
        Repositorybook.put (Book4.getid (), BOOK4);
    }

3.2. @Cacheable

The meaning of a @Cacheable property Cachenames: Specifies the cached name key: Defines the key value that is composed, and if not defined, computes a key value with all parameters. You can use the spring El expression

    /** * Cachenames Set Cached value * Key: Specifies the cached key, which refers to the parameter ID value. Key can use the SPEL expression * @param ID * @return/@Cacheable (cachenames= "Book1", key= "#id") Public book Query
        Bookcacheable (String ID) {logger.info ("querybookcacheable,id={}", id);
    return Repositorybook.get (ID); /** * This uses another cache storage cache * * @param ID * @return/@Cacheable (cachenames= "Book2", key= "#i
        D ") Public book querybookcacheable_2 (String ID) {logger.info (" querybookcacheable_2,id={} ", id);
    return Repositorybook.get (ID); /** * Cached Key can also specify the object's member variable * @param qry * @return/@Cacheable (cachenames= "Book1", key= "#qry . ID ") Public book Querybookcacheablebybookqry (Bookqry qry) {logger.info (" querybookcacheablebybookqry,qry={} ", q
        RY);
        String id = qry.getid ();
        Assert.notnull (ID, "ID can ' t be null!");
        String name = Qry.getname ();
        Book book = null;
  if (ID!= null) {          Book = Repositorybook.get (ID); if (book!= null &&!) (
            Name!= null && book.getname (). Equals (name)) {book = null;
    } return book; }
Keygenerator: Defines the class that the key generates and cannot exist simultaneously with the key
    /**
     * Above we use the default keygenerator, corresponding to spring simplekeygenerator 
     *  If your use is complex, we can also customize the mykeygenerator generated key
     *  Key and Keygenerator are mutually exclusive, and if both are made the exception
     * The key and  keygenerator parameters are mutually exclusive and an operation specifying both to the exception.
     * * 
     @param ID
     * @return
    /@Cacheable (cachenames= "Book3",  keygenerator= "Mykeygenerator") Public book
    Querybookcacheableusemykeygenerator (String id) {
        logger.info (" querybookcacheableusemykeygenerator,id={} ", id);
        return Repositorybook.get (ID);
    }

The build class for the custom cache key is implemented as follows:
@Component public
class Mykeygenerator implements Keygenerator {

    @Override
    public object generate (object target, Method method, Object ... params) {
        System.out.println ("Custom cache, using the first parameter as the cache key.") params = "+ arrays.tostring (params));
        Just for testing, it's not possible to write return
        Params[0] + "0";
    }

}
Sync: If you set sync=true:a. If there is no data in the cache and multiple threads access the method at the same time, only one method executes to the method, and other methods need to wait; B. If there is already data in the cache, multiple threads can retrieve data from the cache at the same time
    /***
     * If you set sync=true,
     *  If there is no data in the cache and multiple threads access the method at the same time, then only one method executes to the method, and the other methods need to wait
     *  If there is already data in the cache, Multiple threads can get data from the cache at the same time
     * @param ID
     * @return
    /@Cacheable (cachenames= "Book3", sync=true)
    public Book Querybookcacheablewithsync (String id) {
        logger.info ("Begin ... querybookcacheablebybookqry,id={}", id);
        try {
            Thread.Sleep (1000 * 2);
        } catch (Interruptedexception e) {
        }
        logger.info ("End ...). querybookcacheablebybookqry,id={} ", id);
        return Repositorybook.get (ID);
    }
Condition and unless cache only for specific conditions:
Condition: The condition value is true before the method is executed, and the data unless is cached: After the method is executed, the unless is judged, and if the value is true, the data conditon and unless can be used at the same time. Then only the records that satisfy both are cached at this time
    /**
     * Condition cache:
     * Only meet the condition request can be cached, if not meet the criteria, the method is not @cacheable annotations like the method
     * The  following is only ID < 3 to cache
     * 
     * *
    @Cacheable (cachenames= "book11", condition= "T (Java.lang.Integer). parseint (#id) < 3") public
    Book Querybookcacheablewithcondition (String id) {
        logger.info ("querybookcacheablebybookqry,id={}", id);
        return Repositorybook.get (ID);
    }

    /**
     * Condition cache:
     * cache for records that do not meet unless
     *  "unless expressions" are evaluated after the method has been Ed
     *  as follows: Only cache records that do not meet the return ' T (Java.lang.Integer). parseint (#result. ID) <3 ' *
     @param ID
     * @return
     * *
    @Cacheable (cachenames= "book22", unless = "T (java.lang.Integer). parseint (#result. Id) <3")
    Public book querybookcacheablewithunless (String id) {
        logger.info ("querybookcacheablebybookqry,id={}", id);
        return Repositorybook.get (ID);
    }
3.3. @CacheEvict

Delete Cache Allentries = true: Empty all values in the cache Book1 Allentries = false: Default value, just delete key's corresponding value

    /**
     * allentries = true: Empty all caches in Book1
    /@CacheEvict (cachenames= "Book1", allentries=true)
    public void Clearbook1all () {
        logger.info ("ClearAll");
    }
    /**
     * Book1 remove
    /@CacheEvict (cachenames= "Book1", key= "#id") public
    void on records that meet key conditions from the cache Updatebook (string ID, string name) {
        logger.info ("Updatebook");
        Book book = Repositorybook.get (ID);
        if (book!= null) {
            book.setname (name);
            Book.setupdate (New Date ());
        }
    
3.4. @CachePut

Each execution executes a method, regardless of whether there is a value in the cache, and the value in the replacement cache of the new return value is used. This differs from @cacheable: @Cacheable If the cache does not have a value, executes the method and caches the data, and if the cache has a value, gets the value from the cache

    @CachePut (cachenames= "Book1", key= "#id") Public book
    Querybookcacheput (String id) {
        logger.info (" querybookcacheput,id={} ", id);
        return Repositorybook.get (ID);
    }
3.5. @CacheConfig

@CacheConfig: Class-level annotations: If we define cachenames in this note, all methods in this class @Cacheable cachenames defaults to this value. Of course @cacheable can also redefine the value of Cachenames

@Component
@CacheConfig (cachenames= "Booksall") public 
class BookService2 extends Abstractservice {
    private static final Logger Logger = Loggerfactory.getlogger (bookservice2.class);

    /**
     * The @cacheable of this method does not define Cachenames, then use the value in the annotation @cacheconfig on the class cachenames
     * @param ID
     * @return
    @Cacheable (key= "#id") Public book
    querybookcacheable (String id) {
        logger.info ("querybookcacheable,id={}") ID);
        return Repositorybook.get (ID);
    }

    /**
     * The @cacheable of this method has a defined cachenames, the value in the class annotation @cacheconfig is overwritten with this value cachenames
     * 
     @param ID
     * @return
     *
    /@Cacheable (cachenames= "Books_custom", key= "#id") Public book
    QueryBookCacheable2 (String ID) {
        logger.info ("querybookcacheable2,id={}", id);
        return Repositorybook.get (ID);
    }

4. Test 4.1. Prepare Redis

Can be installed through the Docker Redis, very convenient. Docker usage See Docker installation and common commands 4.2. Test class

If you want to verify each of these methods, you can download the project and execute the test class cachetest. This is not a demo because it's simpler. 5. Code

Detailed code for this article github

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.