一、连接操作redis
Spring Boot中操作redis还是需要使用相关的启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
按照之前的逻辑 我们还是要分析一下这个启动器的自动配置类RedisAutoConfiguration
做了什么
@AutoConfiguration
@ConditionalOnClass({RedisOperations.class})
// 将spring.redis开头的配置和redis进行绑定
@EnableConfigurationProperties({RedisProperties.class})
// 引入了两个redis连接客户端,Lettuce(启动器默认使用)和Jedis的连接配置类
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
// 注入redisTemplate类,认定key-value都是Object类型
@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;
}
// 注入StringRedisTemplate类,认定key-value都是String类型
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
}
分析完之后,我们就可以通过一个简单的demo,来了解Spring Boot是如何连接操作redis的
首先,我们先设置一下redis客户端的防火墙,要打开6379端口
firewall-cmd --list-port # 查看所有的开放的端口号
firewall-cmd --zone=public --add-port=6379/tcp --permanent #将6379端口加入防火墙
systemctl stop firewalld.service #停止firewall
systemctl start firewalld.service #打开firewall
如果不使用Lettuce连接redis,使用Jedis,我们还需要导入相关依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
然后在配置文件中配置相关连接参数
spring:
redis:
host: 192.168.153.128
port: 6379
client-type: jedis
jedis:
pool:
max-active: 10
# username: 用户名
# password: 密码
最后测试一下对redis的set和get操作
我们创建一个拦截器,将每次请求的访问路径当作key,访问次数当作value放入redis中
package com.decade.interceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class RedisInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 获取请求路径,把它当作key,每请求一次,这个key对应的value就自增1
final String requestURI = request.getRequestURI();
stringRedisTemplate.opsForValue().increment(requestURI);
return true;
}
}
将这个拦截器通过之前的配置类注册到容器中
我们还考虑了一下filter和interceptor的区别
package com.decade.config;
import com.decade.interceptor.LoginInterceptor;
import com.decade.interceptor.RedisInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyConfig implements WebMvcConfigurer {
/**
* filter和interceptor的功能类似,这两者的区别在哪?
* filter:它是servlet定义的原生组件,脱离了spring也可以使用
* interceptor:它是spring定义的接口,可以使用spring的自动装配等功能
*/
@Autowired
private RedisInterceptor redisInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// addPathPatterns:设置要拦截的请求,如果是/**,那么会拦截包括静态资源在内的所有请求
// excludePathPatterns:设置不被拦截的请求,这里我们放行登录页请求和静态资源
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/", "/login", "/css/**", "/images/**", "/js/**", "/fonts/**");
// 这里不能使用new来实例化,因为RedisInterceptor中使用了@Autowired注解,自己new的对象没被spring管理,所以它不会自动进行依赖注入,所以这里应该从容器中拿
registry.addInterceptor(redisInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/", "/login", "/css/**", "/images/**", "/js/**", "/fonts/**");
}
最后,在首页相关的接口中获取访问次数,并打印出来
package com.decade.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpSession;
@Controller
@Slf4j
public class IndexController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 去main页面
* @return 跳转主页面
*/
@GetMapping("/main.html")
public String mainPage(HttpSession session,Model model){
final ValueOperations opsForValue = stringRedisTemplate.opsForValue();
final Object visitTimes = opsForValue.get("/main.html");
log.info("访问首页次数为:{}", visitTimes);
return "main";
}
}
访问几次首页之后,后端打印结果如下
redis客户端查询结果如下
注意:如果出现报错如下报错
org.springframework.dao.InvalidDataAccessApiUsageException:
DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user...
这就说明,redis处于保护模式,这是默认开启的,报错信息中会提供好几种解决方式
因为博主虚拟机上的redis只有自己使用,所以选择了比较省事的一种,那就是关掉保护模式
在redis.conf中搜索protected-mode,将后面的值设置为no即可
另外,我们还需要将6379端口加入防火墙白名单(已在上方写出)
再检查bind设置,如果绑定的是本机IP,需要将那一行注掉
然后重启redis服务
如有错误,欢迎指正!!!