|
|
|
@ -8,50 +8,174 @@
|
|
|
|
|
* 版权所有,侵权必究!
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// 该类所属的包名,表明其位于商城项目的通用(common)配置(config)包下,主要用于对Redis缓存相关的配置进行定义和设置,通过Spring的配置类机制,
|
|
|
|
|
// 在满足一定条件(配置文件中spring.cache.type = redis时)生效,来实现Redis缓存在项目中的集成与定制化配置。
|
|
|
|
|
package com.yami.shop.common.config;
|
|
|
|
|
|
|
|
|
|
import com.yami.shop.common.bean.AliDaYu;
|
|
|
|
|
import com.yami.shop.common.bean.ImgUpload;
|
|
|
|
|
import com.yami.shop.common.bean.Qiniu;
|
|
|
|
|
import lombok.Data;
|
|
|
|
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
|
|
|
import org.springframework.context.annotation.PropertySource;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
|
|
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
|
|
|
import com.fasterxml.jackson.databind.MapperFeature;
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
|
|
|
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
|
|
|
|
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
|
|
|
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|
|
|
|
import org.springframework.cache.CacheManager;
|
|
|
|
|
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 org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
|
|
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
|
|
|
|
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
|
|
|
|
import org.springframework.data.redis.serializer.RedisSerializer;
|
|
|
|
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
|
|
|
|
|
|
|
|
|
import java.time.Duration;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 该类作为商城配置文件相关的实体类,用于绑定配置文件中的各项配置信息到对应的属性上,方便在整个项目中获取和使用商城相关的配置参数,
|
|
|
|
|
* 通过使用 Spring 的相关注解(@Component、@ConfigurationProperties、@PropertySource),可以将配置文件中的配置值自动注入到这些属性中,
|
|
|
|
|
* 使得项目中的不同模块能够方便地获取如七牛云配置、阿里大鱼短信平台配置、加解密 token 的密钥以及本地文件上传配置等信息,实现配置的统一管理和灵活使用。
|
|
|
|
|
* RedisCacheConfig类是一个Spring的配置类,用于配置Redis缓存相关的各种组件和行为,使得项目能够基于Redis实现高效的缓存功能,并且可以根据实际需求进行灵活的定制化配置。
|
|
|
|
|
* 只有当项目的配置文件中指定spring.cache.type = redis时,这里定义的Redis缓存相关配置才会生效,用于控制缓存的存储、序列化、过期时间等关键特性。
|
|
|
|
|
*
|
|
|
|
|
* @author lgh
|
|
|
|
|
*/
|
|
|
|
|
@Data
|
|
|
|
|
@Component
|
|
|
|
|
@PropertySource("classpath:shop.properties")
|
|
|
|
|
@ConfigurationProperties(prefix = "shop")
|
|
|
|
|
public class ShopBasicConfig {
|
|
|
|
|
@EnableCaching
|
|
|
|
|
// 使用@EnableCaching注解开启Spring的缓存功能,使得在项目中可以使用诸如@Cacheable、@CachePut、@CacheEvict等缓存相关的注解来方便地操作缓存,提高应用性能。
|
|
|
|
|
@Configuration
|
|
|
|
|
// 使用@Configuration注解表明该类是一个配置类,Spring会扫描这个类,并根据其中定义的@Bean方法来创建相应的Bean实例,注入到Spring容器中供其他组件使用。
|
|
|
|
|
public class RedisCacheConfig {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建并配置CacheManager的Bean方法,CacheManager是Spring缓存抽象的核心接口,用于管理缓存,在这里具体配置了基于Redis的缓存管理方式。
|
|
|
|
|
* 通过传入RedisConnectionFactory(用于创建与Redis服务器的连接)和RedisSerializer(用于对缓存数据进行序列化和反序列化操作),
|
|
|
|
|
* 构建了一个RedisCacheManager实例,该实例负责管理Redis缓存的各种配置和行为,如缓存的默认过期时间、特定缓存键的过期时间配置等。
|
|
|
|
|
*
|
|
|
|
|
* @param redisConnectionFactory 用于创建与Redis服务器连接的工厂类实例,通过它可以获取到与Redis服务器通信的连接对象,是操作Redis缓存的基础依赖。
|
|
|
|
|
* @param redisSerializer 用于对缓存中存储的对象进行序列化和反序列化的序列化器,确保对象能够正确地在Java内存和Redis存储之间进行转换,保证数据的一致性和可存储性。
|
|
|
|
|
* @return 返回配置好的RedisCacheManager实例,用于管理项目中的Redis缓存,将其注入到Spring容器中,以便其他组件可以获取并使用该缓存管理器来操作缓存。
|
|
|
|
|
*/
|
|
|
|
|
@Bean
|
|
|
|
|
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, RedisSerializer<Object> redisSerializer) {
|
|
|
|
|
|
|
|
|
|
RedisCacheManager redisCacheManager = new RedisCacheManager(
|
|
|
|
|
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
|
|
|
|
|
// 默认策略,未配置的 key 会使用这个
|
|
|
|
|
this.getRedisCacheConfigurationWithTtl(3600, redisSerializer),
|
|
|
|
|
// 指定 key 策略
|
|
|
|
|
this.getRedisCacheConfigurationMap(redisSerializer)
|
|
|
|
|
);
|
|
|
|
|
redisCacheManager.setTransactionAware(true);
|
|
|
|
|
return redisCacheManager;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用于获取特定缓存键对应的Redis缓存配置映射(Map)的私有方法,通过创建一个HashMap实例,并向其中添加特定缓存键(这里是"product")与对应的Redis缓存配置信息,
|
|
|
|
|
* 使得可以针对不同的缓存键设置不同的缓存过期时间等配置,方便根据业务需求对不同类型的数据缓存进行精细化管理。
|
|
|
|
|
*
|
|
|
|
|
* @param redisSerializer 用于对缓存数据进行序列化和反序列化操作的序列化器,确保缓存配置中涉及的数据能够正确地进行序列化处理,与整体的缓存数据格式保持一致。
|
|
|
|
|
* @return 返回包含特定缓存键与对应Redis缓存配置信息的Map,用于在创建RedisCacheManager时设置指定键的缓存策略,以便根据不同的缓存键应用不同的缓存过期时间等规则。
|
|
|
|
|
*/
|
|
|
|
|
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap(RedisSerializer<Object> redisSerializer) {
|
|
|
|
|
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(16);
|
|
|
|
|
redisCacheConfigurationMap.put("product", this.getRedisCacheConfigurationWithTtl(1800, redisSerializer));
|
|
|
|
|
return redisCacheConfigurationMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用于存储七牛云的配置信息的属性,七牛云可能用于文件存储、图片上传等功能,其配置信息包含诸如访问密钥、存储区域等内容,
|
|
|
|
|
* 通过此属性可以在项目中方便地获取七牛云相关配置,以便与七牛云服务进行集成,实现文件上传、管理等操作。
|
|
|
|
|
* 用于获取带有指定过期时间(TTL,Time To Live)的Redis缓存配置的私有方法,通过以默认的Redis缓存配置(RedisCacheConfiguration.defaultCacheConfig())为基础,
|
|
|
|
|
* 使用传入的序列化器(redisSerializer)来配置缓存值的序列化方式,并设置缓存条目的过期时间(通过Duration.ofSeconds(seconds)指定秒数),从而生成符合特定需求的Redis缓存配置信息。
|
|
|
|
|
*
|
|
|
|
|
* @param seconds 缓存条目的过期时间,以秒为单位,用于控制缓存数据在Redis中存储的有效时长,超过这个时间后,缓存数据将被自动清除,以保证缓存数据的时效性和内存空间的合理利用。
|
|
|
|
|
* @param redisSerializer 用于对缓存中存储的对象进行序列化和反序列化的序列化器,确保缓存数据能够按照指定的格式进行转换,以便正确地存储在Redis中以及从Redis中读取还原。
|
|
|
|
|
* @return 返回配置好的带有指定过期时间的Redis缓存配置信息,用于在创建RedisCacheManager或者设置特定缓存键的配置时使用,来定义缓存的具体行为,如数据的序列化和过期策略等。
|
|
|
|
|
*/
|
|
|
|
|
private Qiniu qiniu;
|
|
|
|
|
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds, RedisSerializer<Object> redisSerializer) {
|
|
|
|
|
|
|
|
|
|
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
|
|
|
|
|
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
|
|
|
|
|
RedisSerializationContext
|
|
|
|
|
.SerializationPair
|
|
|
|
|
.fromSerializer(redisSerializer)
|
|
|
|
|
).entryTtl(Duration.ofSeconds(seconds));
|
|
|
|
|
|
|
|
|
|
return redisCacheConfiguration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用于存储阿里大鱼短信平台相关配置信息的属性,阿里大鱼短信平台可用于向用户发送短信通知、验证码等功能,
|
|
|
|
|
* 其配置信息包含访问密钥 ID、访问密钥秘密、短信签名等内容,通过该属性能够获取相应配置,进而调用阿里大鱼的短信服务接口来发送短信。
|
|
|
|
|
* 创建并配置RedisTemplate的Bean方法,RedisTemplate是Spring Data Redis提供的用于操作Redis的核心模板类,
|
|
|
|
|
* 它封装了与Redis进行交互的常见操作方法,如设置键值对、获取值、操作哈希等数据结构,在这里对其进行了详细的配置,包括设置连接工厂、键和值的序列化器等,
|
|
|
|
|
* 使得可以方便地在项目中使用该模板类来操作Redis缓存,实现数据的读写等功能。
|
|
|
|
|
*
|
|
|
|
|
* @param redisConnectionFactory 用于创建与Redis服务器连接的工厂类实例,为RedisTemplate提供与Redis服务器通信的连接,是操作Redis的基础依赖,确保能够正确地访问Redis服务器。
|
|
|
|
|
* @param redisSerializer 用于对缓存中存储的对象进行序列化和反序列化的序列化器,用于配置RedisTemplate中值的序列化方式,保证存入Redis的数据和从Redis读取还原的数据格式正确,与整体缓存数据的序列化策略保持一致。
|
|
|
|
|
* @return 返回配置好的RedisTemplate实例,注入到Spring容器中,方便其他组件获取并使用它来进行与Redis缓存相关的各种操作,如向缓存中存入数据、从缓存中获取数据等操作。
|
|
|
|
|
*/
|
|
|
|
|
private AliDaYu aLiDaYu;
|
|
|
|
|
@Bean
|
|
|
|
|
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory, RedisSerializer<Object> redisSerializer) {
|
|
|
|
|
|
|
|
|
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
|
|
|
|
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
|
|
|
|
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
|
|
|
|
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
|
|
|
|
redisTemplate.setValueSerializer(redisSerializer);
|
|
|
|
|
redisTemplate.setHashValueSerializer(redisSerializer);
|
|
|
|
|
redisTemplate.setEnableTransactionSupport(false);
|
|
|
|
|
|
|
|
|
|
redisTemplate.afterPropertiesSet();
|
|
|
|
|
return redisTemplate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 自定义Redis序列化机制的Bean方法,通过创建一个自定义配置的ObjectMapper实例,对Jackson的序列化和反序列化相关特性进行了一系列配置,
|
|
|
|
|
* 目的是为了避免与Spring MVC中默认的ObjectMapper配置产生冲突,同时满足项目中对Redis缓存数据序列化的特定需求,例如对日期时间类型的序列化处理、处理未知属性、空对象以及无效子类型等情况的处理方式,
|
|
|
|
|
* 最后基于这个自定义的ObjectMapper创建并返回一个GenericJackson2JsonRedisSerializer实例,用于在Redis缓存中对对象进行序列化和反序列化操作。
|
|
|
|
|
*
|
|
|
|
|
* @return 返回配置好的GenericJackson2JsonRedisSerializer实例,作为Redis缓存的序列化器,注入到Spring容器中,供其他与Redis缓存相关的组件(如RedisCacheManager、RedisTemplate等)使用,
|
|
|
|
|
* 确保缓存数据能够按照预期的方式进行序列化和反序列化,保证数据的正确存储和读取。
|
|
|
|
|
*/
|
|
|
|
|
/**
|
|
|
|
|
* 用于存储加解密 token 的密钥信息的属性,在涉及用户认证、授权等场景中,token 常用于传递用户身份信息,
|
|
|
|
|
* 为了保证 token 的安全性,可能会使用此密钥进行加密和解密操作,该属性保存的密钥值会在相关的加密解密逻辑中被使用。
|
|
|
|
|
* 自定义redis序列化的机制,重新定义一个ObjectMapper.防止和MVC的冲突
|
|
|
|
|
* https://juejin.im/post/5e869d426fb9a03c6148c97e
|
|
|
|
|
*/
|
|
|
|
|
private String tokenAesKey;
|
|
|
|
|
@Bean
|
|
|
|
|
public RedisSerializer<Object> redisSerializer() {
|
|
|
|
|
ObjectMapper objectMapper = JsonMapper.builder().disable(MapperFeature.USE_ANNOTATIONS).build();
|
|
|
|
|
// 反序列化时候遇到不匹配的属性并不抛出异常,这样即使缓存数据中存在一些在当前类中没有定义的属性,也能正常进行反序列化操作,提高了兼容性和容错性。
|
|
|
|
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
|
|
|
// 序列化时候遇到空对象不抛出异常,避免因为缓存数据中存在空对象而导致序列化失败的情况,使得空对象也能按照预期进行序列化处理。
|
|
|
|
|
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
|
|
|
|
// 反序列化的时候如果是无效子类型,不抛出异常,在处理复杂的继承结构或者类型变化时,即使遇到不符合预期的子类型情况,也能继续进行反序列化,增强了反序列化的稳定性。
|
|
|
|
|
objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
|
|
|
|
|
// 不使用默认的dateTime进行序列化,避免在处理日期时间类型数据时出现格式不符合项目需求的情况,方便按照项目自定义的方式对日期时间进行序列化。
|
|
|
|
|
objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
|
|
|
|
|
// 使用JSR310提供的序列化类,里面包含了大量的JDK8时间序列化类,利用Java 8中对日期时间API的优化,更规范、准确地对日期时间类型数据进行序列化和反序列化操作。
|
|
|
|
|
objectMapper.registerModule(new JavaTimeModule());
|
|
|
|
|
// 启用反序列化所需的类型信息,在属性中添加@class,通过这种方式在反序列化时可以明确数据的类型信息,有助于正确还原对象类型,尤其是在处理多态类型数据时非常重要。
|
|
|
|
|
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
|
|
|
|
|
JsonTypeInfo.As.PROPERTY);
|
|
|
|
|
// 配置null值的序列化器,确保在缓存数据中存在null值时也能正确地进行序列化和反序列化操作,保证数据的完整性和一致性。
|
|
|
|
|
GenericJackson2JsonRedisSerializer.registerNullValueSerializer(objectMapper, null);
|
|
|
|
|
return new GenericJackson2JsonRedisSerializer(objectMapper);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用于存储本地文件上传配置信息的属性,本地文件上传配置可能涉及到文件存储路径、文件大小限制、允许的文件类型等相关参数,
|
|
|
|
|
* 通过这个属性可以获取相应配置,从而在进行本地文件上传功能实现时,按照配置要求来处理文件上传的各种逻辑,确保文件上传操作符合业务需求。
|
|
|
|
|
* 创建并配置StringRedisTemplate的Bean方法,StringRedisTemplate是Spring Data Redis提供的专门用于操作Redis中字符串类型数据的模板类,
|
|
|
|
|
* 相比于RedisTemplate,它更专注于对字符串类型的操作,在这里对其进行了简单配置,设置了禁止事务支持,并返回配置好的实例注入到Spring容器中,方便在项目中对Redis中的字符串数据进行操作,
|
|
|
|
|
* 例如存储简单的字符串键值对、执行字符串相关的命令等操作。
|
|
|
|
|
*
|
|
|
|
|
* @param redisConnectionFactory 用于创建与Redis服务器连接的工厂类实例,为StringRedisTemplate提供与Redis服务器通信的连接,确保能够正确地访问Redis服务器进行字符串数据的操作。
|
|
|
|
|
* @return 返回配置好的StringRedisTemplate实例,注入到Spring容器中,供其他组件获取并使用它来进行与Redis中字符串类型数据相关的各种操作,方便在项目中处理简单的字符串缓存数据等情况。
|
|
|
|
|
*/
|
|
|
|
|
private ImgUpload imgUpload;
|
|
|
|
|
@Bean
|
|
|
|
|
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
|
|
|
|
StringRedisTemplate redisTemplate = new StringRedisTemplate(redisConnectionFactory);
|
|
|
|
|
redisTemplate.setEnableTransactionSupport(false);
|
|
|
|
|
return redisTemplate;
|
|
|
|
|
}
|
|
|
|
|
}
|