Spring Boot中 监听和处理事件(积分操作)

137 篇文章 0 订阅
85 篇文章 0 订阅

Spring Boot提供了一套强大的事件发布和监听机制,允许不同部分的应用程序相互通信。本文将在Spring Boot应用程序中使用事件监听和处理,通过一个用户活动跟踪系统的案例,展示事件驱动架构在现代应用程序中的应用。

肖哥弹架构 跟大家“弹弹” Spring Boot,需要代码关注

欢迎 点赞,点赞,点赞。

关注公号Solomon肖哥弹架构获取更多精彩内容

历史热点文章

场景:

用户活动跟踪系统需要记录用户的关键行为,并在用户执行特定操作时触发相应的处理逻辑,如积分更新、日志记录或发送通知。

使用技术点:

  1. 事件发布:在Spring Boot中发布自定义事件。
  2. 事件监听:使用@EventListener注解监听事件。
  3. 应用程序事件:Spring的ApplicationEvent类及其子类。

工作流程图:

在这里插入图片描述

代码:

创建自定义事件:
    import org.springframework.context.ApplicationEvent;

    public class UserActivityEvent extends ApplicationEvent {
        private String userId;
        private String activity;

        public UserActivityEvent(Object source, String userId, String activity) {
            super(source);
            this.userId = userId;
            this.activity = activity;
        }

        public String getUserId() {
            return userId;
        }

        public String getActivity() {
            return activity;
        }
    }
发布事件:
    import org.springframework.stereotype.Component;

    @Component
    public class EventPublisher {

        private final ApplicationEventPublisher publisher;

        @Autowired
        public EventPublisher(ApplicationEventPublisher publisher) {
            this.publisher = publisher;
        }

        public void publishUserActivityEvent(String userId, String activity) {
            publisher.publishEvent(new UserActivityEvent(this, userId, activity));
        }
    }

业务逻辑服务类(UserService)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    private final EventPublisher eventPublisher;
    private final UserPonitRepository userPointRepository; // 假设积分仓库

    @Autowired
    public UserService(EventPublisher eventPublisher, UserPonitRepository userPointRepository) {
        this.eventPublisher = eventPublisher;
        this.userPointRepository = userPointRepository;
    }

    // 检查用户状态并更新积分
    public void checkUserStatusAndUpdatePoints(String userId, String activity) {
        // 假设这里有逻辑来检查用户状态
        boolean isActive = isUserActive(userId);

        if (isActive) {
            // 用户活跃,更新积分
            updatePoints(userId, activity);
            
            // 发布用户活动事件
            eventPublisher.publishUserActivityEvent(userId, activity);
        } else {
            // 用户不活跃,处理不活跃逻辑
        }
    }

    private boolean isUserActive(String userId) {
        // 这里应该有检查用户状态的逻辑
        return true; // 假设总是返回活跃状态
    }

    private void updatePoints(String userId, String activity) {
        // 这里应该有更新用户积分的逻辑
        // 根据用户行为来增加积分
        int pointsToAdd = calculatePointsForActivity(activity);
        User user = userPointRepository.findById(userId).orElseThrow();
        user.addPoints(pointsToAdd);
        userPointRepository.save(user);
    }

    private int calculatePointsForActivity(String activity) {
        // 根据活动类型返回不同的积分数
        return 10; // 假设每种活动增加10积分
    }
}
监听事件:
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.event.EventListener;
    import org.springframework.stereotype.Component;

    @Component
    public class UserActivityListener {

        private final UserService userService;

        @Autowired
        public UserActivityListener(UserService userService) {
            this.userService = userService;
        }

        @EventListener
        public void handleUserActivityEvent(UserActivityEvent event) {
            String userId = event.getUserId();
            String activity = event.getActivity();

            // 委托UserService来处理用户活动
            userService.checkUserStatusAndUpdatePoints(userId, activity);
        }
    }
触发事件:
    @RestController
    public class UserController {

        @Autowired
        private UserService userService;

        @PostMapping("/user/performActivity")
        public String userPerformActivity(@RequestParam String userId, @RequestParam String activity) {
            // 委托UserService来检查用户状态并更新积分
            userService.checkUserStatusAndUpdatePoints(userId, activity);

            return "User activity processed";
        }
    }

启动类(Application)

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

结论:

Spring Boot的事件发布和监听机制为构建响应式和可扩展的应用程序提供了一种有效的方式。通过使用事件,应用程序的不同部分可以以松耦合的方式进行通信,使得系统更加灵活和易于维护。在用户活动跟踪系统中,事件监听和处理机制可以有效地记录和响应用户的关键行为,从而提供个性化的用户体验和业务逻辑。

Spring Boot 使用 Redis 监听删除事件,可以结合使用 RedisTemplate 和 Spring Data Redis 提供的监听器(EventListener),具体实现步骤如下: 1. 创建一个 RedisTemplate 对象,用于操作 Redis 数据库: ```java @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.afterPropertiesSet(); return template; } } ``` 2. 创建一个 RedisKeyExpirationListener 类,实现 RedisKeyExpiredEvent 事件的处理方法: ```java @Component public class RedisKeyExpirationListener implements ApplicationListener<RedisKeyExpiredEvent> { @Override public void onApplicationEvent(RedisKeyExpiredEvent event) { String key = event.getSource().toString(); System.out.println("Key expired: " + key); } } ``` 3. 在 RedisTemplate 对象上注册监听器: ```java @Configuration public class RedisConfig { @Autowired private RedisKeyExpirationListener redisKeyExpirationListener; @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.afterPropertiesSet(); // 注册监听器 template.setEnableTransactionSupport(true); template.getConnectionFactory().getConnection().subscribe(new MessageListenerAdapter(redisKeyExpirationListener)); return template; } } ``` 在这个例子,我们使用 RedisKeyExpiredEvent 事件监听 Redis 的键过期事件。当 Redis 的键过期时,会触发 RedisKeyExpiredEvent 事件,事件源是被删除的键名。在 RedisKeyExpirationListener ,我们实现 onApplicationEvent 方法,打印出被删除的键名。 在 RedisTemplate 注册监听器的过程,我们使用了 MessageListenerAdapter 类将 RedisKeyExpirationListener 转化为 MessageListener 对象,然后订阅 Redis 的键事件频道。当 Redis 有键事件发生时,MessageListenerAdapter 会将事件转发给 RedisKeyExpirationListener 处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Solomon_肖哥弹架构

你的欣赏就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值