SpringBoot整合(二)redis

前言

首先确保在服务器或虚拟机中安装配置好了redis,确保服务器或虚拟机上的redis能够被远程调用。
如果没有,见:https://blog.csdn.net/weixin_45773632/article/details/123656061

SpringBoot整合redis

说明

springBoot 2.x之后,原来使用的Jedis被替换为了lettuce

  • jedis: 采用的是直连,多个线程操作的话,是不安全的,如果向要避免不安全的情况出现,使用jedis pool连接池!更像 BIO 模式

  • lettuce: 采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程开销,更像NIO模式

依赖导入

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

查看配置文件

在这里插入图片描述
找到redis相关的自动配置类:
在这里插入图片描述
跳转到RedisAutoConfiguration:
在这里插入图片描述
跳转到RedisProperties:
在这里插入图片描述

RedisAutoConfiguration 源码分析

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

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

}

整合测试

  1. 启动一个单机的redis
    注意:如果redis是安装在服务器上,需要将·bind 127.0.0.1 注释,并且将protected mode
    设置为no。参考:https://blog.csdn.net/bababuzaijia/article/details/88872754

  2. 编写配置文件

spring:
  #redis基础配置
  redis:
  	#redis的地址
    host: 127.0.0.1
    port: 6379
  1. 测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTemplateTest {
    @Resource
    private RedisTemplate redisTemplate;

    @Test
    public void contextLoads() {
        redisTemplate.opsForValue().set("testKey","xxxxxx");
        System.out.println(redisTemplate.opsForValue().get("testKey"));
    }
}

注意@RunWith(SpringRunner.class) 必加,否则报空指针,原文见https://blog.csdn.net/weixin_42236404/article/details/88969718

注意:这里mykey对应的值是英文,如果是中文的话会出现问题。需要自定义Redistemplate

注意:如果set的值是一个对象的话,则这个对象的类必须被序列化,否则就会报错。

RedisTemplate 源码分析

/**
	 * Constructs a new <code>RedisTemplate</code> instance.
	 */
	public RedisTemplate() {}

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.redis.core.RedisAccessor#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() {

		super.afterPropertiesSet();

		boolean defaultUsed = false;

		if (defaultSerializer == null) {

			defaultSerializer = new JdkSerializationRedisSerializer(
					classLoader != null ? classLoader : this.getClass().getClassLoader());
		}

		if (enableDefaultSerializer) {

			if (keySerializer == null) {
				keySerializer = defaultSerializer;
				defaultUsed = true;
			}
			if (valueSerializer == null) {
				valueSerializer = defaultSerializer;
				defaultUsed = true;
			}
			if (hashKeySerializer == null) {
				hashKeySerializer = defaultSerializer;
				defaultUsed = true;
			}
			if (hashValueSerializer == null) {
				hashValueSerializer = defaultSerializer;
				defaultUsed = true;
			}
		}

		if (enableDefaultSerializer && defaultUsed) {
			Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
		}

		if (scriptExecutor == null) {
			this.scriptExecutor = new DefaultScriptExecutor<>(this);
		}

		initialized = true;
	}
  1. RedisTemplate 中有四个值,代表不同键和值的序列化方式
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
	@SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
	@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
	@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;
  1. RedisTemplate中只有一个无参构造函数,导入依赖后,默认会向容器中注入一个RedisTemplate
  2. RedisTemplate默认使用 JdkSerializationRedisSerializer 来序列化
if (defaultSerializer == null) {

			defaultSerializer = new JdkSerializationRedisSerializer(
					classLoader != null ? classLoader : this.getClass().getClassLoader());
		}

自定义RedisTemplate

RedisConfig

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);

        //使用Jackson 提供的json序列化器
        Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jsonRedisSerializer.setObjectMapper(om);

        //String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //key采用字符串序列化
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        //value的序列化方式采用jackson
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        //该方法尽量还是调用一下
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}

测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTemplateTest {
    @Resource
    private RedisTemplate redisTemplate;

    @Test
    public void contextLoads1() {
        User user = new User();
        redisTemplate.opsForValue().set("mykey1",user);
        System.out.println(redisTemplate.opsForValue().get("mykey1"));
    }
}

拓展 (通过Jedis操作redis)

(1) 导入依赖

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.8.0</version>
        </dependency>

(2) 测试连接

public class TestPing {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("121.4.91.181", 6379);
        jedis.auth("afajy487nf34fa.sdfa");

        System.out.println(jedis.ping());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值