天天看點

自定義redis-spring-boot-starter 自動化配置。工程架構starter為通用的元件gitee 項目位址

自定義springboot的starter,自動化配置

  • 工程架構
  • starter為通用的元件
    • 最關鍵的配置
    • web工程繼承redis-starter
      • 測試demo
  • gitee 項目位址

工程架構

自定義redis-spring-boot-starter 自動化配置。工程架構starter為通用的元件gitee 項目位址

starter為通用的元件

建立一個module 工程 xlc-commns

裡面進行自定義starter,這裡我就寫一個redis-starter 作為例子

package cloud.redis;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author cunfeng
 * @create 2021-05-06 10:23
 */

@ConfigurationProperties(prefix = "myredis") //自定義yml格式 随便起名
public class MyRedisProperties {
    /**
     * ip位址
     */
    private String host;
    /**
     * 端口号
     */
    private  int  port;

    /**
     * 密碼
     */
    private String password;
    /**
     * 接池中總連接配接的最大數量
     */
    private int   maxActive;
    /**
     *  連接配接池中空閑連接配接的最大數量
     */
    private int   maxIdle;
    /**
     * 最大建立連接配接等待時間
     */
    private  int  maxWait;
    /**
     * 逾時時間
     */
    private  int timeout;
    /**
     *    第幾個資料庫
     */
    private int database;

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

    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 getMaxActive() {
        return maxActive;
    }
    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }
    public int getMaxIdle() {
        return maxIdle;
    }
    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }
    public int getMaxWait() {
        return maxWait;
    }
    public void setMaxWait(int maxWait) {
        this.maxWait = maxWait;
    }

    public int getTimeout() {
        return timeout;
    }

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

    public int getDatabase() {
        return database;
    }

    public void setDatabase(int database) {
        this.database = database;
    }
}
           
package cloud.redis;
import org.apache.commons.lang.StringUtils;
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.boot.autoconfigure.condition.ConditionalOnClass;
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;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;


/**
 * 利用jedis 進行連接配接redis
 * @author cunfeng
 * @create 2021-05-06 10:33
 */
@Configuration
@EnableConfigurationProperties(MyRedisProperties.class)//開啟屬性注入,通過@autowired注入
@ConditionalOnClass(RedisClient.class)//判斷這個類是否在classpath中存在
public class MyRedisAutoConfigulation {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private MyRedisProperties prop;

    @Bean(name="jedisPool")
    public JedisPool jedisPool() {
        JedisPoolConfig config = new JedisPoolConfig();
        //連接配接池中空閑連接配接的最大數量
        config.setMaxIdle(prop.getMaxIdle());
        // 接池中總連接配接的最大數量
        config.setMaxTotal(prop.getMaxActive());
        //最大建立連接配接等待時間
        config.setMaxWaitMillis(prop.getMaxWait());
        //第幾個資料庫
        int database = prop.getDatabase();
        //密碼
        String password = prop.getPassword();
        int timeout = prop.getTimeout();
        if(StringUtils.isNotBlank(password)){
            logger.info("初始化redis連接配接池完畢--------------");
            return new JedisPool(config, prop.getHost(), prop.getPort(),timeout,password,database);
        }else {
            logger.info("初始化redis連接配接池完畢--------------");
            return new JedisPool(config, prop.getHost(), prop.getPort(),timeout,null,database);
        }

    }

    @Bean
    @ConditionalOnMissingBean(RedisClient.class)//容器中如果沒有RedisClient這個類,那麼自動配置這個RedisClient
    public RedisClient redisClient(@Qualifier("jedisPool")JedisPool pool) {
        RedisClient redisClient = new RedisClient();
        redisClient.setJedisPool(pool);
        return redisClient;
    }

}
           
package cloud.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Client;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;

/**
 * 常用的redis方法
 * @author cunfeng
 * @create 2021-05-06 10:53
 */
public class RedisClient {

    private Logger log = LoggerFactory.getLogger(this.getClass());


    @Autowired
    private JedisPool jedisPool;


    /**
     * 處理jedis請求
     * @param f 處理邏輯,通過lambda行為參數化
     * @return 處理結果
     */
    private Object excuteByJedis(Function<Jedis, Object> f) {
        Jedis jedis = null;
        try{
            jedis= jedisPool.getResource();
            return f.apply(jedis);
        } catch (Exception e) {
            e.printStackTrace();
            if(jedis != null ) {
                jedisPool.close();
            }
            log.error("redis資源池發生錯誤:"+e.getMessage());
            return null;
        }finally {
            if (jedis != null){
                jedis.close();
            }
        }
    }

    public Map<String, Object> getKeysSize() {
        long dbSize = (long) this.excuteByJedis(
                j -> {
                    Client client = j.getClient();
                    client.dbSize();
                    return client.getIntegerReply();
                }
        );
        Map<String, Object> map = new HashMap<>();
        map.put("create_time", System.currentTimeMillis());
        map.put("dbSize", dbSize);
        return map;
    }

    public Map<String, Object> getMemoryInfo() {
        String info = (String) this.excuteByJedis(
                j -> {
                    Client client = j.getClient();
                    client.info();
                    return client.getBulkReply();
                }
        );
        String[] strs = Objects.requireNonNull(info).split("\n");
        Map<String, Object> map = null;
        for (String s : strs) {
            String[] detail = s.split(":");
            if ("used_memory".equals(detail[0])) {
                map = new HashMap<>();
                map.put("used_memory", detail[1].substring(0, detail[1].length() - 1));
                map.put("create_time", System.currentTimeMillis());
                break;
            }
        }
        return map;
    }


    public Set<String> getKeys(String pattern) {
        return (Set<String>) this.excuteByJedis(j -> j.keys(pattern));
    }


    public String get(String key) {
        return (String) this.excuteByJedis(j -> j.get(key));
    }


    public String set(String key, String value) {
        return (String) this.excuteByJedis(j -> j.set(key, value));
    }


    public Long del(String... key) {
        return (Long) this.excuteByJedis(j -> j.del(key));
    }


    public Boolean exists(String key) {
        return (Boolean) this.excuteByJedis(j -> j.exists(key));
    }


    public Long pttl(String key) {
        return (Long) this.excuteByJedis(j -> j.pttl(key));
    }


    public Long pexpire(String key, Long milliseconds) {
        return (Long) this.excuteByJedis(j -> j.pexpire(key, milliseconds));
    }

    public String haSet(String key, Map<String, String> map) {
        return (String) this.excuteByJedis(j -> j.hmset(key, map));
    }

    public Map<String,String> hmGetAll(String key) {
        return  (Map<String, String>) this.excuteByJedis(j -> j.hgetAll(key));
    }

    public JedisPool getJedisPool() {
        return jedisPool;
    }

    public void setJedisPool(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

}  
           

最關鍵的配置

自定義redis-spring-boot-starter 自動化配置。工程架構starter為通用的元件gitee 項目位址
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cloud.redis.MyRedisAutoConfigulation
           

web工程繼承redis-starter

pom檔案

<?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>
        <artifactId>redis-starter</artifactId>
        <groupId>org.xlc</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>xlc-admin</artifactId>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

        <!--自定義yml提示-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.2.6.RELEASE</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.xlc</groupId>
            <artifactId>redis-spring-boot-starter</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>wangxiao</finalName>
    </build>

</project>
           

測試demo

package cloud.test;
import cloud.redis.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;

/**
 * @MethodName: 測試類
 * @Author: cunfeng
 * @Date: 2021年05月05日 16:56
 **/
@RestController

public class test {

    @Autowired
    private RedisClient redisClient;


    @RequestMapping("/set")
    public String set(String key, String value) {
        redisClient.set(key, value);
        return "success";
    }

    @RequestMapping("/get")
    public String get(String key){
        return redisClient.get(key);
    }

}

           
server:
  port: 2222
  servlet:
    context-path: /
myredis:                  #自定義yml
  host: 192.168.2.204
  port: 6379
  password:
  min-idle: 8         #空閑 最小連結數
  max-idle: 500       #空閑 最大連結數
  max-active: 2000    #最大連結數
  max-wait: 10000     #最大建立連接配接等待時間
  timeout: 30000      #逾時時間
  database: 1          #第幾個資料庫
           

gitee 項目位址

https://gitee.com/YuXuanPer/redis-starter

測試案列不易,多多支援