The test here can be used directly in the project, and can be copied and used mindlessly!

1. Configuration depends on POM.xml

<dependencies>
   <! - redis dependence - >
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
      <version>At 2.0.5. RELEASE</version>
   </dependency>
   <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
   </dependency>

   <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
       <version>1.16.18</version>
      <optional>true</optional>
   </dependency>

   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>At 2.0.5. RELEASE</version>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>At 2.0.5. RELEASE</version>
      <scope>provided</scope>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <version>At 2.0.5. RELEASE</version>
      <scope>test</scope>
   </dependency>

   <! - integration swagger - API - >
   <dependency>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-models</artifactId>
      <version>1.5.21</version>
      <scope>compile</scope>
   </dependency>
   <dependency>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-annotations</artifactId>
      <version>1.5.21</version>
      <scope>compile</scope>
   </dependency>
   <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>2.9.2</version>
   </dependency>
   <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>2.9.2</version>
      <exclusions>
         <exclusion>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
         </exclusion>
         <exclusion>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
         </exclusion>
      </exclusions>
   </dependency>
   </dependencies>

Copy the code

2. Redis configures application.yml

The main configuration file is used to store common Settings and is not affected by the environment configuration
server:
  port: 8080
  servlet:
    context-path: /springboot-test-redis2
spring:
  redis:
    database: 6   # Redis database index (default 0)
    host: 127.0. 01.  # Redis server address
    port: 6379         # Redis server connection port
    password:    # Redis server connection password (default null)
    max-wait: 30000    Maximum connection pool blocking wait time (negative value indicates no limit)
    max-active: 100   # maximum number of connections in the pool (use negative values to indicate no limit)
    max-idle: 20     The maximum number of free connections in the connection pool
    min-idle: 0     Minimum free connection in connection pool
    timeout: 5000  Connection timeout (ms)
  # Custom configuration
  redis2:
    database: 5   # Redis database index (default 0)
    host: 192.1682.169.  127.0.0.1 local Redis is also available for testing, since the database index library is not the same
    port: 6379         # Redis server connection port
    password:    # Redis server connection password (default null)
    timeout: 5000  Connection timeout (ms)
    
Copy the code

3. Configure redis multi-instance in the config file

RedisConfig.ava

package com.dist.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.ObjectUtils;

import java.time.Duration;

/** Set the base class for Redis multi-instance *@author [email protected]
 * @data2019/7/29 10:17 * /
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport{

    /** * Data source 1 default configuration (127.0.0.1) redis template **@param redisConnectionFactory
     * @return* /
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return createRedisTemplate(redisConnectionFactory);
    }

    /** * data source 2 redis template */
    @Bean
    public RedisTemplate redisTemplate2(
            @Value("${spring.redis2.database}") int database,
            @Value("${spring.redis.timeout}") long timeout,
            @Value("${spring.redis.max-active}") int maxActive,
            @Value("${spring.redis.max-wait}") int maxWait,
            @Value("${spring.redis.max-idle}") int maxIdle,
            @Value("${spring.redis.min-idle}") int minIdle,

            @Value("${spring.redis2.host}") String hostName,
            @Value("${spring.redis2.port}") int port,
            @Value("${spring.redis2.password}") String password) {

        /* ========= Basic configuration ========= */
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName(hostName);
        configuration.setPort(port);
        configuration.setDatabase(database);
        if(! ObjectUtils.isEmpty(password)) { RedisPassword redisPassword = RedisPassword.of(password); configuration.setPassword(redisPassword); }/* ========= Universal connection pool configuration ========= */
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMinIdle(minIdle);
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);

        /* ========= jedis pool ========= */
        /* JedisClientConfiguration.DefaultJedisClientConfigurationBuilder builder = (JedisClientConfiguration.DefaultJedisClientConfigurationBuilder) JedisClientConfiguration .builder(); builder.connectTimeout(Duration.ofSeconds(timeout)); builder.usePooling(); builder.poolConfig(genericObjectPoolConfig); JedisConnectionFactory connectionFactory = new JedisConnectionFactory(configuration, builder.build()); / / the connection pool initialization connectionFactory. AfterPropertiesSet (); * /

        /* ========= lettuce pool ========= */
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();
        builder.poolConfig(genericObjectPoolConfig);
        builder.commandTimeout(Duration.ofSeconds(timeout));
        LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, builder.build());
        connectionFactory.afterPropertiesSet();

        /* ========= create template ========= */
        return createRedisTemplate(connectionFactory);
    }

    /** ** redisTemplate * <p> * this method cannot be added@BeanOtherwise, connectionFactory will be the default no matter how it is called@param redisConnectionFactory
     * @return* /
    public RedisTemplate createRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

/* Redis connection pool: oracle, Jedis: Jedis is implemented as a direct connection to the Redis server. If the connection pool is not thread safe in a multi-threaded environment, then the only way to add a physical connection to each Jedis instance is to use the connection pool: The connection is Netty based, and StatefulRedisConnection can be accessed concurrently between multiple threads. The StatefulRedisConnection is thread-safe. Therefore, a StatefulRedisConnection can satisfy concurrent access in a multi-threaded environment. Of course, this is also a scalable design. If a connection instance is not enough, it can also be added as needed. Lettuce mainly uses Netty to implement synchronous and asynchronous communication with Redis. * /
}

Copy the code

4. Configure Swagger2Config

For testing the interface, good debugging.

package com.dist.config;

import com.google.common.base.Predicate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/ * * *@author yangmin
 * @date 2018/8/15
 * @desc* /
@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    public Docket adminApi(a){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("Admin API")
                .forCodeGeneration(true)
                .pathMapping("/")
                .select()
                .paths(paths())
                .build()
                .apiInfo(apiInfo())
                .useDefaultResponseMessages(false);
    }

    private Predicate<String> paths(a){
        return PathSelectors.regex("^ /? ! error).*$");
    }

    private ApiInfo apiInfo(a){
        Contact contact = new Contact("BaiDu"."controller://baidu.com"." [email protected]");
        return new ApiInfoBuilder()
                .title("Personal SpringBoot Test System")
                .description("Develop API documentation")
                .contact(contact)
                .version("1.0") .build(); }}Copy the code

5. Configure the Redis utility class

You need to configure two copies, each corresponding to a different data source.

1. Tool class corresponding to data source 1: redisutil-redistemplate
package com.dist.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/** * redisTemplate wraps by default *@author [email protected]
 * @data2019/7/29 10:17 * /
@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /** * Common cache fetch *@paramThe key key *@returnValue * /
    public Object get(String key){
        return key==null?null:redisTemplate.opsForValue().get(key);
    }

    /** * Normal cache into *@paramThe key key *@paramThe value value *@returnTrue Successful false failed */
    public boolean set(String key,Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}}Copy the code
2. The corresponding utility class of data source 1: Redisutil2-redistemplate2
package com.dist.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/** * Data source 2 redisTemplate2 encapsulates *@author [email protected]
 * @data2019/7/29 10:17 * /
@Component
public class RedisUtil2 {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate2;

    public RedisUtil2(RedisTemplate<String, Object> redisTemplate2) {
        this.redisTemplate2 = redisTemplate2;
    }

    /** * Common cache fetch *@paramThe key key *@returnValue * /
    public Object get(String key){
        return key==null?null:redisTemplate2.opsForValue().get(key);
    }

    /** * Normal cache into *@paramThe key key *@paramThe value value *@returnTrue Successful false failed */
    public boolean set(String key,Object value) {
        try {
            redisTemplate2.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}}Copy the code

6. Test the Redis configuration for dual data sources

Controller. Java interface layer

package com.dist.controller;

import com.dist.util.RedisUtil;
import com.dist.util.RedisUtil2;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/ * * *@author [email protected]
 * @data2019/7/29 he * /
@Api(tags = {"RedisController"},description = "Redis dual data source Test")
@RequestMapping(value = "rest/redis")
@RestController
@Slf4j
public class RedisController {

    /** * encapsulated utility class: default 127.0.0.1 */
    @Autowired
    RedisUtil redisUtil;

    /** * Encapsulated tool class 2:192.168.2.169 */
    @Autowired
    RedisUtil2 redisUtil2;

    @ApiOperation(value = "Redis data source 1",httpMethod = "GET")
    @RequestMapping(value = "v1/redis1",method = RequestMethod.GET)
    public Object redis1(@ApiParam(value = "Reids key value") @RequestParam String key,
                         @ApiParam(value = "Redis value value") @RequestParam String value){
        boolean set = redisUtil.set(key, value);
        log.info("Save result:"+set);
        if (set){
            return redisUtil.get(key);
        }
        return null;
    }

    @ApiOperation(value = "Redis Source 2",httpMethod = "GET")
    @RequestMapping(value = "v2/redis2",method = RequestMethod.GET)
    public Object redis2(@ApiParam(value = "Reids key value") @RequestParam String key,
                         @ApiParam(value = "Redis value value") @RequestParam String value){
        boolean set = redisUtil2.set(key, value);
        log.info("Save result:"+set);
        if (set){
            return redisUtil2.get(key);
        }
        return null; }}Copy the code

7. Start swagger page test

#####1. Create index.html under resources/static as follows: index.html


      
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>springboot-test-redis2</title>
</head>
<body>
<h1>page</h1>

<h2>springboot-test-redis2</h2>

<a href="http://localhost:8080/springboot-test-redis2/swagger-ui.html">Enter swagger page test</a>
</body>
</html>
Copy the code

The project address to your own project visit: http://localhost:8080/springboot-test-redis2 # # # # # 2. To access the index.html page:

Enter swagger page test

#####4. Test the two data sources to store and fetch data ###### data source 1- Test:

###### Data source 2- Tests:

Dual data source configuration, test successful!