应用场景
最近有个导入需求,系统导入的Excel数据存入表时,用户手填的信息导入到表里时要将每个值对应的ID也关联起来(用户当然不会手填值对应的ID),以及导入文件的其他信息要更新到其他相关表中等一系列处理,所以此时就可以使用以下元素来实现这个需求
● 一个发布事件
● 一个Handler接口
● 一个@Handler注解
● 一个HandlerContext管理所有的Handler(使用@Handler注解)
● 一个监听器
● n个Handler
实现元素
事件HandlerEvent
import org.springframework.context.ApplicationEvent;
import java.util.Date;
public class HandlerEvent extends ApplicationEvent {
public HandlerEvent(Object source) {
super(source);
}
public HandlerEvent() {
super(new Date());
}
}
Handler接口
public interface HandlerInterface {
void subsequentProcessing(CaseInfo caseInfo);
}
HandlerContext
@Component
public class HandlerContext{
@Autowired
public ApplicationContext applicationContext;
private final List<HandlerInterface> handlerInterfaces = new ArrayList<>();
@PostConstruct
public void init(){
if(applicationContext.getParent()==null){
Map<String,Object> beans = applicationContext.getBeansWithAnnotation(Handler.class);
for (Object bean:beans.values()){
addHandler((HandlerInterface) bean);
}
handlerInterfaces.sort(Comparator.comparingInt(p -> p.getClass().getAnnotation(Handler.class).order()));
}
}
public void addHandler(HandlerInterface handlerInterface){
handlerInterfaces.add(handlerInterface);
}
public void transform(List<CaseInfo> caseInfoList){
for(CaseInfo caseInfo : caseInfoList){
for(int i=0;i<handlerInterfaces.size();i++){
handlerInterfaces.get(i).subsequentProcessing(caseInfo);
}
caseInfo.setIsHandled("1");
}
}
}
监听器
@Component
public class HandlerListener{
@Autowired
private HandlerContext handlerContext;
@Autowired
private CaseInfoService caseInfoService;
// @Async
@EventListener
@Order(8)
public void onApplicationEvent(HandlerEvent handlerEvent) {
List<CaseInfo> files = (List<CaseInfo>) handlerEvent.getSource();
handlerContext.transform(files);
for(CaseInfo file:files){
caseInfoService.updateById(file);
}
}
}
xxHandler
@Handler(order = 6)
public class XXHandler implements HandlerInterface {
@Autowired
private XXService xxService;
@Override
public void subsequentProcessing(CaseInfo caseInfo) {
QueryWrapper<XX> queryWrapper = new QueryWrapper();
queryWrapper.eq("unit_code",caseInfo.getUnitK());
queryWrapper.eq("position_id",caseInfo.getPositionId());
xxService.getBaseMapper().delete(queryWrapper);
}
}
最终调用
导入数据完成后,调用发布事件方法
@Autowired
private ApplicationContext applicationContext;
public void import(MultipartFile file) {
// 导入逻辑
// ...
applicationContext.publishEvent(new HandlerEvent(caseInfoList));
}