up:: SpringBoot电商项目商品分类模块前台的分类列表递归接口

说明:

(1) 为什么写本篇博客?:

● 在实际中,我们这个系统【普通用户】要比【管理员用户】多得多;也就是说【前台系统,被访问次数】要比【后台系统,被访问次数】多的多;

● 而且,对于这个系统来说,其目录变化的频率也并不是很频繁;

● 所以,针对前台的【分类列表(递归)】接口的查询结果,我们考虑对其加一层Redis缓存,来提高访问前台系统时,架子啊目录的效率;

(2) 有关Redis的内容,如有需要可以参考【Linux】、【Redis】专栏中的内容;

(3) 本篇博客的点:

● 如何在Spring Boot项目中,整合【Redis】和【Cache】,来实现缓存效果

(4)本篇博客的某些地方,可能存在偏差和错误的地方;后面可以修改, 有关【Spring缓存】和【Redis】的疑问,在【 待写…… 】中,作了一定程度的介绍;


一:在Spring Boot项目中,使用Redis缓存的步骤;

1.在pom.xml引入【redis依赖】,【Spring的缓存Cache依赖】;

        <!--redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--spring提供的缓存框架;与上面的redis配套使用-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

说明:

(1) 依赖说明;

(2) 一个依赖是Redis;另一个依赖是Spring Boot的Cache; 可以这样认为,redis是实际保存缓存数据的NoSQL数据库;;Cache是Spring Boot和Redis打交道的缓存组件;(存疑)

2.在application.properties配置文件中,配置redis的:端口号、密码、redis服务器的IP地址:这儿配置的作用是【项目能连接上redis服务器】;

spring.redis.host=192.***.***.**4
spring.redis.port=6380
spring.redis.password=12345

说明:

(1) 这儿我使用的就是在 【Redis】的【Linux下安装Redis】中创建的Centos-Redis那台虚拟机上的redis;

(2) 我当时把redis的密码设为了12345;

3.在程序启动类【MallApplication】上,使用【@EnableCaching】注解:打开Spring的缓存功能;

说明:

(1) 我们想要用Spring提供的Cache缓存功能,就需要在启动类上使用【@EnableCaching】注解;即,我们使用了这个注解后,Spring就会知道,我们希望打开缓存功能;

(2) 个人理解:使用了【@EnableCaching】注解后,就表示:【我们这个Spring项目的Cache缓存功能开启了】,换句话说就意味着【这个Spring项目已经准备好,利用Redis这个NoSQL,来实现缓存功能,达到缓存效果了】;

4.在【我们希望使用缓存的方法上,使用【@Cacheable(value = ”**”)】注解:缓存该方法的返回值;

说明:

(1) @Cacheable(value=“listCategoryForCustomer”),这个注释的意思是,当调用这个方法的时候,会从一个名叫 listCategoryForCustomer的缓存中查询,如果没有,则执行实际的方法(即查询数据库),并将执行的结果存入缓存中,否则返回缓存中的对象。

(2) 说明;

(3) 个人理解:使用了【@Cacheable】注解后,就表示:【Spring把这个方法返回的结果,添加到缓存中】;而后续,Spring的缓存,实际上会存放在Redis这个NoSQL数据库中;

5.创建配置类,去配置redis:这儿配置的作用是配置一个Redis的缓存管理器;(这个类需要使用【@EnableCaching】注解;这个类的主要作用是:帮助【Spring的Cache缓存】去和【Redis】打交道;)

CachingConfig类:

 
     package com.imooc.mall.config;
 
     import org.springframework.cache.annotation.EnableCaching;
     import org.springframework.context.annotation.Bean;
     import org.springframework.context.annotation.Configuration;
     import org.springframework.data.redis.cache.RedisCacheConfiguration;
     import org.springframework.data.redis.cache.RedisCacheManager;
     import org.springframework.data.redis.cache.RedisCacheWriter;
     import org.springframework.data.redis.connection.RedisConnectionFactory;
 
     import java.time.Duration;
 
     /**
      * 描述:缓存的配置类
      */
     @Configuration
     @EnableCaching
     public class CachingConfig {
 
         @Bean
         public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
             RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
             RedisCacheConfiguration cacheConfiguration =  RedisCacheConfiguration.defaultCacheConfig();
             cacheConfiguration =  cacheConfiguration.entryTtl(Duration.ofSeconds(30));
 
	             RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter,  cacheConfiguration);
             return redisCacheManager;
         }
 
     }

说明:

(1.1) 【@Configuration】注解,最近的两次使用,是在本专栏的配置Swagger的时候【SpringBoot电商项目商品分类模块使用Swagger自动生成API文档】和【SpringBoot电商项目商品分类模块统一校验管理员身份】;是使用【@Configuration注解】,来指明当前类是一个配置类;

(1.2) 第一次介绍【@Configuration注解】和【@Bean注解】是在【JavaConfig-对象实例化】;如有需要,可以先去快速参考这篇博客内容;

(1.3) 主要内容就是:

● @Configuration:这个注解,放在配置类上; 即,如果一个类使用了@Configuration注解,说明这个类就是个Java Config的配置类,这个配置类的作用就是完全替代xml文件;

● @Bean:这个注解用在方法上,那么这个方法返回的对象将被IoC容器管理,同时这个bean的bean Id默认为方法名;

(2.1) 内容说明:这儿的配置内容,基本是固定的,以后我们需要配置redis的时候,直接过来copy就行了;(当然不排除根据当下的个性需求,修改配置)

(2.2) 配置内容说明;

6.启动项目,测试;

(1)一个以前讲过的坑:一个对象要想能在网路中传入,其类要实现Serializable接口;

看下报错信息:

 
     org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is
 org.springframework.core.serializer.support.SerializationFailedException:
 Failed to serialize object using DefaultSerializer; nested exception is
 java.io.NotSerializableException: com.imooc.mall.model.vo.CategoryVO
 

通过分析报错信息可以知道,原因是:

所以,我们让CategoryVO类实现Serializable接口;

网络传输问题查看对象序列化,这里面提到过

(2)重启程序,再次访问接口;

(3)一个小例子:帮助感受缓存是切实存在的;

因为,我们上面设置了缓存的有效时间是30秒;那么我们在方法这儿打一个断点;很显然,如果缓存失效的话,其会去执行方法内容,访问数据库,去拿数据;如果缓存没有失效的话,其就直接从缓存中拿数据了,而不会去执行方法内容了;

在上次调用接口后,我们等30秒后,再访问接口;

那么,我们放行断点,让其能顺利执行;(其实,这次执行成功后,获取的数据会保存到缓存中,但有效期只有30秒)

7.Summary;

以后,我们就可以把常用的接口,或者访问量大的接口,通过Spring Boot整合Redis和Cache,来实现缓存效果;这可以大大提升运行速度;