封装RedisUtils,静态调用超级简单。【xdxFramework】

这里做一个Reids的封装,可能相对有些复杂,但是很好用,全是静态方法直接调用,不需要每次都注入。
下面我的会详细的把过程列举出来,如果还是有问题可以联系我。


1、项目截图

在这里插入图片描述


2、代码

2-1:RedisConfig
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.lang.reflect.Method;
import java.time.Duration;

//继承CachingConfigurerSupport,为了自定义生成KEY的策略。可以不继承。
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Value("${spring.redis.jedis.pool.max-idle}")
    private Integer maxidle;

    @Value("${spring.redis.jedis.pool.min-idle}")
    private Integer minidle;

    @Value("${spring.redis.jedis.pool.max-active}")
    private Integer maxActive;

    @Value("${spring.redis.jedis.pool.min-idle}")
    private Integer maxWait;

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private Integer port;

    @Value("${spring.redis.database}")
    private Integer database;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.timeout}")
    private Integer timeout;
	/**
	 * 缓存管理器.
	 * 
	 * @param redisTemplate
	 * @return
	 */
	@Bean
	public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
		RedisCacheManager manager = RedisCacheManager.create(connectionFactory);
		return manager;
	}

	/**
	 * JedisPoolConfig 连接池
	 * 
	 * @return
	 */
	@Bean
	public JedisPoolConfig jedisPoolConfig() {
		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
		Integer maxidle = this.maxidle;
		Integer minidle = this.minidle;
		Integer maxActive = this.maxActive;
		Integer maxWait = this.maxWait;

		// 最大空闲数
		jedisPoolConfig.setMaxIdle(maxidle);
		jedisPoolConfig.setMinIdle(minidle);
		// 连接池的最大数据库连接数
		jedisPoolConfig.setMaxTotal(maxActive);
		// 最大建立连接等待时间
		jedisPoolConfig.setMaxWaitMillis(maxWait);
		// Idle时进行连接扫描
		jedisPoolConfig.setTestWhileIdle(true);
		// 表示idle object evitor两次扫描之间要sleep的毫秒数
		jedisPoolConfig.setTimeBetweenEvictionRunsMillis(30000);
		// 表示idle object evitor每次扫描的最多的对象数
		jedisPoolConfig.setNumTestsPerEvictionRun(10);
		// 表示一个对象至少停留在idle状态的最短时间,然后才能被idle object
		// evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
		jedisPoolConfig.setMinEvictableIdleTimeMillis(60000);
		// 在borrow一个jedis实例时,是否提前进行alidate操作
		jedisPoolConfig.setTestOnBorrow(true);
		// 在return给pool时,是否提前进行validate操作
		jedisPoolConfig.setTestOnReturn(true);
		return jedisPoolConfig;
	}

	@Bean
	public JedisConnectionFactory connectionFactory(JedisPoolConfig jedisPoolConfig) {
		String host = this.host;
		Integer port = this.port;
		Integer database = this.database;
		String password = this.password;
		Integer timeout = this.timeout;
		RedisStandaloneConfiguration rf = new RedisStandaloneConfiguration();
		rf.setHostName(host);
		rf.setPort(port);
		rf.setDatabase(database);
		rf.setPassword(RedisPassword.of(password));
		JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration
				.builder();
		JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpb = jedisClientConfiguration
				.usePooling();
		jedisClientConfiguration.connectTimeout(Duration.ofMillis(timeout));// connection timeout
		// 连接池
		jpb.poolConfig(jedisPoolConfig);

		JedisConnectionFactory factory = new JedisConnectionFactory(rf,
				jedisClientConfiguration.build());
		return factory;
	}

	/**
	 * 注解@Cache key生成规则
	 */
	@Bean
	@Override
	public KeyGenerator keyGenerator() {
		return new KeyGenerator() {
			@Override
			public Object generate(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();
			}
		};
	}

	// 设置数据存入 redis 的序列化方式
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Bean
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {
		// 创建一个模板类
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		// 将redis连接工厂设置到模板类中
		template.setConnectionFactory(factory);
		// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
		Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

		ObjectMapper mapper = new ObjectMapper();
		mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		serializer.setObjectMapper(mapper);
		// 开启事务
//		template.setEnableTransactionSupport(true);
		template.setValueSerializer(serializer);
		// 使用StringRedisSerializer来序列化和反序列化redis的key值
		template.setKeySerializer(new StringRedisSerializer());
		
		template.afterPropertiesSet(); 
		return template;
	}
}

2-2:CacheContext
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.concurrent.TimeUnit;

/**
 * 缓存管理工具
 * @author 小道仙
 * @date 2020年2月26日
 */
public class CacheContext<T extends CacheManager> {

	
	static CacheManager cache;

	/**
	 * 初始化方法
	 *
	 * @author 小道仙
	 * @date 2020年2月26日
	 * @version 1.0
	 */
	@SuppressWarnings("unchecked")
	public void init() {
		Type type = this.getClass().getGenericSuperclass();
		if (type instanceof ParameterizedType) {
			Class<T> entityClass;
			Type[] parameterizedType = ((ParameterizedType) type).getActualTypeArguments();
			entityClass = (Class<T>) parameterizedType[0];
			try {
				cache = entityClass.newInstance();
				cache.init();
			} catch (InstantiationException | IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 批量删除对应的value
	 * 
	 * @param keys
	 */
	public static void remove(final String... keys) {
		cache.remove(keys);
	}

	/**
	 * 删除对应的value
	 * 
	 * @param key
	 */
	public static boolean remove(final String key) {
		return cache.remove(key);
	}

	/**
	 * 判断缓存中是否有对应的value
	 * 
	 * @param key
	 * @return
	 */
	public static boolean exists(final String key) {
		return cache.exists(key);
	}

	/**
	 * 读取缓存
	 * 
	 * @param key
	 * @return
	 */
	public static Object get(final String key) {
		return cache.get(key);
	}

	/**
	 * 写入缓存
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public static boolean set(final String key, Object value) {
		return cache.set(key, value);
	}

	/**
	 * 写入缓存(可以配置过期时间-单位分钟)
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public static boolean set(final String key, Object value, long expireTime) {
		return cache.set(key, value, expireTime);
	}
	
	/**
	 * 设置缓存时间,默认单位分钟
	 * @param key
	 * @param timeout
	 * @return
	 * @author 小道仙
	 * @date 2020年2月26日
	 * @version 1.0
	 */
	public static  Boolean expire(String key, final long timeout) {
		return cache.expire(key, timeout);
	}
	
	/**
	 * 设置缓存时间
	 * @param key
	 * @param timeout
	 * @return
	 * @author 小道仙
	 * @date 2020年2月26日
	 * @version 1.0
	 */
	public static Boolean expire(String key, final long timeout, final TimeUnit unit) {
		return cache.expire(key, timeout,unit);
	} 

	/**
	 * 获取key有效期
	 * 
	 * @param key
	 * @return
	 * @author 小道仙
	 * @date 2020年2月26日
	 * @version 1.0
	 */
	public static Long getExpire(String key) {
		return cache.getExpire(key);
	}
}

2-3:CacheManager

import java.util.concurrent.TimeUnit;

public interface CacheManager {
	/**
	 * 默认过期时间,单位分钟
	 */
	 Long defaultExpirationTime =  30L;

	/**
	 * 初始化方法
	 * 
	 * @author 小道仙
	 * @date 2020年2月26日
	 * @version 1.0
	 */
	 void init();

	/**
	 * 批量删除对应的value
	 * 
	 * @param keys
	 */
	 void remove(final String... keys);

	/**
	 * 删除对应的value
	 * 
	 * @param key
	 */
	 boolean remove(final String key);

	/**
	 * 判断缓存中是否有对应的value
	 * 
	 * @param key
	 * @return
	 */
	 boolean exists(final String key);

	/**
	 * 读取缓存
	 * 
	 * @param key
	 * @return
	 */
	 Object get(final String key);

	/**
	 * 写入缓存
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	 boolean set(final String key, Object value);

	/**
	 * 写入缓存(可以配置过期时间-单位分钟)
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	 boolean set(final String key, Object value, long expireTime);

	/**
	 * 设置缓存时间,默认单位分钟
	 * 
	 * @param key
	 * @param timeout
	 * @return
     * @author 小道仙
     * @date 2020年2月26日
	 * @version 1.0
	 */
	 Boolean expire(String key, final long timeout);

	/**
	 * 设置缓存时间
	 * 
	 * @param key
	 * @param timeout
	 * @return
     * @author 小道仙
     * @date 2020年2月26日
	 * @version 1.0
	 */
	 Boolean expire(String key, final long timeout, final TimeUnit unit);

	/**
	 * 获取key有效期
	 * 
	 * @param key
	 * @return
     * @author 小道仙
     * @date 2020年2月26日
	 * @version 1.0
	 */
	 Long getExpire(String key);
}

2-4:RedisManager
import com.xdx97.framework.utils.SpringContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisManager implements CacheManager {
	private final Logger logger = LoggerFactory.getLogger(RedisManager.class);

    @Resource
	protected RedisTemplate<Serializable, Object> redisTemplate;

	@Override
	public void init() {
		@SuppressWarnings("unchecked")
        RedisTemplate<Serializable, Object> redisTemplate = (RedisTemplate<Serializable, Object>) SpringContextUtils
				.getBean("redisTemplate");
		if (redisTemplate != null && this.redisTemplate == null) {
			this.redisTemplate = redisTemplate;
		}
	}

	/**
	 * 批量删除对应的value
	 * 
	 * @param keys
	 */
	@Override
	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);
		}
	}

	/**
	 * 删除对应的value
	 * 
	 * @param key
	 */
	@Override
	public boolean remove(final String key) {
		if (exists(key)) {
			return redisTemplate.delete(key);
		}
		return true;
	}

	/**
	 * 判断缓存中是否有对应的value
	 * 
	 * @param key
	 * @return
	 */
	@Override
	public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
	}

	/**
	 * 读取缓存
	 * 
	 * @param key
	 * @return
	 */
	@Override
	public Object get(final String key) {
		if (!exists(key)) {
			return null;
		}
		Object result = null;
		ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
		result = operations.get(key);
		return result;
	}

	/**
	 * 写入缓存
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	@Override
	public boolean set(final String key, Object value) {
		Integer expire = defaultExpirationTime.intValue() ;
		return set(key, value, expire);
	}

	/**
	 * 写入缓存(可以配置过期时间-单位分钟)
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	@Override
	public boolean set(final String key, Object value, long expireTime) {
		boolean result = false;
		try {
			if (expireTime <= 0) {
				logger.warn("设置缓存时间不能小于0,key:{},value:{}", key, value);
				return result;
			}
			ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			expire(key, expireTime);
			result = true;
		} catch (Exception e) {
			logger.warn("缓存设置失败,key:{},value:{}", key, value);
		}
		return result;
	}

	@Override
	public Boolean expire(String key, final long timeout) {
		return redisTemplate.expire(key, timeout, TimeUnit.MINUTES);
	}

	@Override
	public Boolean expire(String key, final long timeout, final TimeUnit unit) {
		return redisTemplate.expire(key, timeout, unit);
	}

	/**
	 * 获取key有效期
	 * 
	 * @param key
	 * @return
     * @author 小道仙
     * @date 2020年2月26日
	 * @version 1.0
	 */
	@Override
	public Long getExpire(String key) {
		return redisTemplate.getExpire(key) == null ? 0 : redisTemplate.getExpire(key);
	}

	public void setRedisTemplate(RedisTemplate<Serializable, Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	public RedisTemplate<Serializable, Object> getRedisTemplate() {
		return redisTemplate;
	}
}
2-5:RedisUtils
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

/**
 * RedisUtils
 *
 * @DependsOn(value = "springContextUtils")
 * 作用是在这之前加载springContextUtils bean
 *
 * @author 小道仙
 * @date 2020年2月26日
 */
@Component
@DependsOn(value = "springContextUtils")
public class RedisUtils extends CacheContext<RedisManager>{
	public RedisUtils() {
		super.init();
	}
}

2-6:SpringContextUtils
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Spring Context 工具类
 * 
 * @author 小道仙
 * @date 2020年2月26日
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {

	private static ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
	}

	public static ApplicationContext getApplicationContext() {
		assertApplicationContext();
		return applicationContext;
	}

	@SuppressWarnings("unchecked")
	public static <T> T getBean(String beanName) {
		assertApplicationContext();
		return (T) applicationContext.getBean(beanName);
	}

	public static <T> T getBean(Class<T> requiredType) {
		assertApplicationContext();
		return applicationContext.getBean(requiredType);
	}

	private static void assertApplicationContext() {
		if (SpringContextUtils.applicationContext == null) {
			throw new RuntimeException("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!");
		}
	}

}

2-7: yml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-edpwGNM3-1582699118287)(https://www.xdx97.com:8185/api/preview?url=uploads/ARTICLE/root/article/2020-02-26/xdx_qXYi7XsGUzAdNIKx.png)]

    # redis配置
    redis:
        database: 0
        host: 47.100.60.252
        port: 8379
        password: fdE#84K$EW~
        timeout: 3000
        jedis:
            pool:
                max-active: 8
                max-idle: 8
                max-wait: -1
                min-idle: 0

3、使用

封装的时候有点麻烦,所以使用的时候超级简单了。

在这里插入图片描述


关注我吧,和我一起进步:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值