拓展Spring实现监听器
实现非常简单, 只需要定义一个类实现 ApplicationListener 接口, 并指明泛型(监听的事件类型), 重写里面的 onApplicationEvent方法,只有触发当前事件类型就会执行里面的方法,然后交给 Spring IOC 容器进行管理.
使用场景:
/**
* 此处的应用场景, 在维护老项目的时候加入了 redis 对数据进行缓存处理, 由于项目所有的数据都存储在 MySQL 中,
* 所以需要将数据库中的数据迁移到 redis 缓存中进行存储, 那么什么时候迁移数据呢, 在服务启动的时候就同步数据,
* 那么怎么在 spring 容器启动的时候触发数据同步呢, 学过前端的小伙伴立马就想到了时间监听器, 不错! 我们后端的小伙伴
* 也说 java web 不是有三大组件之一的 Listener 监听器吗, 确实, 但是此处是通过实现 Spring 的 ApplicationContentListenr
* 拓展监听器的接口, 来完成容器已启动就立马触发数据同步.
*/
Spring 提供了以下5种标准的事件:
- 上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
- 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件
- 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
- 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
- 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。
如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。
定义监听器,实现接口:ApplicationListener
/**
* 攻略文章统计初始化监听器
* 在 spring 容器自动成功后执行
* 负责将 MySQL 中的数据初始化到 Redis 中
*/
@Component
public class StrategyStatDataInitListener implements ApplicationListener<ContextRefreshedEvent> {
public static final Logger log = LoggerFactory.getLogger("StrategyStatDataInitListener");
@Autowired
private IStrategyService strategyService;
@Autowired
private IRedisService<KeyPrefix, Object> redisService;
//当spring容器启动/初始化完成之后马上执行
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
log.info("--------------------文章统计初始化开始--------------------");
int count = 0;
// 1. 查询所有的文章
List<Strategy> strategyList = strategyService.list();
for (Strategy strategy : strategyList) {
// 2. 遍历所有的文章, 是否在 redis 中存在
Boolean exists = redisService.exists(ArticleRedisPrefix.STRATEGIES_STAT_PREFIX, String.valueOf(strategy.getId()));
if (! exists) {
// 3. 如果不存在, 将其存入 redis, 如果存在则不更新
Map<String, Object> map = new HashMap<>();
map.put(ArticleStatVo.FAVOR_NUM, strategy.getFavornum());
map.put(ArticleStatVo.REPLY_NUM, strategy.getReplynum());
map.put(ArticleStatVo.SHARE_NUM, strategy.getSharenum());
map.put(ArticleStatVo.THUMBSUP_NUM, strategy.getThumbsupnum());
map.put(ArticleStatVo.VIEW_NUM, strategy.getViewnum());
// 一次性的将整个 map put 到 redis 的 hash 中
redisService.hputAll(ArticleRedisPrefix.STRATEGIES_STAT_PREFIX, map, String.valueOf(strategy.getId()));
count++;
}
}
log.info("--------------------文章初始化完成, 初始化数量: {}--------------------", count);
}
}
``