观察者+策略模式实现应用解耦、代码无侵入

应用场景

最近有个导入需求,系统导入的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));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值