欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring與Redis集成的正確方式流程詳解

 更新時間:2023年06月20日 14:19:40   作者:右耳菌  
這篇文章主要為大家介紹了Spring與Redis集成的正確方式流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

1. 引入RedisTemplate

據以前的情況,我們在Java中使用Redis時一般是使用Jedis來操作的,大致的一段代碼如下所示

    @Override
    public User findUserById(Integer id) {
        User user = null;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String userStr = jedis.get("user_" + id); // 嘗試獲取數據
            if (userStr != null && !userStr.isEmpty()) { // 如果獲取到有效數據,則轉換后返回
                user = JSONObject.parseObject(userStr, User.class);
            } else {// 如果沒有獲取到數據,則查詢數據庫返回
                user = userMapper.findUserById(id);
                if (user != null) jedis.set("user_" + id, JSONObject.toJSONString(user)); // 設置到redis中
            }
        } finally {
            // 記得關閉Jedis,因為這里使用的是JedisPool,所以這里的關閉并不是直接關閉連接,而是釋放,以供其他的業(yè)務使用
            if (jedis != null) jedis.close();
        }
        return user;
    }

上邊的這樣的一段代碼其實是有些臃腫的,但是如果我們引入RedisTemplate,其實會簡化不少。

  • maven 引入 spring-data-redis
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.9.0</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-redis</artifactId>
      <version>2.2.13.RELEASE</version>
    </dependency>
  • 將RedisTemplate 加入Bean容器中,讓Spring進行管理。
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setPort(port);
        RedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
        return redisConnectionFactory;
    }
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //設置key值的序列化方式,默認是JDK的形式
        redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8);
        return redisTemplate;
    }
  • 如果使用RedisTemplate的替換的話,會簡潔很多。
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public User findUserById(Integer id) {
        Object result = redisTemplate.opsForValue().get("user_" + id);
        if (result != null) return (User) result;
        User user = userMapper.findUserById(id);
        // 設置到redis中
        if (user != null) redisTemplate.opsForValue().set("user_" + id, user);
        return user;
    }

大概看一下關于RedisTemplate的方法

看了以上的內容,可以看到引入了RedisTemplate其實已經很簡潔了,但是明顯還不夠,下面我們將考慮引入 “注解”

2. 引入注解

  • 開啟緩存 @EnableCaching
    AppConfig.java
@Configuration
@EnableCaching
public class AppConfig {
  ...
}
  • 引入@Cacheable,表示這個方法將會訪問緩存,如果無法命中緩存的話,會將方法返回的值存入redis,假設有注解為 @Cacheable(value="user", key = "#id"),那么生成的key值為 user::{id},即如果id為1 那么生成的 key就是 user::1
    @Override
    @Cacheable(value="user", key = "#id")
    // 這里返回的值會被存放到redis,key-value格式,其中生成的key值(假設id為1): user::1
    public User findUserById(Integer id) {
        User user = userMapper.findUserById(id);
        return user;
    }

但是這樣還不夠,因為Spring并不清楚緩存的方式是什么,這就涉及到CacheManager

  • 設置CacheManager,在AppConfig中加入以下內容
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(host); // 這里是redis的ip
        redisStandaloneConfiguration.setPort(port);// 這里是redis的端口
        // 自適應集群變化
        RedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
        return redisConnectionFactory;
    }
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
        return redisCacheConfiguration;
    }
    @Bean
    public RedisCacheWriter redisCacheWriter(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        return redisCacheWriter;
    }
    @Bean
    public CacheManager cacheManager(RedisCacheWriter redisCacheWriter, RedisCacheConfiguration redisCacheConfiguration) {
        CacheManager cacheManager = new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
        ((RedisCacheManager) cacheManager).isTransactionAware();
        return cacheManager;
    }

3. 擴展 - 自行通過注解和AOP實現緩存

  • 引入AOP相關的包
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.3.22</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.3.22</version>
    </dependency>
    <!-- Jackson JSON Processor -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.8</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.8</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.8</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.28</version>
    </dependency>
  • 創(chuàng)建@CustomCache
package cn.lazyfennec.cache.redis.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomCache {
    /**
     * key的規(guī)則,可以使用springEL表達式,可以使用方法執(zhí)行的一些參數
     */
    String key();
    /**
     *  類似前綴
     * @return
     */
    String value();
}
  • 修改AppConfig
@EnableAspectJAutoProxy // 開啟AOP自動代理
public class AppConfig {
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setPort(port);
        // 自適應集群變化
        RedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
        return redisConnectionFactory;
    }
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8);
        redisTemplate.setValueSerializer(StringRedisSerializer.UTF_8);
        return redisTemplate;
    }
}
  • 創(chuàng)建 CustomCacheAspect
package cn.lazyfennec.cache.redis.annotation.aop;
import cn.lazyfennec.cache.redis.annotation.CustomCache;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
 * @Author: Neco
 * @Description:
 * @Date: create in 2022/8/24 22:18
 */
@Component
@Aspect
public class CustomCacheAspect {
    @Autowired
    private RedisTemplate redisTemplate;
    @Pointcut("@annotation(cn.lazyfennec.cache.redis.annotation.CustomCache)")
    public void cachePointcut() {
    }
    @Around("cachePointcut()")
    public Object doCache(ProceedingJoinPoint joinPoint) {
        Object obj = null;
        try {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = joinPoint.getTarget().getClass().getMethod(signature.getName(), signature.getMethod().getParameterTypes());
            CustomCache customCache = method.getAnnotation(CustomCache.class);
            String cacheKey = customCache.key();
            String cacheValue = customCache.value();
            // 創(chuàng)建解析器
            ExpressionParser parser = new SpelExpressionParser();
            Expression expression = parser.parseExpression(cacheKey);
            EvaluationContext context = new StandardEvaluationContext(); // 參數
            // 添加參數
            Object[] args = joinPoint.getArgs();
            DefaultParameterNameDiscoverer discover = new DefaultParameterNameDiscoverer();
            String[] parameterNames = discover.getParameterNames(method);
            for (int i = 0; i &lt; parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i].toString());
            }
            // 解析
            String key = cacheValue + "::" + expression.getValue(context).toString();
            // 1、 判定緩存中是否存在
            obj = redisTemplate.opsForValue().get(key);
            if (obj != null) return obj;
            // 2、不存在則繼續(xù)行方法
            obj = joinPoint.proceed();
            // 3、 同步存儲value到緩存。
            redisTemplate.opsForValue().set(key, obj);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return obj;
    }
}
  • 新建方法 getUserNameById
    @RequestMapping("/custom/name/{id}")
    @ResponseBody
    public String getUserNameById(@PathVariable Integer id) {
        return userService.getUserNameById(id);
    }
  • 實際實現方法 getUserNameById,使用方式
    @Override
    @CustomCache(value = "custom_user", key = "#id")
    public String getUserNameById(Integer id) {
        return userMapper.findUserNameById(id);
    }

以上就是Spring與Redis集成的正確方式詳解的詳細內容,更多關于Spring Redis集成方式的資料請關注腳本之家其它相關文章!

相關文章

  • 詳解SpringBoot讀取resource目錄下properties文件的常見方式

    詳解SpringBoot讀取resource目錄下properties文件的常見方式

    這篇文章主要介紹了SpringBoot讀取resource目錄下properties文件的常見方式,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • SpringBoot中默認緩存實現方案的示例代碼

    SpringBoot中默認緩存實現方案的示例代碼

    這篇文章主要介紹了SpringBoot中默認緩存實現方案,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Java?synchronized與死鎖深入探究

    Java?synchronized與死鎖深入探究

    這篇文章主要介紹了Java?synchronized與死鎖,Java中提供了synchronized關鍵字,將可能引發(fā)安全問題的代碼包裹在synchronized代碼塊中,表示這些代碼需要進行線程同步
    2023-01-01
  • java注解實現websocket服務的兩種方式

    java注解實現websocket服務的兩種方式

    Java WebSocket是一種基于TCP協(xié)議的雙向全雙工消息傳輸技術,它允許服務器和客戶端之間實時通信,具有低延遲和高效率的特點,下面這篇文章主要給大家介紹了關于java注解實現websocket服務的兩種方式,需要的朋友可以參考下
    2024-08-08
  • 關于springboot2.4跨域配置問題

    關于springboot2.4跨域配置問題

    這篇文章主要介紹了springboot2.4跨域配置的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-07-07
  • Java雙冒號(::)運算符使用詳解

    Java雙冒號(::)運算符使用詳解

    之前沒用過::這個東西,今天看flink的時候發(fā)現官網有個例子用到了這個符號,本文就詳細的來介紹一下Java雙冒號(::)運算符使用詳解,感興趣的可以了解一下
    2021-09-09
  • Spring中使用Async進行異步功能開發(fā)實戰(zhàn)示例(大文件上傳為例)

    Spring中使用Async進行異步功能開發(fā)實戰(zhàn)示例(大文件上傳為例)

    本文以大文件上傳為例,首先講解在未進行程序異步化時,程序的運行機制和具體表現,然后講解如何進行異步化的改造,讓程序進行異步執(zhí)行,通過本文不僅能讓你掌握如何進行Event的事件開發(fā),同時還能掌握在Spring中如何進行異步開發(fā),熟悉@Async的具體用法,感興趣的朋友一起看看吧
    2024-08-08
  • Java使用FFmpeg提取音頻的詳細指南

    Java使用FFmpeg提取音頻的詳細指南

    FFmpeg 是一個開源的多媒體處理工具,支持視頻、音頻的編碼、解碼、轉換等多種功能,本文將詳細講解如何使用 FFmpeg 提取音頻,包括常見的音頻格式提取、音頻質量調整、高級處理操作等,內容淺顯易懂,適合初學者快速掌握,需要的朋友可以參考下
    2024-11-11
  • Springboot jar運行時如何將jar內的文件拷貝到文件系統(tǒng)中

    Springboot jar運行時如何將jar內的文件拷貝到文件系統(tǒng)中

    因為執(zhí)行需要,需要把jar內templates文件夾下的的文件夾及文件加壓到宿主機器的某個路徑下,以便執(zhí)行對應的腳本文件,這篇文章主要介紹了Springboot jar運行時如何將jar內的文件拷貝到文件系統(tǒng)中,需要的朋友可以參考下
    2024-06-06
  • MyEclipse10安裝Log4E插件

    MyEclipse10安裝Log4E插件

    這篇文章主要介紹了MyEclipse10安裝Log4E插件的相關資料,需要的朋友可以參考下
    2017-10-10

最新評論