成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

SpringBoot整合Redis的完整步驟

前言

實際 開發(fā) 中 緩存 處理是必須的,不可能我們每次客戶端去請求一次 服務(wù)器 ,服務(wù)器每次都要去 數(shù)據(jù)庫 中進(jìn)行查找,為什么要使用緩存?說到底是為了提高系統(tǒng)的運行速度。將用戶頻繁訪問的內(nèi)容存放在離用戶最近,訪問速度最 快的 地方,提高用戶的響 應(yīng)速度,今天先來講下在 springboot 中整合 redis 的詳細(xì)步驟。

創(chuàng)新互聯(lián)公司是一家業(yè)務(wù)范圍包括IDC托管業(yè)務(wù),虛擬主機、主機租用、主機托管,四川、重慶、廣東電信服務(wù)器租用,服務(wù)器托管,成都網(wǎng)通服務(wù)器托管,成都服務(wù)器租用,業(yè)務(wù)范圍遍及中國大陸、港澳臺以及歐美等多個國家及地區(qū)的互聯(lián)網(wǎng)數(shù)據(jù)服務(wù)公司。

一、Spring Boot對Redis的支持

Spring對Redis的支持是使用Spring Data Redis來實現(xiàn)的,一般使用Jedis或者lettuce(默認(rèn)),Java客戶端在 org.springframework.boot.autoconfigure.data.redis(Spring Boot 2.x) 中redis的自動配置 AutoConfigureDataRedis

Spring Boot整合Redis的完整步驟 

RedisAutoConfiguration提供了RedisTemplate與StringRedisTemplate(只針對鍵值都是字符型的數(shù)據(jù))模板,其中注解 @ConditionalOnMissingBean 是關(guān)鍵,表明該Bean如果在Spring中已經(jīng)存在,則忽略,如果沒有存在則在此處注冊由Spring管理,也就是說我們可以“重寫”該bean,實現(xiàn)自己的RedisTemplate與StringRedisTemplate,事實上,是要需要重寫的,理由如下:

  • 沒有實現(xiàn)我們所需要的序列化;
  • 泛型總是<Object, Object>,大部分場景我們更需要<String, Object>。
@Bean
 @ConditionalOnMissingBean(
  name = {"redisTemplate"}
 )
 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
  RedisTemplate<Object, Object> template = new RedisTemplate();
  template.setConnectionFactory(redisConnectionFactory);
  return template;
 }

 @Bean
 @ConditionalOnMissingBean
 public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
  StringRedisTemplate template = new StringRedisTemplate();
  template.setConnectionFactory(redisConnectionFactory);
  return template;
 }

二、實戰(zhàn)

1、添加依賴

1)需要spring-boot-starter-cache依賴,管理緩存

<!-- Spring Boot Cache -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2)需要spring-boot-starter-data-redis依賴(注:spring boot 2.x改為在data下),支持redis:主要以為Jedis客戶端為主,排除默認(rèn)的lettuce作為客戶端的依賴

<!-- Redis Cache -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
  <!-- 排除lettuce包,使用jedis代替-->
  <exclusions>
    <exclusion>
      <groupId>io.lettuce</groupId>
      <artifactId>lettuce-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>

3)需要jedis-client依賴(注:Redis Client 3版本以上會報錯與spring-boot-starter-data-redis沖突,最好使用2.9.x),使用jedis作為客戶端

<!-- Redis Client 3版本以上會報錯與spring-boot-starter-data-redis沖突 -->
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.9.0</version>
</dependency>

2、redis配置

創(chuàng)建RedisConfig配置類,增加@Configuration注解,同時開啟緩存管理支持(添加注解@EnableCaching),繼承CachingConfigurerSupport重寫key生成策略

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
   /**
   * 生成key的策略:根據(jù)類名+方法名+所有參數(shù)的值生成唯一的一個key
   * @return
   */
  @Bean
  @Override
  public KeyGenerator keyGenerator() {
    return (Object target, Method method, Object... params) -> {
      StringBuilder sb = new StringBuilder();
      sb.append(target.getClass().getName());
      sb.append(method.getName());
      for (Object obj : params) {
        sb.append(obj.toString());
      }
      return sb.toString();
    };
  }

}

之后使用的application.yml配置文件,其中這里已經(jīng)選擇jedis作為客戶端。

# redis 配置
 redis:
   port: 6379
   # Redis服務(wù)器連接密碼(默認(rèn)為空)
   password:
   host: xxx.xxx.xxx.xxx
   database: 0
   jedis:
    pool:
     #連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
     max-active: 300
     # 連接池中的最小空閑連接
     max-idle: 100
      # 連接池最大阻塞等待時間(使用負(fù)值表示沒有限制)
     max-wait: 10000
     # 連接超時時間(毫秒)
     timeout: 5000

同時讀取配置屬性,注入JedisPoolConfig

/**
   * redis配置屬性讀取
   */
  @Value("${spring.redis.host}")
  private String host;
  @Value("${spring.redis.port}")
  private int port;
  @Value("${spring.redis.database}")
  private int database;
  @Value("${spring.redis.jedis.pool.max-idle}")
  private int maxIdle;
  @Value("${spring.redis.jedis.pool.max-wait}")
  private long maxWaitMillis;
  @Value("${spring.redis.jedis.pool.max-active}")
  private int maxActive;


  /**
   * JedisPoolConfig配置
   * @return
   */
  @Bean
  public JedisPoolConfig jedisPoolConfig() {
    log.info("初始化JedisPoolConfig");
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxTotal(maxActive);
    jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
    jedisPoolConfig.setMaxIdle(maxIdle);
    return jedisPoolConfig;
  }

3、實現(xiàn)序列化

針對RedisTemplate或StringRedisTemplate進(jìn)行序列化,同時重寫注冊Bean

RedisTemplate默認(rèn)使用JdkSerializationRedisSerializer,StringRedisTmeplate默認(rèn)使用的是StringRedisSerializer。但都是不符合實際要求的

/**
   * 重新實現(xiàn)RedisTemplate:解決序列化問題
   * @param redisConnectionFactory
   * @return
   */
  @Bean
  @SuppressWarnings({"rawtype", "unchecked"})
  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
    RedisTemplate<String, Object> template = new RedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    ObjectMapper om = new ObjectMapper();
    // 設(shè)置任何字段可見
    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    // 設(shè)置不是final的屬性可以轉(zhuǎn)換
    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    log.info("objectMapper: {}", om);
    jackson2JsonRedisSerializer.setObjectMapper(om);
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    // key采用String的序列化方式
    template.setKeySerializer(stringRedisSerializer);
    // hash的key采用String的序列化方式
    template.setHashKeySerializer(stringRedisSerializer);
    // value序列化方式采用jackson序列化方式
    template.setValueSerializer(jackson2JsonRedisSerializer);
    // hash的value序列化方式采用jackson序列化方式
    template.setHashValueSerializer(jackson2JsonRedisSerializer);
    template.afterPropertiesSet();
    template.setEnableTransactionSupport(true);
    return template;
  }

  /**
   * 重新實現(xiàn)StringRedisTmeplate:鍵值都是String的的數(shù)據(jù)
   * @param redisConnectionFactory
   * @return
   */
  @Bean
  public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
    StringRedisTemplate template = new StringRedisTemplate();
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    template.setConnectionFactory(redisConnectionFactory);
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    // key采用String的序列化方式
    template.setKeySerializer(stringRedisSerializer);
    // hash的key采用String的序列化方式
    template.setHashKeySerializer(stringRedisSerializer);
    // value序列化方式采用jackson序列化方式
    template.setValueSerializer(jackson2JsonRedisSerializer);
    // hash的value序列化方式采用jackson序列化方式
    template.setHashValueSerializer(jackson2JsonRedisSerializer);
    return template;
  }

4、創(chuàng)建Redis連接工廠,同時注冊Bean

注意Spring Boot 1.x與Spring Boot 2.x的區(qū)別,已在代碼中注釋表明,Spring Boot 1.x使用的是JedisConnectionFactory 。而Spring Boot 2.x使用的是RedisStandaloneConfiguration ,之后傳入JedisConnectionFactory返回Bean

/**
   * 注入RedisConnectionFactory
   * @return
   */
  @Bean
  public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
    log.info("初始化JedisConnectionFactory");
    /* 在Spring Boot 1.x中已經(jīng)過時,采用RedisStandaloneConfiguration配置
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
    jedisConnectionFactory.setHostName(host);
    jedisConnectionFactory.setDatabase(database);*/

    // JedisConnectionFactory配置hsot、database、password等參數(shù)
    RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
    redisStandaloneConfiguration.setHostName(host);
    redisStandaloneConfiguration.setPort(port);
    redisStandaloneConfiguration.setDatabase(database);
    // JedisConnectionFactory配置jedisPoolConfig
    JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jedisPoolConfigBuilder =
        (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder();
    jedisPoolConfigBuilder.poolConfig(jedisPoolConfig);
    return new JedisConnectionFactory(redisStandaloneConfiguration);

  }

5、完整的RedisConfig配置類

/**
 *
 * @author jian
 * @date 2019/4/14
 * @description
 * 1) RedisTemplate(或StringRedisTemplate)雖然已經(jīng)自動配置,但是不靈活(第一沒有序列化,第二泛型為<Object, Object>不是我們想要的類型)
 * 所以自己實現(xiàn)RedisTemplate或StringRedisTemplate)
 * 2) 采用RedisCacheManager作為緩存管理器
 *
 */

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

  private static final Logger log = LoggerFactory.getLogger(RedisConfig.class);

  /**
   * redis配置屬性讀取
   */
  @Value("${spring.redis.host}")
  private String host;
  @Value("${spring.redis.port}")
  private int port;
  @Value("${spring.redis.database}")
  private int database;
  @Value("${spring.redis.jedis.pool.max-idle}")
  private int maxIdle;
  @Value("${spring.redis.jedis.pool.max-wait}")
  private long maxWaitMillis;
  @Value("${spring.redis.jedis.pool.max-active}")
  private int maxActive;


  /**
   * JedisPoolConfig配置
   * @return
   */
  @Bean
  public JedisPoolConfig jedisPoolConfig() {
    log.info("初始化JedisPoolConfig");
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxTotal(maxActive);
    jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
    jedisPoolConfig.setMaxIdle(maxIdle);
    return jedisPoolConfig;
  }

  /**
   * 注入RedisConnectionFactory
   * @return
   */
  @Bean
  public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
    log.info("初始化JedisConnectionFactory");
    /* 在Spring Boot 1.x中已經(jīng)過時,采用RedisStandaloneConfiguration配置
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
    jedisConnectionFactory.setHostName(host);
    jedisConnectionFactory.setDatabase(database);*/

    // JedisConnectionFactory配置hsot、database、password等參數(shù)
    RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
    redisStandaloneConfiguration.setHostName(host);
    redisStandaloneConfiguration.setPort(port);
    redisStandaloneConfiguration.setDatabase(database);
    // JedisConnectionFactory配置jedisPoolConfig
    JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jedisPoolConfigBuilder =
        (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder();
    jedisPoolConfigBuilder.poolConfig(jedisPoolConfig);
    return new JedisConnectionFactory(redisStandaloneConfiguration);

  }

  /**
   * 采用RedisCacheManager作為緩存管理器
   * @param connectionFactory
   */
  @Bean
  public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
    RedisCacheManager redisCacheManager = RedisCacheManager.create(connectionFactory);
    return redisCacheManager;
  }


  /**
   * 生成key的策略:根據(jù)類名+方法名+所有參數(shù)的值生成唯一的一個key
   * @return
   */
  @Bean
  @Override
  public KeyGenerator keyGenerator() {
    return (Object target, Method method, Object... params) -> {
      StringBuilder sb = new StringBuilder();
      sb.append(target.getClass().getName());
      sb.append(method.getName());
      for (Object obj : params) {
        sb.append(obj.toString());
      }
      return sb.toString();
    };
  }

  /**
   * 重新實現(xiàn)RedisTemplate:解決序列化問題
   * @param redisConnectionFactory
   * @return
   */
  @Bean
  @SuppressWarnings({"rawtype", "unchecked"})
  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
    RedisTemplate<String, Object> template = new RedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    ObjectMapper om = new ObjectMapper();
    // 設(shè)置任何字段可見
    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    // 設(shè)置不是final的屬性可以轉(zhuǎn)換
    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    log.info("objectMapper: {}", om);
    jackson2JsonRedisSerializer.setObjectMapper(om);
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    // key采用String的序列化方式
    template.setKeySerializer(stringRedisSerializer);
    // hash的key采用String的序列化方式
    template.setHashKeySerializer(stringRedisSerializer);
    // value序列化方式采用jackson序列化方式
    template.setValueSerializer(jackson2JsonRedisSerializer);
    // hash的value序列化方式采用jackson序列化方式
    template.setHashValueSerializer(jackson2JsonRedisSerializer);
    template.afterPropertiesSet();
    template.setEnableTransactionSupport(true);
    return template;
  }

  /**
   * 重新實現(xiàn)StringRedisTmeplate:鍵值都是String的的數(shù)據(jù)
   * @param redisConnectionFactory
   * @return
   */
  @Bean
  public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
    StringRedisTemplate template = new StringRedisTemplate();
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    template.setConnectionFactory(redisConnectionFactory);
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    // key采用String的序列化方式
    template.setKeySerializer(stringRedisSerializer);
    // hash的key采用String的序列化方式
    template.setHashKeySerializer(stringRedisSerializer);
    // value序列化方式采用jackson序列化方式
    template.setValueSerializer(jackson2JsonRedisSerializer);
    // hash的value序列化方式采用jackson序列化方式
    template.setHashValueSerializer(jackson2JsonRedisSerializer);
    return template;
  }

}

三、測試

1、編寫redis工具類

雖然RedisTemplate與StringRedisTemplate模板有提供的主要數(shù)據(jù)訪問方法:

  • opsForValue():操作只有簡單屬性的數(shù)據(jù)
  • opsForList():操作含有List的數(shù)據(jù)
  • opsForSet():操作含有set的數(shù)據(jù)
  • opsForHash():操作含有hash的數(shù)據(jù)
  • opsForZSet():操作含有有序set類型ZSet的數(shù)據(jù)

但是相關(guān)比較抽象,實現(xiàn)起來比較復(fù)雜,有必要進(jìn)一步封裝,比如使用redisTmeplate中的簡單value的get操作:

Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);

但是封裝之后,相對客戶端用戶來說比較明了

/**
   * 讀取緩存
   *
   * @param key
   * @return
   */
  public Object get(final String key) {
    Object result = null;
    ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
    result = operations.get(key);
    return result;
  }

完整的簡單工具類如下:

@Component
public class RedisUtils {


  @Autowired
  private RedisTemplate redisTemplate;

  /**
   * 批量刪除對應(yīng)的value
   *
   * @param keys
   */
  public void remove(final String... keys) {
    for (String key : keys) {
      remove(key);
    }
  }

  /**
   * 批量刪除key
   *
   * @param pattern
   */
  public void removePattern(final String pattern) {
    Set<Serializable> keys = redisTemplate.keys(pattern);
    if (keys.size() > 0) {
      redisTemplate.delete(keys);
    }
  }

  /**
   * 刪除對應(yīng)的value
   *
   * @param key
   */
  public void remove(final String key) {
    if (exists(key)) {
      redisTemplate.delete(key);
    }
  }

  /**
   * 判斷緩存中是否有對應(yīng)的value
   *
   * @param key
   * @return
   */
  public boolean exists(final String key) {
    return redisTemplate.hasKey(key);
  }

  /**
   * 讀取緩存
   *
   * @param key
   * @return
   */
  public Object get(final String key) {
    Object result = null;
    ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
    result = operations.get(key);
    return result;
  }

  /**
   * 寫入緩存
   *
   * @param key
   * @param value
   * @return
   */
  public boolean set(final String key, Object value) {
    boolean result = false;
    try {
      ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
      operations.set(key, value);
      result = true;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }

  /**
   * 寫入緩存
   *
   * @param key
   * @param value
   * @return
   */
  public boolean set(final String key, Object value, Long 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;
  }
}

2、Person實體類

需要注意的是一定要實現(xiàn)序列化,并且有序列化版本ID

public class Person implements Serializable {
  private final long serialVersionUID = 1L;

  private String id;
  private String name;
  private int age;
  private String gender;

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public String getGender() {
    return gender;
  }

  public void setGender(String gender) {
    this.gender = gender;
  }

  @Override
  public String toString() {
    return "Person{" +
        "id='" + id + '\'' +
        ", name='" + name + '\'' +
        ", age=" + age +
        ", gender='" + gender + '\'' +
        '}';
  }
}

3、編寫測試類

Redis工具類Spring已經(jīng)做了管理(增加@Compent注解),使用很簡單,只需要注入RedisUtils即可

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

  @Autowired
  private RedisUtils redisUtils;

  @Test
  public void test(){
    Person person = new Person();
    person.setAge(23);
    person.setId("001");
    person.setName("Zhangsan");
    redisUtils.set("person-001", person);
    System.out.println(redisUtils.get("person-001"));
  }

}

4、測試結(jié)果

在IDE控制臺中:

Spring Boot整合Redis的完整步驟 

在登錄客戶端后查看value值

 Spring Boot整合Redis的完整步驟

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對創(chuàng)新互聯(lián)的支持。

網(wǎng)站標(biāo)題:SpringBoot整合Redis的完整步驟
標(biāo)題URL:http://jinyejixie.com/article14/psipde.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計、網(wǎng)站維護(hù)、動態(tài)網(wǎng)站、ChatGPT網(wǎng)站策劃、網(wǎng)站導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
高陵县| 两当县| 靖边县| 台湾省| 会泽县| 巴楚县| 精河县| 镇雄县| 田东县| 元朗区| 沈阳市| 深水埗区| 大安市| 中牟县| 宝应县| 西宁市| 久治县| 北流市| 赤城县| 丰顺县| 和田县| 温州市| 凤庆县| 景谷| 漳平市| 雷山县| 桦甸市| 宜丰县| 英吉沙县| 肇东市| 遂平县| 全州县| 神木县| 长顺县| 博湖县| 天津市| 洪泽县| 卢湾区| 阿拉善左旗| 会东县| 神农架林区|