亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot實現(xiàn)緩存組件配置動態(tài)切換的步驟詳解

 更新時間:2024年07月26日 11:51:28   作者:Mr Tang  
現(xiàn)在有多個springboot項目,但是不同的項目中使用的緩存組件是不一樣的,有的項目使用redis,有的項目使用ctgcache,現(xiàn)在需要用同一套代碼通過配置開關(guān),在不同的項目中切換這兩種緩存,本文介紹了SpringBoot實現(xiàn)緩存組件配置動態(tài)切換的步驟,需要的朋友可以參考下

一、需求背景

現(xiàn)在有多個springboot項目,但是不同的項目中使用的緩存組件是不一樣的,有的項目使用redis,有的項目使用ctgcache,現(xiàn)在需要用同一套代碼通過配置開關(guān),在不同的項目中切換這兩種緩存。

二、實現(xiàn)緩存組件的動態(tài)切換

1.第一步:配置文件新增切換開關(guān)

#緩存組件配置
#cache.type=ctgcache
cache.type=redis

2.第二步:創(chuàng)建ctgcache 緩存條件類

package com.gstanzer.supervise.cache;
 
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
 
/**
 * ctgcache 緩存條件類
 *
 * @author: tangbingbing
 * @date: 2024/7/22 14:31
 */
public class CtgCacheCondition implements Condition {
 
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 從 Environment 中獲取屬性
        Environment env = context.getEnvironment();
        String cacheType = env.getProperty("cache.type");
 
        // 檢查 cache.type 是否與 metadata 中的某個值匹配(這里簡單比較字符串)
        // 注意:實際應(yīng)用中可能需要更復(fù)雜的邏輯來確定 metadata 中的值
        // 這里我們假設(shè) metadata 中沒有特定值,僅根據(jù) cache.type 判斷
        if ("ctgcache".equalsIgnoreCase(cacheType)) {
            // 使用 ctgcache
            return true;
        }
 
        // 如果沒有明確指定,或者指定了其他值,我們可以選擇默認(rèn)行為
        // 這里假設(shè)默認(rèn)不使用這個 Bean
        return false;
    }
 
}

3.第三步:創(chuàng)建redis 緩存條件類

package com.gstanzer.supervise.cache;
 
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
 
/**
 * redis 緩存條件類
 *
 * @author: tangbingbing
 * @date: 2024/7/22 14:31
 */
public class RedisCondition implements Condition {
 
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 從 Environment 中獲取屬性
        Environment env = context.getEnvironment();
        String cacheType = env.getProperty("cache.type");
 
        // 檢查 cache.type 是否與 metadata 中的某個值匹配(這里簡單比較字符串)
        // 注意:實際應(yīng)用中可能需要更復(fù)雜的邏輯來確定 metadata 中的值
        // 這里我們假設(shè) metadata 中沒有特定值,僅根據(jù) cache.type 判斷
        if ("redis".equalsIgnoreCase(cacheType)) {
            // 使用 Redis
            return true;
        }
 
        // 如果沒有明確指定,或者指定了其他值,我們可以選擇默認(rèn)行為
        // 這里假設(shè)默認(rèn)不使用這個 Bean
        return false;
    }
 
}

4.第四步:創(chuàng)建緩存切換配置類

package com.gstanzer.supervise.cache;
 
import com.ctg.itrdc.cache.pool.CtgJedisPool;
import com.ctg.itrdc.cache.pool.CtgJedisPoolConfig;
import com.ctg.itrdc.cache.vjedis.jedis.JedisPoolConfig;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
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.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.HostAndPort;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * 緩存配置類
 *
 * @author: tangbingbing
 * @date: 2024/7/22 14:28
 */
@Configuration
public class CacheConfig {
 
    @Value("${access.cq.redis.host1}")
    private String reidsHost1;
 
    @Value("${access.cq.redis.host2}")
    private String reidsHost2;
 
    @Value("${access.cq.redis.port}")
    private int port;
 
    @Value("${access.cq.redis.password}")
    private String password;
 
    @Value("${access.cq.redis.group}")
    private String group;
 
    @Value("${access.cq.redis.max-total}")
    private int maxTotal;
 
    @Value("${access.cq.redis.max-idle}")
    private int maxIdle;
 
    @Value("${access.cq.redis.min-idle}")
    private int minIdle;
 
    @Value("${access.cq.redis.max-wait}")
    private int maxWait;
 
    @Value("${access.cq.redis.period}")
    private int period;
 
    @Value("${access.cq.redis.monitor-timeout}")
    private int monitorTimeout;
 
    @Bean
    @Conditional(RedisCondition.class)
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 創(chuàng)建并返回RedisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
 
 
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);
        redisTemplate.setHashKeySerializer(redisSerializer);
 
        // 設(shè)置value的序列化器
        //使用Jackson 2,將對象序列化為JSON
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //json轉(zhuǎn)對象類,不設(shè)置默認(rèn)的會將json轉(zhuǎn)成hashmap
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
 
        // json中會顯示類型
//        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
 
    @Bean
    @Conditional(RedisCondition.class)
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
        // 創(chuàng)建并返回RedisMessageListenerContainer
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        // 監(jiān)聽所有庫的key過期事件
        container.setConnectionFactory(connectionFactory);
        return container;
    }
 
    @Bean
    @Conditional(CtgCacheCondition.class)
    public CtgJedisPool ctgJedisPool() {
        // 創(chuàng)建并返回CtgJedisPool
        List<HostAndPort> hostAndPortList = new ArrayList();
        HostAndPort host1 = new HostAndPort(reidsHost1, port);
        HostAndPort host2 = new HostAndPort(reidsHost2, port);
        hostAndPortList.add(host1);
        hostAndPortList.add(host2);
 
        GenericObjectPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(maxTotal); // 最大連接數(shù)(空閑+使用中)
        poolConfig.setMaxIdle(maxIdle); //最大空閑連接數(shù)
        poolConfig.setMinIdle(minIdle); //保持的最小空閑連接數(shù)
        poolConfig.setMaxWaitMillis(maxWait); //借出連接時最大的等待時間
 
        CtgJedisPoolConfig config = new CtgJedisPoolConfig(hostAndPortList);
        config.setDatabase(group)
                .setPassword(password)
                .setPoolConfig(poolConfig)
                .setPeriod(period)
                .setMonitorTimeout(monitorTimeout);
 
        CtgJedisPool pool = new CtgJedisPool(config);
        return pool;
    }
}

5.第五步:創(chuàng)建緩存服務(wù)接口

package com.gstanzer.supervise.cache;
 
/**
 * 緩存服務(wù)接口
 *
 * @author: tangbingbing
 * @date: 2024/7/22 14:46
 */
public interface CacheService {
 
    /**
     * 檢查緩存中是否存在某個key
     *
     * @param key
     * @return
     */
    public boolean exists(final String key);
 
    /**
     * 獲取緩存中對應(yīng)key的value值
     *
     * @param key
     * @return
     */
    public String get(final String key);
 
    /**
     * 存入值到緩存,并設(shè)置有效期
     *
     * @param key
     * @param value
     * @param expireTime 有效期,單位s
     * @return
     */
    public boolean set(final String key, String value, int expireTime);
 
    /**
     * 存入值到緩存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, String value);
 
    /**
     * 刪除緩存對應(yīng)的key值
     *
     * @param key
     * @return
     */
    public boolean del(final String key);
 
}

6.第六步:創(chuàng)建ctgcache實現(xiàn)類實現(xiàn)緩存服務(wù)接口

package com.gstanzer.supervise.cache;
 
import com.ctg.itrdc.cache.pool.CtgJedisPool;
import com.ctg.itrdc.cache.pool.ProxyJedis;
import com.gstanzer.supervise.ctgcache.CtgRedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
 
/**
 * ctgcache 緩存方法實現(xiàn)
 *
 * @author: tangbingbing
 * @date: 2024/7/22 14:48
 */
@Service
@Conditional(CtgCacheCondition.class)
public class CtgCacheService implements CacheService {
 
    private static Logger logger = LoggerFactory.getLogger(CtgRedisUtil.class);
 
    @Resource
    private CtgJedisPool ctgJedisPool;
 
    /**
     * 判斷緩存中是否有對應(yīng)的value
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        Boolean exists = false;
        ProxyJedis jedis = new ProxyJedis();
        try {
            jedis = ctgJedisPool.getResource();
            exists = jedis.exists(key);
            jedis.close();
        } catch (Throwable e) {
            logger.error(e.getMessage());
            jedis.close();
        } finally {
            // finally內(nèi)執(zhí)行,確保連接歸還
            try {
                jedis.close();
            } catch (Throwable ignored) {
 
            }
        }
        return exists;
    }
 
    /**
     * 讀取緩存
     *
     * @param key
     * @return
     */
    public String get(final String key) {
        String value = null;
        ProxyJedis jedis = new ProxyJedis();
        try {
            jedis = ctgJedisPool.getResource();
            value = jedis.get(key);
            jedis.close();
        } catch (Throwable e) {
            logger.error(e.getMessage());
            jedis.close();
        } finally {
            // finally內(nèi)執(zhí)行,確保連接歸還
            try {
                jedis.close();
            } catch (Throwable ignored) {
 
            }
        }
        return value;
    }
 
    /**
     * 寫入緩存設(shè)置時效時間
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, String value, int expireTime) {
        Boolean result = false;
        ProxyJedis jedis = new ProxyJedis();
        try {
            jedis = ctgJedisPool.getResource();
            jedis.setex(key, expireTime, value);
            result = true;
            jedis.close();
        } catch (Throwable e) {
            logger.error(e.getMessage());
            jedis.close();
        } finally {
            // finally內(nèi)執(zhí)行,確保連接歸還
            try {
                jedis.close();
            } catch (Throwable ignored) {
 
            }
        }
        return result;
    }
 
    /**
     * 寫入緩存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, String value) {
        Boolean result = false;
        ProxyJedis jedis = new ProxyJedis();
        try {
            jedis = ctgJedisPool.getResource();
            jedis.set(key, value);
            result = true;
            jedis.close();
        } catch (Throwable e) {
            logger.error(e.getMessage());
            jedis.close();
        } finally {
            // finally內(nèi)執(zhí)行,確保連接歸還
            try {
                jedis.close();
            } catch (Throwable ignored) {
 
            }
        }
        return result;
    }
 
    /**
     * 刪除緩存
     *
     * @param key
     * @return
     */
    public boolean del(final String key) {
        Boolean result = false;
        ProxyJedis jedis = new ProxyJedis();
        try {
            jedis = ctgJedisPool.getResource();
            jedis.del(key);
            result = true;
            jedis.close();
        } catch (Throwable e) {
            logger.error(e.getMessage());
            jedis.close();
        } finally {
            // finally內(nèi)執(zhí)行,確保連接歸還
            try {
                jedis.close();
            } catch (Throwable ignored) {
 
            }
        }
        return result;
    }
 
}

7.第七步:創(chuàng)建redis實現(xiàn)類實現(xiàn)緩存服務(wù)接口

package com.gstanzer.supervise.cache;
 
import com.gstanzer.supervise.redis.RedisUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Conditional;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
 
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
 
/**
 * reids 緩存方法實現(xiàn)
 *
 * @author: tangbingbing
 * @date: 2024/7/22 14:48
 */
@Service
@Conditional(RedisCondition.class)
public class RedisCacheService implements CacheService {
 
    @Autowired
    private RedisTemplate redisTemplate;
 
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
 
    private static Logger logger = LoggerFactory.getLogger(RedisUtils.class);
 
    /**
     * 檢查緩存中是否存在某個key
     *
     * @param key
     * @return
     */
    @Override
    public boolean exists(String key) {
        return redisTemplate.hasKey(key);
    }
 
    /**
     * 獲取緩存中對應(yīng)key的value值
     *
     * @param key
     * @return
     */
    @Override
    public String get(String key) {
        String result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key).toString();
        return result;
    }
 
    /**
     * 存入值到緩存,并設(shè)置有效期
     *
     * @param key
     * @param value
     * @param expireTime 有效期,單位s
     * @return
     */
    @Override
    public boolean set(String key, String value, int expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
 
    /**
     * 存入值到緩存
     *
     * @param key
     * @param value
     * @return
     */
    @Override
    public boolean set(String key, String value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
 
    /**
     * 刪除緩存對應(yīng)的key值
     *
     * @param key
     * @return
     */
    @Override
    public boolean del(String key) {
        Boolean result = false;
        try {
            if (exists(key)) {
                redisTemplate.delete(key);
            }
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

8.第八步:在程序中注入緩存服務(wù)接口使用

package com.gstanzer.supervise.controller;
 
import com.gstanzer.supervise.cache.CacheService;
import com.gstanzer.supervise.jwt.PassToken;
import com.gstanzer.supervise.swagger.ApiForBackEndInIAM;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
 
import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
 
 
/**
 * 緩存測試 Controller
 *
 * @author: tangbingbing
 * @date: 2023/10/23 16:25
 */
@Api(tags = "緩存測試")
@Slf4j
@Validated
@RestController
@RequestMapping(value = "/redis")
public class RedisController {
 
 
    @Resource
    private CacheService cacheService;
 
    @PassToken
    @ApiForBackEndInIAM
    @ApiOperation(value = "redis測試")
    @PostMapping("/test")
    public String test(
            @RequestParam() @ApiParam(value = "redis鍵") @NotEmpty(message = "{validator.RedisController.test.key.NotEmpty}") String key
    ) {
        String res = "獲取到redis-value為:空";
        if (cacheService.exists(key)){
            String value = cacheService.get(key);
            res = "獲取到redis-value為:" + value;
        } else {
            cacheService.set(key,"test",60);
            res = "未獲取到value,重新設(shè)置值有效期為60s";
        }
        return res;
    }
}

三、總結(jié)

其實整體實現(xiàn)是一個比較簡單的過程,核心是需要了解Springboot中@Conditional注解的應(yīng)用,希望對大家有所幫助。

到此這篇關(guān)于SpringBoot實現(xiàn)緩存組件配置動態(tài)切換的步驟詳解的文章就介紹到這了,更多相關(guān)SpringBoot緩存組件動態(tài)切換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Reflect如何利用反射獲取屬性上的注解

    Java Reflect如何利用反射獲取屬性上的注解

    AnnotatedElement接口是Java反射機制的一部分,用于讀取運行中程序的注釋信息,通過getAnnotation、getAnnotations、isAnnotationPresent和getDeclaredAnnotations方法,可以訪問和判斷注解,Field類實現(xiàn)了該接口
    2024-09-09
  • 詳解Spring Cloud Zuul中路由配置細(xì)節(jié)

    詳解Spring Cloud Zuul中路由配置細(xì)節(jié)

    本篇文章主要介紹了詳解Spring Cloud Zuul中路由配置細(xì)節(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • java streamfilter list 過濾的實現(xiàn)

    java streamfilter list 過濾的實現(xiàn)

    Java Stream API中的filter方法是過濾List集合中元素的一個強大工具,可以輕松地根據(jù)自定義條件篩選出符合要求的元素,本文就來介紹一下java streamfilter list 過濾的實現(xiàn),感興趣的可以了解一下
    2025-03-03
  • Java操作redis實現(xiàn)增刪查改功能的方法示例

    Java操作redis實現(xiàn)增刪查改功能的方法示例

    這篇文章主要介紹了Java操作redis實現(xiàn)增刪查改功能的方法,涉及java操作redis數(shù)據(jù)庫的連接、設(shè)置、增刪改查、釋放資源等相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • 基于spring+quartz的分布式定時任務(wù)框架實現(xiàn)

    基于spring+quartz的分布式定時任務(wù)框架實現(xiàn)

    在Spring中的定時任務(wù)功能,最好的辦法當(dāng)然是使用Quartz來實現(xiàn)。這篇文章主要介紹了基于spring+quartz的分布式定時任務(wù)框架實現(xiàn),有興趣的可以了解一下。
    2017-01-01
  • java分布式緩存方案

    java分布式緩存方案

    本文簡單介紹了緩存的種類,緩存常見的問題,對大家的學(xué)習(xí)和工作有一定的參考價值,需要的小伙伴可以參考一下
    2021-08-08
  • mybaties plus實體類設(shè)置typeHandler不生效的解決

    mybaties plus實體類設(shè)置typeHandler不生效的解決

    這篇文章主要介紹了mybaties plus實體類設(shè)置typeHandler不生效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • java向上轉(zhuǎn)型發(fā)生的時機知識點詳解

    java向上轉(zhuǎn)型發(fā)生的時機知識點詳解

    在本篇文章里小編給大家整理分享的是關(guān)于java向上轉(zhuǎn)型發(fā)生的時機知識點內(nèi)容,有興趣的讀者們可以參考下。
    2021-05-05
  • springboot2.2.2集成dubbo的實現(xiàn)方法

    springboot2.2.2集成dubbo的實現(xiàn)方法

    這篇文章主要介紹了springboot2.2.2集成dubbo的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • Java使用Tess4J實現(xiàn)圖像識別方式

    Java使用Tess4J實現(xiàn)圖像識別方式

    這篇文章主要介紹了Java使用Tess4J實現(xiàn)圖像識別方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評論