springCloud工作筆記090---SpringCloud_redis配置多數據源_redis多數據源

技術交流QQ羣【JAVA,C++,Python,.NET,BigData,AI】:170933152  

1.pom.xml添加依賴

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2.application.properties中添加redis配置

#redis緩存配置

# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.pool.max-active=-1
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連接池中的最大空閒連接
spring.redis.pool.max-idle=8
# 連接池中的最小空閒連接
spring.redis.pool.min-idle=0

spring.redis.database=5
spring.redis.host=172.19.128.38
spring.redis.password=123456
spring.redis.port=6379

#redis緩存配置
spring.redis.database2=6
spring.redis.host2=172.19.128.38
spring.redis.password2=123456
spring.redis.port2=6379
#6個小時
spring.redis.timeout=21600

#redis緩存配置
spring.redis2.database=6
spring.redis2.host=172.19.128.38
spring.redis2.password=123456
spring.redis2.port=6379
#6個小時
spring.redis2.timeout=21600

3.新建配置類 

RedisConfig

package cn.gov.credream.scsupport.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.lang.reflect.Method;

/**
 * spring-boot-data-packing 設置Redis多實例的基類
 *
 * @Author credream
 * @Date 2019/10/12
 */
@EnableCaching
@Configuration
public class RedisConfig {
    @Value("${spring.redis.pool.max-active}")
    private int redisPoolMaxActive;

    @Value("${spring.redis.pool.max-wait}")
    private int redisPoolMaxWait;

    @Value("${spring.redis.pool.max-idle}")
    private int redisPoolMaxIdle;

    @Value("${spring.redis.pool.min-idle}")
    private int redisPoolMinIdle;

    /**
     * 配置Key的生成方式
     *
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(o.getClass().getName())
                        .append(method.getName());
                for (Object object : objects) {
                    stringBuilder.append(object.toString());
                }
                return stringBuilder.toString();
            }
        };
    }

    /**
     * 創建redis連接工廠
     *
     * @param dbIndex
     * @param host
     * @param port
     * @param password
     * @param timeout
     * @return
     */
    public JedisConnectionFactory createJedisConnectionFactory(int dbIndex, String host, int port, String password, int timeout) {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setDatabase(dbIndex);
        jedisConnectionFactory.setHostName(host);
        jedisConnectionFactory.setPort(port);
        jedisConnectionFactory.setPassword(password);
        jedisConnectionFactory.setTimeout(timeout);
        jedisConnectionFactory.setPoolConfig(setPoolConfig(redisPoolMaxIdle, redisPoolMinIdle, redisPoolMaxActive, redisPoolMaxWait, true));
        return jedisConnectionFactory;

    }

    /**
     * 配置CacheManager
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        return redisCacheManager;
    }

    /**
     * 設置連接池屬性
     *
     * @param maxIdle
     * @param minIdle
     * @param maxActive
     * @param maxWait
     * @param testOnBorrow
     * @return
     */
    public JedisPoolConfig setPoolConfig(int maxIdle, int minIdle, int maxActive, int maxWait, boolean testOnBorrow) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxWaitMillis(maxWait);
        poolConfig.setTestOnBorrow(testOnBorrow);
        return poolConfig;
    }

    /**
     * 設置RedisTemplate的序列化方式
     *
     * @param redisTemplate
     */
    public void setSerializer(RedisTemplate redisTemplate) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //設置鍵(key)的序列化方式
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //設置值(value)的序列化方式
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
    }
}

4.配置第一個數據源的配置類

 DefaultRedisConfig

package cn.gov.credream.scsupport.config;

import org.springframework.beans.factory.annotation.Value;
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.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * llld-parent 配置默認Redis操作實例 到Spring中
 *
 * @Author credream
 * @Date 2018/8/2
 */
@Configuration
@EnableCaching
public class DefaultRedisConfig extends RedisConfig {


    @Value("${spring.redis.database}")
    private int dbIndex;

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.timeout}")
    private int timeout;

    /**
     * 配置redis連接工廠
     *
     * @return
     */
    @Bean
    public RedisConnectionFactory defaultRedisConnectionFactory() {
        return createJedisConnectionFactory(dbIndex, host, port, password, timeout);
    }

    /**
     * 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
     *
     * @return
     */
    @Bean(name = "defaultRedisTemplate")
    public StringRedisTemplate defaultRedisTemplate() {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(defaultRedisConnectionFactory());
        setSerializer(template);
        template.afterPropertiesSet();
        return template;
    }
}

5.配置第2個數據源,配置類

CacheRedisConfig

package cn.gov.credream.scsupport.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * llld-parent 配置緩存Redis操作實例 到Spring中
 *
 * @Author credream
 * @Date 2018/8/2
 */
@Configuration
@EnableCaching
public class CacheRedisConfig extends RedisConfig {


    @Value("${spring.redis2.database}")
    private int dbIndex;

    @Value("${spring.redis2.host}")
    private String host;

    @Value("${spring.redis2.port}")
    private int port;

    @Value("${spring.redis2.password}")
    private String password;

    @Value("${spring.redis2.timeout}")
    private int timeout;

    /**
     * 配置redis連接工廠
     *
     * @return
     */
    @Primary
    @Bean
    public RedisConnectionFactory cacheRedisConnectionFactory() {
        return createJedisConnectionFactory(dbIndex, host, port, password, timeout);
    }

    /**
     * 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
     *
     * @return
     */
    @Primary
    @Bean(name = "cacheRedisTemplate")
    public StringRedisTemplate cacheRedisTemplate() {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(cacheRedisConnectionFactory());
        setSerializer(template);
        template.afterPropertiesSet();
        return template;
    }

}

6.爲了方便創建工具類:

CacheSosUtils

package cn.gov.credream.scsupport.util;

import cn.gov.credream.sccommon.core.ConstantKey;
import cn.gov.credream.sccommon.core.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 描述: 操作redis 工具類
 * author: credream
 * Date: 2018/09/19 15:01
 */
@Component
public class CacheSosUtils {

    @Resource(name="cacheRedisTemplate")
    private StringRedisTemplate redisTemplate;

    private static CacheSosUtils cacheUtils;

    private static final Logger logger = LoggerFactory.getLogger(CacheSosUtils.class);

    @PostConstruct
    public void init() {
        cacheUtils = this;
        cacheUtils.redisTemplate = this.redisTemplate;
    }

    /**
     * 獲取所有登錄的用戶
     *
     * @return
     */
    public static Integer getOnlineUsers() {
        Integer userCount = 0;
        userCount = cacheUtils.redisTemplate.keys("*").size();
        return userCount;
    }


    /**
     * 將數據存入緩存
     *
     * @param key
     * @param val
     * @return
     */
    public static void saveString(String key, String val) {

        ValueOperations<String, String> vo = cacheUtils.redisTemplate.opsForValue();
        vo.set(key, val);
    }

    /**
     * 將數據存入緩存的集合中
     *
     * @param key
     * @param val
     * @return
     */
    public static void saveToSet(String key, String val) {

        SetOperations<String, String> so = cacheUtils.redisTemplate.opsForSet();

        so.add(key, val);
    }

    /**
     * key 緩存Key
     *
     * @param key
     * @return
     */
    public static String getFromSet(String key) {
        return cacheUtils.redisTemplate.opsForSet().pop(key);
    }

    /**
     * 將 key的值保存爲 value ,當且僅當 key 不存在。 若給定的 key 已經存在,則 SETNX 不做任何動作。 SETNX 是『SET if
     * Not eXists』(如果不存在,則 SET)的簡寫。 <br>
     * 保存成功,返回 true <br>
     * 保存失敗,返回 false
     */
    public static boolean saveNX(String key, String val) {

        /** 設置成功,返回 1 設置失敗,返回 0 **/
        return cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.setNX(key.getBytes(), val.getBytes());
        });

    }

    /**
     * 將 key的值保存爲 value ,當且僅當 key 不存在。 若給定的 key 已經存在,則 SETNX 不做任何動作。 SETNX 是『SET if
     * Not eXists』(如果不存在,則 SET)的簡寫。 <br>
     * 保存成功,返回 true <br>
     * 保存失敗,返回 false
     *
     * @param key
     * @param val
     * @param expire 超時時間
     * @return 保存成功,返回 true 否則返回 false
     */
    public static boolean saveNX(String key, String val, int expire) {

        boolean ret = saveNX(key, val);
        if (ret) {
            cacheUtils.redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        return ret;
    }

    /**
     * 將數據存入緩存(並設置失效時間)
     *
     * @param key
     * @param val
     * @param seconds
     * @return
     */
    public static void saveString(String key, String val, int seconds) {

        cacheUtils.redisTemplate.opsForValue().set(key, val, seconds, TimeUnit.SECONDS);
    }

    /**
     * 將自增變量存入緩存
     */
    public static void saveSeq(String key, long seqNo) {

        cacheUtils.redisTemplate.delete(key);
        cacheUtils.redisTemplate.opsForValue().increment(key, seqNo);
    }

    /**
     * 將遞增浮點數存入緩存
     */
    public static void saveFloat(String key, float data) {

        cacheUtils.redisTemplate.delete(key);
        cacheUtils.redisTemplate.opsForValue().increment(key, data);
    }

    /**
     * 保存複雜類型數據到緩存
     *
     * @param key
     * @param obj
     * @return
     */
    public static void saveBean(String key, Object obj) {

        cacheUtils.redisTemplate.opsForValue().set(key, JSON.toJSONString(obj));
    }

    /**
     * 保存複雜類型數據到緩存(並設置失效時間)
     *
     * @param key
     * @param obj
     * @param seconds
     */
    public static void saveBean(String key, Object obj, int seconds) {

        cacheUtils.redisTemplate.opsForValue().set(key, JSON.toJSONString(obj), seconds, TimeUnit.SECONDS);
    }

    /**
     * 存到指定的隊列中
     *
     * @param key
     * @param val
     * @param size
     */
    public static void saveToQueue(String key, String val, long size) {

        ListOperations<String, String> lo = cacheUtils.redisTemplate.opsForList();

        if (size > 0 && lo.size(key) >= size) {
            lo.rightPop(key);
        }
        lo.leftPush(key, val);
    }

    /**
     * 保存到hash集合中
     *
     * @param hName 集合名
     * @param key
     * @param value
     */
    public static void hashSet(String hName, String key, String value) {

        cacheUtils.redisTemplate.opsForHash().put(hName, key, value);
    }

    /**
     * 根據key獲取所以值
     *
     * @param key
     * @return
     */
    public static Map<Object, Object> hgetAll(String key) {

        return cacheUtils.redisTemplate.opsForHash().entries(key);
    }

    /**
     * 保存到hash集合中
     *
     * @param <T>
     * @param hName 集合名
     * @param key
     * @param t
     */
    public static <T> void hashSet(String hName, String key, T t) {

        hashSet(hName, key, JSON.toJSONString(t));
    }

    /**
     * 取得複雜JSON數據
     *
     * @param key
     * @param clazz
     * @param clazz
     * @return
     */
    public static <T> T getBean(String key, Class<T> clazz) {

        String value = cacheUtils.redisTemplate.opsForValue().get(key);
        if (value == null) {
            return null;
        }
        return JSON.parseObject(value, clazz);
    }

    /**
     * 從緩存中取得字符串數據
     *
     * @param key
     * @return 數據
     */
    public static String getString(String key) {
        cacheUtils.redisTemplate.opsForValue().get(key);

        return cacheUtils.redisTemplate.opsForValue().get(key);
    }

    /**
     * 從指定隊列裏取得數據
     *
     * @param key
     * @param size
     * @return
     */
    public static List<String> getFromQueue(String key, long size) {

        boolean flag = cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.exists(key.getBytes());
        });

        if (flag) {
            return new ArrayList<>();
        }
        ListOperations<String, String> lo = cacheUtils.redisTemplate.opsForList();
        if (size > 0) {
            return lo.range(key, 0, size - 1);
        } else {
            return lo.range(key, 0, lo.size(key) - 1);
        }
    }

    /**
     * 從指定隊列裏取得數據
     *
     * @param key
     * @return
     */
    public static String popQueue(String key) {

        return cacheUtils.redisTemplate.opsForList().rightPop(key);

    }

    /**
     * 取得序列值的下一個
     *
     * @param key
     * @return
     */
    public static Long getSeqNext(String key) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> {

            return connection.incr(key.getBytes());

        });
    }

    /**
     * 取得序列值的下一個
     *
     * @param key
     * @return
     */
    public static Long getSeqNext(String key, long value) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> {

            return connection.incrBy(key.getBytes(), value);

        });

    }

    /**
     * 將序列值回退一個
     *
     * @param key
     * @return
     */
    public static void getSeqBack(String key) {

        cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> connection.decr(key.getBytes()));

    }

    /**
     * 從hash集合裏取得
     *
     * @param hName
     * @param key
     * @return
     */
    public static Object hashGet(String hName, String key) {

        return cacheUtils.redisTemplate.opsForHash().get(hName, key);
    }

    public static <T> T hashGet(String hName, String key, Class<T> clazz) {

        return JSON.parseObject((String) hashGet(hName, key), clazz);
    }

    /**
     * 增加浮點數的值
     *
     * @param key
     * @return
     */
    public static Double incrFloat(String key, double incrBy) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Double>) connection -> {

            return connection.incrBy(key.getBytes(), incrBy);

        });
    }

    /**
     * 判斷是否緩存了數據
     *
     * @param key 數據KEY
     * @return 判斷是否緩存了
     */
    public static boolean isCached(String key) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.exists(key.getBytes());
        });
    }

    /**
     * 判斷hash集合中是否緩存了數據
     *
     * @param hName
     * @param key   數據KEY
     * @return 判斷是否緩存了
     */
    public static boolean hashCached(String hName, String key) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.hExists(key.getBytes(), key.getBytes());
        });
    }

    /**
     * 判斷是否緩存在指定的集合中
     *
     * @param key 數據KEY
     * @param val 數據
     * @return 判斷是否緩存了
     */
    public static boolean isMember(String key, String val) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.sIsMember(key.getBytes(), val.getBytes());
        });
    }

    /**
     * 從緩存中刪除數據
     *
     * @param key
     * @return
     */
    public static void delKey(String key) {

        cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> connection.del(key.getBytes()));
    }

    /**
     * 設置超時時間
     *
     * @param key
     * @param seconds
     */
    public static void expire(String key, int seconds) {
        cacheUtils.redisTemplate
                .execute((RedisCallback<Boolean>) connection -> connection.expire(key.getBytes(), seconds));

    }

    /**
     * 列出set中所有成員
     *
     * @param setName set名
     * @return
     */
    public static Set<Object> listSet(String setName) {

        return cacheUtils.redisTemplate.opsForHash().keys(setName);

    }

    /**
     * 向set中追加一個值
     *
     * @param setName set名
     * @param value
     */
    public static void setSave(String setName, String value) {

        cacheUtils.redisTemplate
                .execute((RedisCallback<Long>) connection -> connection.sAdd(setName.getBytes(), value.getBytes()));

    }

    /**
     * 利用redis實現分佈式鎖,防止集羣環境下 schedule定時任務重複執行的情況
     * @param key
     * @param value
     * @return
     */
    public static boolean setScheduler(final String key, String value) {
        boolean result = false;
        synchronized (cacheUtils){
            try {
                ValueOperations<String, String> operations = cacheUtils.redisTemplate.opsForValue();
                return operations.setIfAbsent(key, value);

            } catch (Exception e) {
                logger.error("定時器鎖設定失敗,失敗原因:",e);
            }
            return result;
        }
    }

    /**
     * 刪除對應的key
     * @param key
     */
    public static void remove(String key){
        cacheUtils.redisTemplate.delete(key);
    }

    /**
     * 逆序列出sorted set包括分數的set列表
     *
     * @param key   set名
     * @param start 開始位置
     * @param end   結束位置
     * @return 列表
     */
    public static Set<Tuple> listSortedsetRev(String key, int start, int end) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Set<Tuple>>) connection -> {
            return connection.zRevRangeWithScores(key.getBytes(), start, end);
        });
    }

    /**
     * 逆序取得sorted sort排名
     *
     * @param key    set名
     * @param member 成員名
     * @return 排名
     */
    public static Long getRankRev(String key, String member) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> {
            return connection.zRevRank(key.getBytes(), member.getBytes());
        });

    }

    /**
     * 根據成員名取得sorted sort分數
     *
     * @param key    set名
     * @param member 成員名
     * @return 分數
     */
    public static Double getMemberScore(String key, String member) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Double>) connection -> {
            return connection.zScore(key.getBytes(), member.getBytes());
        });
    }

    /**
     * 向sorted set中追加一個值
     *
     * @param key    set名
     * @param score  分數
     * @param member 成員名稱
     */
    public static void saveToSortedset(String key, Double score, String member) {

        cacheUtils.redisTemplate.execute(
                (RedisCallback<Boolean>) connection -> connection.zAdd(key.getBytes(), score, member.getBytes()));
    }

    /**
     * 從sorted set刪除一個值
     *
     * @param key    set名
     * @param member 成員名稱
     */
    public static void delFromSortedset(String key, String member) {
        cacheUtils.redisTemplate
                .execute((RedisCallback<Long>) connection -> connection.zRem(key.getBytes(), member.getBytes()));

    }

    /**
     * 從hash map中取得複雜JSON數據
     *
     * @param key
     * @param field
     * @param clazz
     */
    public static <T> T getBeanFromMap(String key, String field, Class<T> clazz) {

        byte[] input = cacheUtils.redisTemplate.execute((RedisCallback<byte[]>) connection -> {
            return connection.hGet(key.getBytes(), field.getBytes());
        });
        return JSON.parseObject(input, clazz, Feature.AutoCloseSource);
    }

    /**
     * 從hashmap中刪除一個值
     *
     * @param key   map名
     * @param field 成員名稱
     */
    public static void delFromMap(String key, String field) {

        cacheUtils.redisTemplate
                .execute((RedisCallback<Long>) connection -> connection.hDel(key.getBytes(), field.getBytes()));
    }

    /**
     * @param key
     * @return
     * @Description: 根據key增長 ,計數器
     * @author clg
     * @date 2016年6月30日 下午2:37:52
     */
    public static long incr(String key) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> {
            return connection.incr(key.getBytes());
        });
    }


    /**
     * 根據key獲取當前計數結果
     *
     * @param key
     * @return
     */
    public static String getCount(String key) {

        return cacheUtils.redisTemplate.opsForValue().get(key);
    }

    /**
     * 將所有指定的值插入到存於 key 的列表的頭部。如果 key 不存在,那麼在進行 push 操作前會創建一個空列表
     *
     * @param <T>
     * @param key
     * @param value
     * @return
     */
    public static <T> Long lpush(String key, T value) {

        return cacheUtils.redisTemplate.opsForList().leftPush(key, JSON.toJSONString(value));
    }

    /**
     * 只有當 key 已經存在並且存着一個 list 的時候,在這個 key 下面的 list 的頭部插入 value。 與 LPUSH 相反,當 key
     * 不存在的時候不會進行任何操作
     *
     * @param key
     * @param value
     * @return
     */
    public static <T> Long lpushx(String key, T value) {

        return cacheUtils.redisTemplate.opsForList().leftPushIfPresent(key, JSON.toJSONString(value));
    }

    /**
     * 返回存儲在 key 裏的list的長度。 如果 key 不存在,那麼就被看作是空list,並且返回長度爲 0
     *
     * @param key
     * @return
     */
    public static Long llen(String key) {

        return cacheUtils.redisTemplate.opsForList().size(key);
    }

    /**
     * 返回存儲在 key 的列表裏指定範圍內的元素。 start 和 end
     * 偏移量都是基於0的下標,即list的第一個元素下標是0(list的表頭),第二個元素下標是1,以此類推
     *
     * @param key
     * @return
     */
    public static List<String> lrange(String key, long start, long end) {

        return cacheUtils.redisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 移除並且返回 key 對應的 list 的第一個元素
     *
     * @param key
     * @return
     */
    public static String lpop(String key) {

        return cacheUtils.redisTemplate.opsForList().leftPop(key);
    }

    /**
     * 保存到hash集合中 只在 key 指定的哈希集中不存在指定的字段時,設置字段的值。如果 key 指定的哈希集不存在,會創建一個新的哈希集並與 key
     * 關聯。如果字段已存在,該操作無效果。
     *
     * @param hName 集合名
     * @param key
     * @param value
     */
    public static void hsetnx(String hName, String key, String value) {

        cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.hSetNX(key.getBytes(),
                key.getBytes(), value.getBytes()));

    }

    /**
     * 保存到hash集合中 只在 key 指定的哈希集中不存在指定的字段時,設置字段的值。如果 key 指定的哈希集不存在,會創建一個新的哈希集並與 key
     * 關聯。如果字段已存在,該操作無效果。
     *
     * @param hName 集合名
     * @param key
     * @param t
     * @param <T>
     */
    public static <T> void hsetnx(String hName, String key, T t) {
        hsetnx(hName, key, JSON.toJSONString(t));
    }

    /**
     * 驗證token是否有效
     *
     * @param token
     * @return 驗證結果
     */
    private static Result tokenVerify(String token) {
        Result result = new Result();
        if (token != null && !token.equals("")) {
            try {
                Jwts.parser()
                        .setSigningKey(ConstantKey.SIGNING_KEY)
                        .parseClaimsJws(token.replace("Bearer ", ""))
                        .getBody()
                        .getSubject();
                result.setCode("200");
                result.setSuccess(true);
                return result;

            } catch (ExpiredJwtException e) {
                logger.error("Token已過期: {} " + e);
                result.setSuccess(false);
                result.setCode("401");
                result.setMessage("請求超時");
                return result;
            } catch (UnsupportedJwtException e) {
                logger.error("Token格式錯誤: {} " + e);
                result.setSuccess(false);
                result.setCode("413");
                result.setMessage("不被支持的令牌");
                return result;

            } catch (MalformedJwtException e) {
                logger.error("Token沒有被正確構造: {} " + e);
                result.setSuccess(false);
                result.setCode("414");
                result.setMessage("令牌格式錯誤");
                return result;
            } catch (SignatureException e) {
                logger.error("簽名失敗: {} " + e);
                result.setSuccess(false);
                result.setCode("415");
                result.setMessage("令牌簽名失敗");
                return result;
            } catch (IllegalArgumentException e) {
                logger.error("非法參數異常: {} " + e);
                result.setSuccess(false);
                result.setCode("416");
                result.setMessage("錯誤的參數");
                return result;
            }
        } else {
            result.setSuccess(false);
            result.setCode("417");
            result.setMessage("沒有接收到令牌");
            return result;
        }
    }
}

7.爲了方便創建第二個數據源使用的

 

package cn.gov.credream.scsupport.util;

import cn.gov.credream.sccommon.core.ConstantKey;
import cn.gov.credream.sccommon.core.Result;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 描述: 操作redis 工具類
 * author: credream
 * Date: 2018/09/19 15:01
 */
@Component
public class CacheUtils {

    @Resource(name="defaultRedisTemplate")
    private StringRedisTemplate redisTemplate;


    private static CacheUtils cacheUtils;

    private static final Logger logger = LoggerFactory.getLogger(CacheUtils.class);

    @PostConstruct
    public void init() {
        cacheUtils = this;
        cacheUtils.redisTemplate = this.redisTemplate;
    }

    /**
     * 獲取所有登錄的用戶
     *
     * @return
     */
    public static Integer getOnlineUsers() {
        Integer userCount = 0;
        userCount = cacheUtils.redisTemplate.keys("*").size();
        return userCount;
    }


    /**
     * 將數據存入緩存
     *
     * @param key
     * @param val
     * @return
     */
    public static void saveString(String key, String val) {

        ValueOperations<String, String> vo = cacheUtils.redisTemplate.opsForValue();
        vo.set(key, val);
    }

    /**
     * 將數據存入緩存的集合中
     *
     * @param key
     * @param val
     * @return
     */
    public static void saveToSet(String key, String val) {

        SetOperations<String, String> so = cacheUtils.redisTemplate.opsForSet();

        so.add(key, val);
    }

    /**
     * key 緩存Key
     *
     * @param key
     * @return
     */
    public static String getFromSet(String key) {
        return cacheUtils.redisTemplate.opsForSet().pop(key);
    }

    /**
     * 將 key的值保存爲 value ,當且僅當 key 不存在。 若給定的 key 已經存在,則 SETNX 不做任何動作。 SETNX 是『SET if
     * Not eXists』(如果不存在,則 SET)的簡寫。 <br>
     * 保存成功,返回 true <br>
     * 保存失敗,返回 false
     */
    public static boolean saveNX(String key, String val) {

        /** 設置成功,返回 1 設置失敗,返回 0 **/
        return cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.setNX(key.getBytes(), val.getBytes());
        });

    }

    /**
     * 將 key的值保存爲 value ,當且僅當 key 不存在。 若給定的 key 已經存在,則 SETNX 不做任何動作。 SETNX 是『SET if
     * Not eXists』(如果不存在,則 SET)的簡寫。 <br>
     * 保存成功,返回 true <br>
     * 保存失敗,返回 false
     *
     * @param key
     * @param val
     * @param expire 超時時間
     * @return 保存成功,返回 true 否則返回 false
     */
    public static boolean saveNX(String key, String val, int expire) {

        boolean ret = saveNX(key, val);
        if (ret) {
            cacheUtils.redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
        return ret;
    }

    /**
     * 將數據存入緩存(並設置失效時間)
     *
     * @param key
     * @param val
     * @param seconds
     * @return
     */
    public static void saveString(String key, String val, int seconds) {

        cacheUtils.redisTemplate.opsForValue().set(key, val, seconds, TimeUnit.SECONDS);
    }

    /**
     * 將自增變量存入緩存
     */
    public static void saveSeq(String key, long seqNo) {

        cacheUtils.redisTemplate.delete(key);
        cacheUtils.redisTemplate.opsForValue().increment(key, seqNo);
    }

    /**
     * 將遞增浮點數存入緩存
     */
    public static void saveFloat(String key, float data) {

        cacheUtils.redisTemplate.delete(key);
        cacheUtils.redisTemplate.opsForValue().increment(key, data);
    }

    /**
     * 保存複雜類型數據到緩存
     *
     * @param key
     * @param obj
     * @return
     */
    public static void saveBean(String key, Object obj) {

        cacheUtils.redisTemplate.opsForValue().set(key, JSON.toJSONString(obj));
    }

    /**
     * 保存複雜類型數據到緩存(並設置失效時間)
     *
     * @param key
     * @param obj
     * @param seconds
     */
    public static void saveBean(String key, Object obj, int seconds) {

        cacheUtils.redisTemplate.opsForValue().set(key, JSON.toJSONString(obj), seconds, TimeUnit.SECONDS);
    }

    /**
     * 存到指定的隊列中
     *
     * @param key
     * @param val
     * @param size
     */
    public static void saveToQueue(String key, String val, long size) {

        ListOperations<String, String> lo = cacheUtils.redisTemplate.opsForList();

        if (size > 0 && lo.size(key) >= size) {
            lo.rightPop(key);
        }
        lo.leftPush(key, val);
    }

    /**
     * 保存到hash集合中
     *
     * @param hName 集合名
     * @param key
     * @param value
     */
    public static void hashSet(String hName, String key, String value) {

        cacheUtils.redisTemplate.opsForHash().put(hName, key, value);
    }

    /**
     * 根據key獲取所以值
     *
     * @param key
     * @return
     */
    public static Map<Object, Object> hgetAll(String key) {

        return cacheUtils.redisTemplate.opsForHash().entries(key);
    }

    /**
     * 保存到hash集合中
     *
     * @param <T>
     * @param hName 集合名
     * @param key
     * @param t
     */
    public static <T> void hashSet(String hName, String key, T t) {

        hashSet(hName, key, JSON.toJSONString(t));
    }

    /**
     * 取得複雜JSON數據
     *
     * @param key
     * @param clazz
     * @param clazz
     * @return
     */
    public static <T> T getBean(String key, Class<T> clazz) {

        String value = cacheUtils.redisTemplate.opsForValue().get(key);
        if (value == null) {
            return null;
        }
        return JSON.parseObject(value, clazz);
    }

    /**
     * 從緩存中取得字符串數據
     *
     * @param key
     * @return 數據
     */
    public static String getString(String key) {
        cacheUtils.redisTemplate.opsForValue().get(key);

        return cacheUtils.redisTemplate.opsForValue().get(key);
    }

    /**
     * 從指定隊列裏取得數據
     *
     * @param key
     * @param size
     * @return
     */
    public static List<String> getFromQueue(String key, long size) {

        boolean flag = cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.exists(key.getBytes());
        });

        if (flag) {
            return new ArrayList<>();
        }
        ListOperations<String, String> lo = cacheUtils.redisTemplate.opsForList();
        if (size > 0) {
            return lo.range(key, 0, size - 1);
        } else {
            return lo.range(key, 0, lo.size(key) - 1);
        }
    }

    /**
     * 從指定隊列裏取得數據
     *
     * @param key
     * @return
     */
    public static String popQueue(String key) {

        return cacheUtils.redisTemplate.opsForList().rightPop(key);

    }

    /**
     * 取得序列值的下一個
     *
     * @param key
     * @return
     */
    public static Long getSeqNext(String key) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> {

            return connection.incr(key.getBytes());

        });
    }

    /**
     * 取得序列值的下一個
     *
     * @param key
     * @return
     */
    public static Long getSeqNext(String key, long value) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> {

            return connection.incrBy(key.getBytes(), value);

        });

    }

    /**
     * 將序列值回退一個
     *
     * @param key
     * @return
     */
    public static void getSeqBack(String key) {

        cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> connection.decr(key.getBytes()));

    }

    /**
     * 從hash集合裏取得
     *
     * @param hName
     * @param key
     * @return
     */
    public static Object hashGet(String hName, String key) {

        return cacheUtils.redisTemplate.opsForHash().get(hName, key);
    }

    public static <T> T hashGet(String hName, String key, Class<T> clazz) {

        return JSON.parseObject((String) hashGet(hName, key), clazz);
    }

    /**
     * 增加浮點數的值
     *
     * @param key
     * @return
     */
    public static Double incrFloat(String key, double incrBy) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Double>) connection -> {

            return connection.incrBy(key.getBytes(), incrBy);

        });
    }

    /**
     * 判斷是否緩存了數據
     *
     * @param key 數據KEY
     * @return 判斷是否緩存了
     */
    public static boolean isCached(String key) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.exists(key.getBytes());
        });
    }

    /**
     * 判斷hash集合中是否緩存了數據
     *
     * @param hName
     * @param key   數據KEY
     * @return 判斷是否緩存了
     */
    public static boolean hashCached(String hName, String key) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.hExists(key.getBytes(), key.getBytes());
        });
    }

    /**
     * 判斷是否緩存在指定的集合中
     *
     * @param key 數據KEY
     * @param val 數據
     * @return 判斷是否緩存了
     */
    public static boolean isMember(String key, String val) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> {
            return connection.sIsMember(key.getBytes(), val.getBytes());
        });
    }

    /**
     * 從緩存中刪除數據
     *
     * @param key
     * @return
     */
    public static void delKey(String key) {

        cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> connection.del(key.getBytes()));
    }

    /**
     * 設置超時時間
     *
     * @param key
     * @param seconds
     */
    public static void expire(String key, int seconds) {
        cacheUtils.redisTemplate
                .execute((RedisCallback<Boolean>) connection -> connection.expire(key.getBytes(), seconds));

    }

    /**
     * 列出set中所有成員
     *
     * @param setName set名
     * @return
     */
    public static Set<Object> listSet(String setName) {

        return cacheUtils.redisTemplate.opsForHash().keys(setName);

    }

    /**
     * 向set中追加一個值
     *
     * @param setName set名
     * @param value
     */
    public static void setSave(String setName, String value) {

        cacheUtils.redisTemplate
                .execute((RedisCallback<Long>) connection -> connection.sAdd(setName.getBytes(), value.getBytes()));

    }

    /**
     * 利用redis實現分佈式鎖,防止集羣環境下 schedule定時任務重複執行的情況
     * @param key
     * @param value
     * @return
     */
    public static boolean setScheduler(final String key, String value) {
        boolean result = false;
        synchronized (cacheUtils){
            try {
                ValueOperations<String, String> operations = cacheUtils.redisTemplate.opsForValue();
                return operations.setIfAbsent(key, value);

            } catch (Exception e) {
                logger.error("定時器鎖設定失敗,失敗原因:",e);
            }
            return result;
        }
    }

    /**
     * 刪除對應的key
     * @param key
     */
    public static void remove(String key){
        cacheUtils.redisTemplate.delete(key);
    }

    /**
     * 逆序列出sorted set包括分數的set列表
     *
     * @param key   set名
     * @param start 開始位置
     * @param end   結束位置
     * @return 列表
     */
    public static Set<Tuple> listSortedsetRev(String key, int start, int end) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Set<Tuple>>) connection -> {
            return connection.zRevRangeWithScores(key.getBytes(), start, end);
        });
    }

    /**
     * 逆序取得sorted sort排名
     *
     * @param key    set名
     * @param member 成員名
     * @return 排名
     */
    public static Long getRankRev(String key, String member) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> {
            return connection.zRevRank(key.getBytes(), member.getBytes());
        });

    }

    /**
     * 根據成員名取得sorted sort分數
     *
     * @param key    set名
     * @param member 成員名
     * @return 分數
     */
    public static Double getMemberScore(String key, String member) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Double>) connection -> {
            return connection.zScore(key.getBytes(), member.getBytes());
        });
    }

    /**
     * 向sorted set中追加一個值
     *
     * @param key    set名
     * @param score  分數
     * @param member 成員名稱
     */
    public static void saveToSortedset(String key, Double score, String member) {

        cacheUtils.redisTemplate.execute(
                (RedisCallback<Boolean>) connection -> connection.zAdd(key.getBytes(), score, member.getBytes()));
    }

    /**
     * 從sorted set刪除一個值
     *
     * @param key    set名
     * @param member 成員名稱
     */
    public static void delFromSortedset(String key, String member) {
        cacheUtils.redisTemplate
                .execute((RedisCallback<Long>) connection -> connection.zRem(key.getBytes(), member.getBytes()));

    }

    /**
     * 從hash map中取得複雜JSON數據
     *
     * @param key
     * @param field
     * @param clazz
     */
    public static <T> T getBeanFromMap(String key, String field, Class<T> clazz) {

        byte[] input = cacheUtils.redisTemplate.execute((RedisCallback<byte[]>) connection -> {
            return connection.hGet(key.getBytes(), field.getBytes());
        });
        return JSON.parseObject(input, clazz, Feature.AutoCloseSource);
    }

    /**
     * 從hashmap中刪除一個值
     *
     * @param key   map名
     * @param field 成員名稱
     */
    public static void delFromMap(String key, String field) {

        cacheUtils.redisTemplate
                .execute((RedisCallback<Long>) connection -> connection.hDel(key.getBytes(), field.getBytes()));
    }

    /**
     * @param key
     * @return
     * @Description: 根據key增長 ,計數器
     * @author clg
     * @date 2016年6月30日 下午2:37:52
     */
    public static long incr(String key) {

        return cacheUtils.redisTemplate.execute((RedisCallback<Long>) connection -> {
            return connection.incr(key.getBytes());
        });
    }


    /**
     * 根據key獲取當前計數結果
     *
     * @param key
     * @return
     */
    public static String getCount(String key) {

        return cacheUtils.redisTemplate.opsForValue().get(key);
    }

    /**
     * 將所有指定的值插入到存於 key 的列表的頭部。如果 key 不存在,那麼在進行 push 操作前會創建一個空列表
     *
     * @param <T>
     * @param key
     * @param value
     * @return
     */
    public static <T> Long lpush(String key, T value) {

        return cacheUtils.redisTemplate.opsForList().leftPush(key, JSON.toJSONString(value));
    }

    /**
     * 只有當 key 已經存在並且存着一個 list 的時候,在這個 key 下面的 list 的頭部插入 value。 與 LPUSH 相反,當 key
     * 不存在的時候不會進行任何操作
     *
     * @param key
     * @param value
     * @return
     */
    public static <T> Long lpushx(String key, T value) {

        return cacheUtils.redisTemplate.opsForList().leftPushIfPresent(key, JSON.toJSONString(value));
    }

    /**
     * 返回存儲在 key 裏的list的長度。 如果 key 不存在,那麼就被看作是空list,並且返回長度爲 0
     *
     * @param key
     * @return
     */
    public static Long llen(String key) {

        return cacheUtils.redisTemplate.opsForList().size(key);
    }

    /**
     * 返回存儲在 key 的列表裏指定範圍內的元素。 start 和 end
     * 偏移量都是基於0的下標,即list的第一個元素下標是0(list的表頭),第二個元素下標是1,以此類推
     *
     * @param key
     * @return
     */
    public static List<String> lrange(String key, long start, long end) {

        return cacheUtils.redisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 移除並且返回 key 對應的 list 的第一個元素
     *
     * @param key
     * @return
     */
    public static String lpop(String key) {

        return cacheUtils.redisTemplate.opsForList().leftPop(key);
    }

    /**
     * 保存到hash集合中 只在 key 指定的哈希集中不存在指定的字段時,設置字段的值。如果 key 指定的哈希集不存在,會創建一個新的哈希集並與 key
     * 關聯。如果字段已存在,該操作無效果。
     *
     * @param hName 集合名
     * @param key
     * @param value
     */
    public static void hsetnx(String hName, String key, String value) {

        cacheUtils.redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.hSetNX(key.getBytes(),
                key.getBytes(), value.getBytes()));

    }

    /**
     * 保存到hash集合中 只在 key 指定的哈希集中不存在指定的字段時,設置字段的值。如果 key 指定的哈希集不存在,會創建一個新的哈希集並與 key
     * 關聯。如果字段已存在,該操作無效果。
     *
     * @param hName 集合名
     * @param key
     * @param t
     * @param <T>
     */
    public static <T> void hsetnx(String hName, String key, T t) {
        hsetnx(hName, key, JSON.toJSONString(t));
    }

    /**
     * 驗證token是否有效
     *
     * @param token
     * @return 驗證結果
     */
    private static Result tokenVerify(String token) {
        Result result = new Result();
        if (token != null && !token.equals("")) {
            try {
                Jwts.parser()
                        .setSigningKey(ConstantKey.SIGNING_KEY)
                        .parseClaimsJws(token.replace("Bearer ", ""))
                        .getBody()
                        .getSubject();
                result.setCode("200");
                result.setSuccess(true);
                return result;

            } catch (ExpiredJwtException e) {
                logger.error("Token已過期: {} " + e);
                result.setSuccess(false);
                result.setCode("401");
                result.setMessage("請求超時");
                return result;
            } catch (UnsupportedJwtException e) {
                logger.error("Token格式錯誤: {} " + e);
                result.setSuccess(false);
                result.setCode("413");
                result.setMessage("不被支持的令牌");
                return result;

            } catch (MalformedJwtException e) {
                logger.error("Token沒有被正確構造: {} " + e);
                result.setSuccess(false);
                result.setCode("414");
                result.setMessage("令牌格式錯誤");
                return result;
            } catch (SignatureException e) {
                logger.error("簽名失敗: {} " + e);
                result.setSuccess(false);
                result.setCode("415");
                result.setMessage("令牌簽名失敗");
                return result;
            } catch (IllegalArgumentException e) {
                logger.error("非法參數異常: {} " + e);
                result.setSuccess(false);
                result.setCode("416");
                result.setMessage("錯誤的參數");
                return result;
            }
        } else {
            result.setSuccess(false);
            result.setCode("417");
            result.setMessage("沒有接收到令牌");
            return result;
        }
    }
}

 8.新建測試類測試:

 

package cn.gov.credream.scsupport;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ScSupportApplicationTests {

    @Test
    public void contextLoads() {

    }

    @Resource(name = "defaultRedisTemplate")
    private StringRedisTemplate redisTemplate;

    @Resource(name = "cacheRedisTemplate")
    private StringRedisTemplate redisTemplate1;

    @Test
    public void stringRedisTest() {

        redisTemplate.opsForValue().set("slzzzz", "111111");
        redisTemplate1.opsForValue().set("slzzzz", "222222");

    }

    @Test
    public void objectRedisTest() {
        redisTemplate.opsForValue().set("person", "777777777777777");
        redisTemplate1.opsForValue().set("person", "1234564564");
    }


}

9.注意,如果測試的時候報錯:

java.lang.NoSuchMethodError: org.springframework.util.Assert.state(ZLjava/util/function/Supplier;)V

at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:379) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildDefaultMergedContextConfiguration(AbstractTestContextBootstrapper.java:312) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:265) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildTestContext(AbstractTestContextBootstrapper.java:108) at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.buildTestContext(SpringBootTestContextBootstrapper.java:82) at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:139) at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:124) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTestContextManager(SpringJUnit4ClassRunner.java:151) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:142) at org.springframework.test.context.junit4.SpringRunner.<init>(SpringRunner.java:49) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104) at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26) at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59) at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33) at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:36) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:49) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

 

需要把:

<!--<dependency>-->
    <!--<groupId>org.springframework</groupId>-->
    <!--<artifactId>spring-test</artifactId>-->
    <!--<version>RELEASE</version>-->
<!--</dependency>-->

刪除然後重新啓動就可以了.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章