【Java教程】Day23-13 Spring Boot开发:集成第三方组件——访问Redis

在开发高效的Web应用时,Redis作为一种高性能的键值存储数据库,经常被用于缓存、会话存储等场景。本文将介绍如何在Spring Boot中集成Redis,通过使用Lettuce和RedisTemplate简化Redis操作,并实现基本的缓存功能。

 


1. 集成Redis的准备工作

在Spring Boot中,访问Redis非常简单。我们只需要引入spring-boot-starter-data-redis依赖,Spring Boot会自动帮我们配置相关的Redis客户端。

1.1 添加依赖

首先,在pom.xml中添加spring-boot-starter-data-redis依赖:

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

 

为了使用Lettuce作为Redis客户端,还需要添加以下依赖:

xml<dependency>    <groupId>io.lettuce.core</groupId>    <artifactId>lettuce-core</artifactId></dependency><dependency>    <groupId>org.apache.commons</groupId>    <artifactId>commons-pool2</artifactId></dependency>

 

这些依赖引入了Redis客户端Lettuce和对象池Commons Pool,用于管理Redis连接。


2. 配置Redis连接

接下来,我们需要在application.yml配置Redis连接的相关信息。以下是Redis连接的常见配置项:

yamlspring:  redis:    host: ${REDIS_HOST:localhost}    port: ${REDIS_PORT:6379}    password: ${REDIS_PASSWORD:}    ssl: ${REDIS_SSL:false}    database: ${REDIS_DATABASE:0}

 

这里配置了Redis的主机、端口、密码、是否启用SSL等信息。注意,${REDIS_HOST:localhost}是一个Spring Boot的占位符,如果环境变量中没有REDIS_HOST,则会使用默认的localhost


3. 创建Redis客户端

通过RedisConfiguration类来读取配置并创建Redis客户端。我们可以通过@ConfigurationProperties注解将配置文件中的属性自动绑定到RedisConfiguration类中。

java@ConfigurationProperties("spring.redis")public class RedisConfiguration {    private String host;    private int port;    private String password;    private int database;    // Getters and setters}

 

然后,使用@Bean方法创建RedisClient实例:

java@Beanpublic RedisClient redisClient() {    RedisURI uri = RedisURI.Builder.redis(this.host, this.port)            .withPassword(this.password)            .withDatabase(this.database)            .build();    return RedisClient.create(uri);}

 

这样,我们就完成了Redis客户端的初始化工作。


4. 使用RedisService封装Redis操作

为了方便进行Redis操作,我们创建一个RedisService类,将所有的Redis操作封装在里面,并利用Commons Pool来管理Redis连接池。

4.1 创建连接池

我们使用GenericObjectPool来缓存Redis连接,这样可以提高连接的复用性。连接池的配置如下:

java@Componentpublic class RedisService {    @Autowired    private RedisClient redisClient;        private GenericObjectPool<StatefulRedisConnection<String, String>> redisConnectionPool;    @PostConstruct    public void init() {        GenericObjectPoolConfig<StatefulRedisConnection<String, String>> poolConfig = new GenericObjectPoolConfig<>();        poolConfig.setMaxTotal(20);        poolConfig.setMaxIdle(5);        poolConfig.setTestOnReturn(true);        poolConfig.setTestWhileIdle(true);                this.redisConnectionPool = ConnectionPoolSupport.createGenericObjectPool(() -> redisClient.connect(), poolConfig);    }    @PreDestroy    public void shutdown() {        this.redisConnectionPool.close();        this.redisClient.shutdown();    }}

 

4.2 简化Redis操作

我们可以通过回调函数简化Redis操作。定义一个SyncCommandCallback接口来执行Redis命令:

java@FunctionalInterfacepublic interface SyncCommandCallback<T> {    T doInConnection(RedisCommands<String, String> commands);}

 

然后,编写executeSync方法,通过回调的方式操作Redis:

javapublic <T> T executeSync(SyncCommandCallback<T> callback) {    try (StatefulRedisConnection<String, String> connection = redisConnectionPool.borrowObject()) {        connection.setAutoFlushCommands(true);        RedisCommands<String, String> commands = connection.sync();        return callback.doInConnection(commands);    } catch (Exception e) {        logger.warn("executeSync redis failed.", e);        throw new RuntimeException(e);    }}

 

4.3 常用Redis命令封装

接下来,我们封装常用的Redis命令,例如setgethsethget等:

javapublic String set(String key, String value) {    return executeSync(commands -> commands.set(key, value));}public String get(String key) {    return executeSync(commands -> commands.get(key));}public boolean hset(String key, String field, String value) {    return executeSync(commands -> commands.hset(key, field, value));}public String hget(String key, String field) {    return executeSync(commands -> commands.hget(key, field));}public Map<String, String> hgetall(String key) {    return executeSync(commands -> commands.hgetall(key));}

 

这些封装使得访问Redis变得更加简洁易用。


5. 在Controller中使用Redis

通过RedisService,我们可以在控制器中轻松读写Redis。例如,在用户登录时,我们将用户ID存储在Session中,而用户信息存储到Redis中:

java@Controllerpublic class UserController {    public static final String KEY_USER_ID = "__userid__";    public static final String KEY_USERS = "__users__";    @Autowired     private ObjectMapper objectMapper;    @Autowired     private RedisService redisService;    private void putUserIntoRedis(User user) throws Exception {        redisService.hset(KEY_USERS, user.getId().toString(), objectMapper.writeValueAsString(user));    }    private User getUserFromRedis(HttpSession session) throws Exception {        Long id = (Long) session.getAttribute(KEY_USER_ID);        if (id != null) {            String s = redisService.hget(KEY_USERS, id.toString());            if (s != null) {                return objectMapper.readValue(s, User.class);            }        }        return null;    }    @PostMapping("/signin")    public ModelAndView doSignin(@RequestParam("email") String email, @RequestParam("password") String password, HttpSession session) throws Exception {        User user = userService.signin(email, password);        session.setAttribute(KEY_USER_ID, user.getId());        putUserIntoRedis(user);        return new ModelAndView("redirect:/profile");    }    @GetMapping("/profile")    public ModelAndView profile(HttpSession session) throws Exception {        User user = getUserFromRedis(session);        if (user == null) {            return new ModelAndView("redirect:/signin");        }        return new ModelAndView("profile.html", Map.of("user", user));    }}

 

在这里,用户登录后,我们将用户信息存储到Redis,并通过Session存储用户ID。获取用户信息时,我们从Redis中读取并返回。


6. 小结

通过本节内容,我们学习了如何在Spring Boot中集成Redis,使用Lettuce客户端并通过对象池优化连接管理。我们还通过封装Redis操作,简化了对Redis的使用,并通过RedisService来集中处理Redis相关的逻辑。

Redis在Spring Boot中的集成非常简单,但通过合理的封装,可以提高应用的可维护性和扩展性。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值