栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

如何实现自己的spring boot starter(二)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何实现自己的spring boot starter(二)

如何实现自己的spring boot starter(一)​​​​​​​

我们在SpringBoot中使用redis的时候,直接引用 spring-boot-starter-data-redis 的pom,然后配置

spring.redis.host = localhost

spring.redis.port = 6379

spring.redis.password = 123456

就可以使用在我们的业务系统里注入redisTemplate来操作redis了,但是他是怎么工作的呢?

让我们走进SpringBoot的源码,看几张截图:

在 spring-boot-autoconfigure 模块中

 然后暴露出一个 spring-boot-starter-data-redis 模块,留给业务方引用

 可以看到这个 starter 其实就是一个门面,里面组装了redis所需要的依赖, 那我们也模仿着这种写法,实现自己的 starter。我的项目结构是这样的:

 

 以glocalcommon-redis为例子,这里写的是redis的自动配置,下面的glocalcommon-redis-spring-boot-starter里仅仅引用了glocalcommon-redis的jar而已,然后业务系统想使用redis的话,直接引用下面的pom,然后配置redis的host,password即可。

        
            com.gane.glocalcommon
            glocalcommon-redis-spring-boot-starter
            1.0-SNAPSHOT
        
glocalcommon-redis

pom


    4.0.0

    com.gane.glocalcommon
    glocalcommon-redis
    1.0-SNAPSHOT

    
        
            org.springframework.boot
            spring-boot-starter
            2.2.6.RELEASE
            compile
        

        
            com.gane.glocalcommon
            glocalcommon-utils-spring-boot-starter
            1.0-SNAPSHOT
        

        
            redis.clients
            jedis
            2.9.0
        
    

这里的 glocalcommon-utils-spring-boot-starter 你们可以换成其他的工具类

RedisProperties

到时候业务费写配置的时候,会以 glocalcommon.redis 开头,如:glocalcommon.redis.host=localhost

package com.gane.glocalcommon.redis;

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


@ConfigurationProperties(prefix = "glocalcommon.redis")
public class RedisProperties {

    private static final String DEFAULT_HOST = "localhost";
    private static final int DEFAULT_PORT = 6379;
    private static final String DEFAULT_URL = DEFAULT_HOST + ":" + DEFAULT_PORT;

    private String host = DEFAULT_URL;
    private int port = DEFAULT_PORT;
    private int timeout = 2000;
    private String password;
    private int database = 0;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getDatabase() {
        return database;
    }

    public void setDatabase(int database) {
        this.database = database;
    }
}
RedisClient

这里主要是redis的操作方法

package com.gane.glocalcommon.redis;

import com.gane.glocalcommon.redis.serializer.ObjectSerializer;
import com.gane.glocalcommon.redis.serializer.RedisSerializer;
import com.gane.glocalcommon.redis.serializer.StringSerializer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


public abstract class RedisClient {

    public static final Logger log = LoggerFactory.getLogger(RedisClient.class);

    private static final int DEFAULT_EXPIRE = -1;
    private RedisSerializer keySerializer = new StringSerializer();
    private RedisSerializer valueSerializer = new ObjectSerializer();

    protected abstract Jedis getResource();

    private JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

    public JedisPoolConfig getJedisPoolConfig() {
        return jedisPoolConfig;
    }

    public String get(String key) {
        String value = null;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            if (jedis.exists(key)) {
                value = jedis.get(key);
                value = StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value) ? value : null;
                log.debug("get {} = {}", key, value);
            }
        } catch (Exception e) {
            log.error("get {} = {}", new Object[]{key, value, e});
        } finally {
            jedis.close();
        }
        return value;
    }

    public Object getObj(String key) {
        Object obj = null;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            if (jedis.exists(key)) {
                byte[] bytes = jedis.get(key.getBytes());
                if (bytes != null && bytes.length != 0) {
                    obj = valueSerializer.deserialize(bytes);
                }
                log.debug("getObj {} = {}", key, obj);
            }
        } catch (Exception e) {
            log.error("getObj {} = {}", new Object[]{key, obj, e});
        } finally {
            jedis.close();
        }
        return obj;
    }

    public String set(String key, String value) {
        return this.set(key, value, DEFAULT_EXPIRE);
    }

    public String setObj(String key, Object value) {
        return this.setObj(key, value, DEFAULT_EXPIRE);
    }

    public String set(String key, String value, int expire) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = this.getResource();
            result = jedis.set(key, value);
            if (expire >= 0) {
                jedis.expire(key, expire);
            }
            log.debug("set {} = {}", key, value);
        } catch (Exception e) {
            log.error("set {} = {}", new Object[]{key, value, e});
        } finally {
            jedis.close();
        }
        return result;
    }

    public String setObj(String key, Object value, int expire) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = this.getResource();
            result = jedis.set(key.getBytes(), valueSerializer.serialize(value));
            if (expire >= 0) {
                jedis.expire(key, expire);
            }
            log.debug("setObj {} = {}", key, value);
        } catch (Exception e) {
            log.error("setObj {} = {}", new Object[]{key, value, e});
        } finally {
            jedis.close();
        }
        return result;
    }

    public Long del(String key) {
        Long value = null;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            if (jedis.exists(key)) {
                value = jedis.del(key);
                log.debug("del {} = {}", key, value);
            }
        } catch (Exception e) {
            log.error("del {} = {}", new Object[]{key, value, e});
        } finally {
            jedis.close();
        }
        return value;
    }

    public boolean exists(String key) {
        boolean result = false;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            result = jedis.exists(key);
        } catch (Exception e) {
            log.error("exists {}", key, e);
        } finally {
            jedis.close();
        }
        return result;
    }

    public Long incr(String key) {
        return incrWithExpire(key, 0);
    }

    public Long incrWithExpire(String key, int seconds) {
        Jedis jedis = null;
        Long incr;
        try {
            if (StringUtils.isBlank(key)) {
                incr = null;
                return incr;
            }
            jedis = this.getResource();
            incr = jedis.incr(key);
            if (seconds >= 0) {
                jedis.expire(key, seconds);
            }
        } catch (Exception e) {
            log.error("incr {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
        return incr;
    }

    public Long incrBy(String key, Long integer) {
        Jedis jedis = null;
        Long incrBy;
        try {
            if (StringUtils.isBlank(key)) {
                incrBy = null;
                return incrBy;
            }
            if (integer == null) {
                integer = 0L;
            }
            jedis = this.getResource();
            incrBy = jedis.incrBy(key, integer);
        } catch (Exception e) {
            log.error("incr {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
        return incrBy;
    }

    public Long incrByWithExpire(String key, Long integer, int seconds) {
        Jedis jedis = null;
        Long incrBy;
        try {
            if (StringUtils.isBlank(key)) {
                incrBy = null;
                return incrBy;
            }
            if (integer == null) {
                integer = 0L;
            }
            jedis = this.getResource();
            incrBy = jedis.incrBy(key, integer);

            if (seconds >= 0) {
                jedis.expire(key, seconds);
            }
        } catch (Exception e) {
            log.error("incr {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
        return incrBy;
    }

    public Long decrBy(String key, Long integer) {
        Jedis jedis = null;
        Long decrBy;
        try {
            if (StringUtils.isBlank(key)) {
                decrBy = null;
                return decrBy;
            }
            if (integer == null) {
                integer = 0L;
            }
            jedis = this.getResource();
            decrBy = jedis.decrBy(key, integer);
        } catch (Exception e) {
            log.error("incr {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
        return decrBy;
    }

    public Long decr(String key) {
        Jedis jedis = null;
        Long decr;
        try {
            if (StringUtils.isBlank(key)) {
                decr = null;
                return decr;
            }
            jedis = this.getResource();
            decr = jedis.decr(key);
            return decr;
        } catch (Exception e) {
            log.error("decr {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    
    public Long ttl(String key) {
        Long result = 0L;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            result = jedis.ttl(key);
        } catch (Exception e) {
            log.error("ttl {}", key, e);
        } finally {
            jedis.close();
        }
        return result;
    }

    

    
    public Map hgetAll(String key) {
        Map map = new HashMap();
        Jedis jedis = null;
        try {
            if (StringUtils.isBlank(key)) {
                return map;
            }
            jedis = this.getResource();
            map = jedis.hgetAll(key);
            return map;
        } catch (Exception e) {
            log.error("hgetAll {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    
    public String hmset(String key, Map map) {
        Jedis jedis = null;
        try {
            if (StringUtils.isBlank(key)) {
                return null;
            }
            jedis = this.getResource();
            return jedis.hmset(key, map);
        } catch (Exception e) {
            log.error("hmset {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    
    public Long hdel(String key, String... fields) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            return jedis.hdel(key, fields);
        } catch (Exception e) {
            log.error("hdel {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    

    
    public Long llen(String key) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            return jedis.llen(key);
        } catch (Exception e) {
            log.error("llen {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    
    public Long lpushx(String key, String value) {
        return lpush(key, value);
    }

    
    public Long lpush(String key, String... fields) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            return jedis.lpush(key, fields);
        } catch (Exception e) {
            log.error("lpush {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    
    public String rpop(String key) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            return jedis.rpop(key);
        } catch (Exception e) {
            log.error("rpop {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    
    public Long zadd(String key, double score, String member) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            return jedis.zadd(key, score, member);
        } catch (Exception e) {
            log.error("zadd {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    public Long sadd(String key, String... member) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            return jedis.sadd(key, member);
        } catch (Exception e) {
            log.error("sadd {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }

    public Set smembers(String key) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            return jedis.smembers(key);
        } catch (Exception e) {
            log.error("smembers {} ", key, e);
            return null;
        } finally {
            jedis.close();
        }
    }


    
    public boolean getLock(String lockKey) {
        return this.getLock(lockKey, "1", 5);
    }

    
    public boolean getLock(String lockKey, String requestId, int expireTime) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            String result = jedis.set(lockKey, requestId, "NX", "EX", expireTime);
            if ("OK".equals(result)) {
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("getLock {} ", lockKey, e);
            return false;
        } finally {
            jedis.close();
        }
    }

    
    public boolean unLock(String lockKey) {
        return this.unLock(lockKey, "1");
    }

    
    public boolean unLock(String lockKey, String requestId) {
        Jedis jedis = null;
        try {
            String script = "if redis.call("get",KEYS[1]) == ARGV[1] thenn" +
                    "    return redis.call("del",KEYS[1])n" +
                    "elsen" +
                    "    return 0n" +
                    "end";
            jedis = this.getResource();
            Object result = jedis.eval(script, Collections.singletonList(lockKey),
                    Collections.singletonList(requestId));
            if ("OK".equals(result)) {
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("unLock {} ", lockKey, e);
            return false;
        } finally {
            jedis.close();
        }
    }
}
RedisManager

 这里 是拿到业务方配置的redis参数,通过这些参数生成jedisPool,获取到Jedis,供RedisClient操作redis,业务方在项目中主要是注入这个类来使用

package com.gane.glocalcommon.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;


public class RedisManager extends RedisClient{

    private RedisProperties redisProperties;

    private JedisPool jedisPool;

    @Override
    protected Jedis getResource() {
        if (jedisPool == null) {
            init();
        }
        return jedisPool.getResource();
    }

    private void init() {
        synchronized (this) {
            if (jedisPool == null) {
                if (redisProperties.getHost().contains(":")) {
                    String[] hostAndPort = redisProperties.getHost().split(":");
                    jedisPool = new JedisPool(getJedisPoolConfig(),
                            hostAndPort[0],
                            Integer.parseInt(hostAndPort[1]),
                            redisProperties.getTimeout(),
                            redisProperties.getPassword(),
                            redisProperties.getDatabase());
                } else {
                    jedisPool = new JedisPool(getJedisPoolConfig(),
                            redisProperties.getHost(),
                            redisProperties.getPort(),
                            redisProperties.getTimeout(),
                            redisProperties.getPassword(),
                            redisProperties.getDatabase());
                }
            }
        }
    }

    public void setRedisProperties(RedisProperties redisProperties) {
        this.redisProperties = redisProperties;
    }
}
RedisAutoConfiguration
package com.gane.glocalcommon.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
@EnableConfigurationProperties({RedisProperties.class})
public class RedisAutoConfiguration {

    private RedisProperties redisProperties;

    @Autowired
    public RedisAutoConfiguration(RedisProperties redisProperties) {
        this.redisProperties = redisProperties;
    }

    @Bean
    @ConditionalOnMissingBean(name = "redisManager")
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();
        redisManager.setRedisProperties(redisProperties);
        return redisManager;
    }
}
spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.gane.glocalcommon.redis.RedisAutoConfiguration

这样 glocalcommon-redis 就已经完成了,打个 jar 包,让 glocalcommon-redis-spring-boot-starter 引用

再让 glocalcommon-redis-spring-boot-starter 打成 jar 包,给业务方引用

       
            com.gane.glocalcommon
            glocalcommon-redis-spring-boot-starter
            1.0-SNAPSHOT
        

 业务方配置redis参数

 启动并测试

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/324630.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号