springboot 2.0 自定义redis自动装配

首先创建maven项目 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<parent>
		<groupId>com.tuling</groupId>
		<artifactId>tuling-springboot</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>

	<modelVersion>4.0.0</modelVersion>

	<groupId>com.hnnd</groupId>
	<artifactId>redisoper-spring-boot-autoconfiguration</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>redisoper-spring-boot-autoconfiguration</name>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
			<version>2.0.9.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.9.0</version>
		</dependency>

		<!-- 自动配置的依赖-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-autoconfigure</artifactId>
		</dependency>

		<!-- 实体类映射属性文件需要的-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>18.0</version>
		</dependency>

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

	</dependencies>


</project>

  自定义配置工程截图:

RedisOperAutoConfiguration类 是核心类

package com.redisoper;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;

import java.util.List;

/**
 * redis操作配置类
 * Created by Administrator on 2018/8/8.
 */
@Configuration  //开启配置
@EnableConfigurationProperties(value = {RedisConfigProperties.class,ShardedRedisConfigProperties.class})//开启使用映射实体对象
@ConditionalOnClass(value = {JedisPoolConfig.class, JedisPool.class})//存在JedisPoolConfig JedisPool时初始化该配置类
@Slf4j
public class RedisOperAutoConfiguration {

    @Autowired
    private RedisConfigProperties redisConfigProperties;

    @Autowired
    private ShardedRedisConfigProperties shardedRedisConfigProperties;

    public RedisOperAutoConfiguration(RedisConfigProperties redisConfigProperties,ShardedRedisConfigProperties shardedRedisConfigProperties) {
        this.redisConfigProperties = redisConfigProperties;
        this.shardedRedisConfigProperties = shardedRedisConfigProperties;
    }
  
  
   // 此处是redis集群配置,单机版可忽略 @Bean @ConditionalOnMissingBean(ShardedJedisPool.class) @ConditionalOnProperty(prefix = "spring.ha.redis",name = "USEHA",havingValue ="false") //配置文件是否存在spring.ha.redis的配置 public JedisPool jedisPool() { log.info("加载jedisPool"); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(redisConfigProperties.getMaxTotal()); jedisPoolConfig.setMaxIdle(redisConfigProperties.getMaxIdel()); jedisPoolConfig.setMinIdle(redisConfigProperties.getMinIdel()); jedisPoolConfig.setTestOnBorrow(redisConfigProperties.isTestOnBorrow()); jedisPoolConfig.setTestOnReturn(redisConfigProperties.isTestOnRetrun()); JedisPool jedisPool = new JedisPool(jedisPoolConfig,redisConfigProperties.getRedis_server_ip(),redisConfigProperties.getRedis_server_port(),1000*1,redisConfigProperties.getRedis_pass()); return jedisPool; }
  // 此处是集群配置 单机版忽略 @Bean @ConditionalOnMissingBean(JedisPool.class) @ConditionalOnProperty(prefix = "spring.ha.redis",name = "USEHA",havingValue ="true") // 配置文件是否存在spring.ha.redis public ShardedJedisPool shardedJedisPool() { log.info("shardedJedisPool"); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(shardedRedisConfigProperties.getMaxIdel()); jedisPoolConfig.setMaxTotal(shardedRedisConfigProperties.getMaxTotal()); jedisPoolConfig.setMinIdle(shardedRedisConfigProperties.getMinIdel()); jedisPoolConfig.setTestOnReturn(shardedRedisConfigProperties.isTestOnRetrun()); jedisPoolConfig.setTestOnBorrow(shardedRedisConfigProperties.isTestOnBorrow()); jedisPoolConfig.setBlockWhenExhausted(true); JedisShardInfo jedisShardInfo = new JedisShardInfo(shardedRedisConfigProperties.getRedis_server_ip1(),shardedRedisConfigProperties.getRedis_server_port1()); jedisShardInfo.setPassword(shardedRedisConfigProperties.getRedis_pass1()); JedisShardInfo jedisShardInfo2 = new JedisShardInfo(shardedRedisConfigProperties.getRedis_server_ip2(),shardedRedisConfigProperties.getRedis_server_port2()); jedisShardInfo2.setPassword(shardedRedisConfigProperties.getRedis_pass2()); List<JedisShardInfo> shardInfos = Lists.newArrayList(); shardInfos.add(jedisShardInfo); shardInfos.add(jedisShardInfo2); ShardedJedisPool shardingRedisPool = new ShardedJedisPool(jedisPoolConfig,shardInfos, Hashing.MURMUR_HASH, Sharded.DEFAULT_KEY_TAG_PATTERN); return shardingRedisPool; } @Bean @ConditionalOnBean(JedisPool.class) // 容器中存在JedisPool类则初始化该bean public RedisOperClient redisOperClient() { RedisOperClient redisOperClient = new RedisOperClient(jedisPool()); return redisOperClient; } @Bean @ConditionalOnBean(ShardedJedisPool.class) //一样的道理 public ShardedRedisOperClient shardedRedisOperClient() { ShardedRedisOperClient shardedRedisOperClient = new ShardedRedisOperClient(shardedJedisPool()); return shardedRedisOperClient; } }
@Configuration:这个配置就不用多做解释了,我们一直在使用
@EnableConfigurationProperties:这是一个开启使用配置参数的注解,value值就是我们配置实体参数映射的ClassType,将配置实体作为配置来源。
SpringBoot内置条件注解
有关@ConditionalOnXxx相关的注解这里要系统的说下,因为这个是我们配置的关键,根据名称我们可以理解为具有Xxx条件,当然它实际的意义也是如此,条件注解是一个系列,下面我们详细做出解释
@ConditionalOnBean:当SpringIoc容器内存在指定Bean的条件
@ConditionalOnClass:当SpringIoc容器内存在指定Class的条件
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在时查找指定的位置
@ConditionalOnMissingBean:当SpringIoc容器内不存在指定Bean的条件
@ConditionalOnMissingClass:当SpringIoc容器内不存在指定Class的条件
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnSingleCandidate:当指定Bean在SpringIoc容器内只有一个,或者虽然有多个但是指定首选的Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件
以上注解都是元注解@Conditional演变而来的,根据不用的条件对应创建以上的具体条件注解。

  RedisConfigProperties类:

package com.redisoper;


import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 单机redis配置
 * Created by Administrator on 2018/8/8.
 */
@ConfigurationProperties("spring.redis")
@Data
public class RedisConfigProperties {

    /**
     * jedispool中jedis最大的可用实例
     */

    private Integer maxTotal = 50;

    /**
     * jedispool中jedis 最大空闲数
     */
    private Integer maxIdel = 20;

    /**
     * jedispool中最小空闲数
     */
    private Integer minIdel = 5;

    /**
     * 从连接池中借出的jedis都会经过测试
     */
    private boolean testOnBorrow = true;

    /**
     * 返回jedis到池中Jedis 实例都会经过测试
     */
    private boolean testOnRetrun = false;
    /**
     * IP
     */
    private String redis_server_ip;
    /**
     * port
     */
    private Integer redis_server_port;
    /**
     * 连接redis的password
     */
    private String redis_pass;

}

  RedisOperClient类:

package com.redisoper;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.Collections;

/**
 * redis操作类
 * Created by Administrator on 2018/8/8.
 */
@Slf4j
public class RedisOperClient {

    private JedisPool jedisPool;

    public RedisOperClient(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

    /**
     * set 操作
     *
     * @param key   键
     * @param value 值
     * @return result
     */
    public String set(String key, String value) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.set(key, value);
        } catch (Exception e) {
            log.error("set key:{},value:{},error:{}", key, value, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * list接口存储用作消息队列
     *
     * @param queueName 队列名称
     * @param value     消息
     * @return 成功
     */
    public long lpush(String queueName, String value) {
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.lpush(queueName, value);
        } catch (Exception e) {
            log.error("lpush key:{},value:{},异常:{}", queueName, value, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * 判断是否为空
     *
     * @param queueName 队列名称
     * @return true|false
     */
    public boolean isEmptyQueue(String queueName) {

        Jedis jedis = null;
        Long result = null;
        try {
            jedis = jedisPool.getResource();
            if (jedis.llen(queueName).intValue() == 0) {
                return false;
            }
            return true;
        } catch (Exception e) {
            log.error("isEmptyQueue key:{},异常:{}", queueName, e);
            jedisPool.returnResource(jedis);
            return false;
        } finally {
            jedisPool.returnResource(jedis);
        }
    }

    /**
     * 出队操作
     *
     * @param queueName 队列名称
     * @return 队首消息
     */
    public String rpop(String queueName) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.rpop(queueName);
        } catch (Exception e) {
            log.error("rpop key:{},异常:{}", queueName, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    public String set(String key, String value, String set_if_not_exits, String set_with_expire_time, int expire) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.set(key, value, set_if_not_exits, set_with_expire_time, expire);
        } catch (Exception e) {
            log.error("set key:{},value:{},set_if_not_exits:{},set_with_expire_time:{},expire:{},error:{}", key, value, set_if_not_exits, set_with_expire_time, expire, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * setex 操作
     *
     * @param key        key 键
     * @param expireTime 过期时间(m)
     * @param value      值
     * @return String
     */
    public String setex(String key, int expireTime, String value) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.setex(key, expireTime, value);
        } catch (Exception e) {
            log.error("setex key:{},expireTime:{},value:{},error:{}", key, expireTime, value, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * get 操作
     *
     * @param key 键
     * @return value
     */
    public String get(String key) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.get(key);
        } catch (Exception e) {
            log.error("get key:{}error:{}", key, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * 让key失效
     *
     * @param key        键
     * @param expireTime 失效时间
     * @return Long
     */
    public Long expire(String key, int expireTime) {
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.expire(key, expireTime);
        } catch (Exception e) {
            log.error("expire key:{},expireTime:{},error:{}", key, expireTime, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return boolean
     */
    public boolean isExists(String key) {
        Jedis jedis = null;
        boolean result = false;
        try {
            jedis = jedisPool.getResource();
            result = jedis.exists(key);
        } catch (Exception e) {
            log.error("isExists key:{},error:{}", key, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }


    /**
     * 自增
     *
     * @param key key
     * @return Long
     */
    public Long incr(String key) {
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.incr(key);
        } catch (Exception e) {
            log.error("incr key:{},error:{}", key, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * 指定步长增加
     *
     * @param key  键
     * @param step 步长
     * @return Long
     */
    public Long incrBy(String key, Integer step) {
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.incrBy(key, step);
        } catch (Exception e) {
            log.error("incrBy key:{},step:{},error:{}", key, step, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * 递减
     *
     * @param key key
     * @return Long
     */
    public Long decr(String key) {
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.decr(key);
        } catch (Exception e) {
            log.error("decr key:{},error:{}", key, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    /**
     * 指定步长递减
     *
     * @param key  键
     * @param step 步长
     * @return Long
     */
    public Long decrBy(String key, Integer step) {
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.incrBy(key, step);
        } catch (Exception e) {
            log.error("decrBy key:{},step:{},error:{}", key, step, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }

    public Long del(String key) {
        Jedis jedis = null;
        Long result = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.del(key);
        } catch (Exception e) {
            log.error("del key:{},error:{}", key, e);
            jedisPool.returnResource(jedis);
            return result;
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;
    }


    public long eval(String script, String lock, String lockValue) {
        Jedis jedis = null;
        //删除锁失败
        long result = 0;
        try {
            jedis = jedisPool.getResource();
            result = (Long) jedis.eval(script, Collections.singletonList(lock), Collections.singletonList(lockValue));
            return result;
        } catch (Exception e) {
            log.error("eval script:{},lock:{},lockValue:{},error:{}", script, lock, lockValue, e);
            jedisPool.returnResource(jedis);
        } finally {
            jedisPool.returnResource(jedis);
        }
        return result;

    }
}

  

至此结束配置类,然后把这个项目打包程jar。

接着新建starter maven 工程:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.hnnd</groupId>
	<artifactId>redisoper-springboot-starter</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>redisoper-springboot-starter</name>

	<parent>
		<groupId>com.tuling</groupId>
		<artifactId>tuling-springboot</artifactId>
		<version>0.0.1-SNAPSHOT</version> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

          <!-- 依赖刚刚自定义的配置jar--> <dependency> <groupId>com.hnnd</groupId> <artifactId>redisoper-spring-boot-autoconfiguration</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>

  application.properties:

spring.redis.redis-server-ip=localhost
spring.redis.redis-server-port=6379
spring.redis.redis-pass=

 

  

至此starter 工程 就可以直接使用在autoConfiguration工程自己配置的RedisOperClient 类 来操作redis,如果您把starter工程jar 包放在公司私服,那么同事就都能用你配置好的组件。多爽? 你就是传说的架构师。

欢迎来群 592495675 畅聊技术。


 

posted on 2019-04-04 13:47  小鱼儿灬  阅读(2011)  评论(0编辑  收藏  举报

导航