实现ApplicationListener
由应用程序事件侦听器实现的接口。基于Observer设计模式的标准{@code java.util.EventListener}接口。
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context;
import java.util.EventListener;
/**
* Interface to be implemented by application event listeners.
* Based on the standard {@code java.util.EventListener} interface
* for the Observer design pattern.
*
* <p>As of Spring 3.0, an ApplicationListener can generically declare the event type
* that it is interested in. When registered with a Spring ApplicationContext, events
* will be filtered accordingly, with the listener getting invoked for matching event
* objects only.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @param <E> the specific ApplicationEvent subclass to listen to
* @see org.springframework.context.event.ApplicationEventMulticaster
*/
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
ApplicationListener内置事件
原文链接:https://blog.csdn.net/liyantianmin/article/details/81017960
ContextRefreshedEvent | ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法来发生。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用 |
ContextStartedEvent | 当使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。 ——注:可能不会触发不止一次,具体原因不清楚,服务启动就绪触发可用ApplicationReadyEvent |
ApplicationReadyEvent | 可能在很晚才发布的事件,表明该应用程序已准备就绪,可以处理请求。事件的来源是{@link SpringApplication}本身,但是请注意不要修改其内部状态,因为所有初始化步骤到那时都已完成。 |
ContextStoppedEvent | 当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作 |
ContextClosedEvent | 当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。 |
RequestHandledEvent | 这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。 |
案例一:在服务启动就绪的时候加载db中的数据到redis中
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* 服务就绪时,初始化所有接入事件对应的规则
*
* @author yangning
* @date 2021/5/6 2:48 下午
**/
@Component
@Slf4j
public class ApplicationReadyInitRuleListener implements ApplicationListener<ApplicationReadyEvent> {
@Autowired
private RedisUtil redisUtil;
@Autowired
private RiskEventMapper riskEventMapper;
@Autowired
private RiskManageRuleMapper ruleMapper;
@Autowired
private RiskEventSceneAssociationMapper eventSceneAssociationMapper;
@Autowired
private RiskSceneRuleAssociationMapper sceneRuleAssociationMapper;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
List<RiskEvent> events = riskEventMapper.selectList(Wrappers.lambdaQuery());
Map<String, List<RiskRuleDTO>> eventRulesMap = new HashMap<>(12);
for (RiskEvent riskEvent : events) {
Set<String> ruleIds = new HashSet<>();
QueryWrapper<RiskEventSceneAssociation> wrapper = new QueryWrapper<>();
wrapper.eq("event_code", riskEvent.getEventCode());
// 查出事件配置的所有场景策略
List<RiskEventSceneAssociation> sceneAssociations = eventSceneAssociationMapper.selectList(wrapper);
if (CollectionUtils.isNotEmpty(sceneAssociations)) {
for (RiskEventSceneAssociation sceneAssociation : sceneAssociations) {
QueryWrapper<RiskSceneRuleAssociation> wrapper2 = new QueryWrapper<>();
wrapper2.eq("scene_id", sceneAssociation.getSceneId());
List<RiskSceneRuleAssociation> ruleAssociations = sceneRuleAssociationMapper.selectList(wrapper2);
ruleIds.addAll(ruleAssociations.stream().map(RiskSceneRuleAssociation::getRuleId).collect(Collectors.toSet()));
}
}
if (ruleIds.size() > 0) {
QueryWrapper<RiskRule> ruleWrapper = new QueryWrapper<>();
ruleWrapper.in("rule_id", ruleIds);
List<RiskRule> rules = ruleMapper.selectList(ruleWrapper);
List<RiskRuleDTO> ruleDTOList = CollectionCopyUtil.copyList(rules, RiskRuleDTO.class);
eventRulesMap.put(riskEvent.getEventCode(), ruleDTOList);
redisUtil.setObj(RedisCacheKeyConstant.getRiskEventCodeKey(riskEvent.getEventCode()), ruleDTOList, 2, TimeUnit.HOURS);
}
}
log.info("服务就绪,初始化所有接入事件和对应的规则集合:{}", JSON.toJSONString(eventRulesMap));
}
}