背景
-
最近有个特别紧急的需求,今天开发明天就要演示,而且还是16点开的需求会,听说涉及过亿的金额(mmp,分我嘛),抱怨归抱怨,工作还是要保质保量完成的.
需求内容
-
之前已经开发了一套新版的基础信息,包含了学校信息,年级信息,班级信息,学生信息等13个分类,现在想在教育局做一个统计页面,统计汇总教育局下面学校相关的信息,涉及web端和平台端,一句话就是今天晚上要通宵,明天上午要演示(听完心态都崩了,f**k!).
需求分解
-
考虑到紧急性,什么好不好扩展好不好维护基本上都不用想的了,将13个分类按功能相近分成4个模块,也就是4张表,大大减少了建表的时间.
-
因为请求和传参的基本上一致,对外就提供一个接口,使用策略模式和统一接口实现
-
表里的数据,不可能去写相关的逻辑实现,要写相关的逻辑,没有半个月搞不定,还能怎么办,手动填充,到时候页面上展示对不上就要看产品的应急能力或者让他绕开.
接口实现
- 关于策略模式和spring的整合我之前写过,感兴趣的同学可以去看一下
- 接口
public interface IBaseStatisticalService {
StatisticalRespDTO query(StatisticalReqDTO dto);
}
复制代码
- controller
@PostMapping("/query")
@Description("查找对应的统计")
public ResultRespDto query(@RequestBody StatisticalReqDTO dto) {
return Rets.success(this.handler.query(dto));
}
复制代码
- 策略模式调用(核心)
```
@Autowired
private Map<String, IBaseStatisticalService> baseStatisticalServiceMap ;
public StatisticalRespDTO query(StatisticalReqDTO dto) {
logger.info("BaseStatisticalHandler.query,dto:{}",dto);
if (Objects.isNull(dto)){
ExceptionEnum.throwException(ExceptionEnum.FAILED,"参数为空");
}
String key = BaseStatisticalConstance.BASE_STATISTICAL + dto.getType();
IBaseStatisticalService baseStatisticalService = baseStatisticalServiceMap.get(key);
if (Objects.isNull(baseStatisticalService)){
ExceptionEnum.throwException(ExceptionEnum.FAILED,"对应类型不存在");
}
return baseStatisticalService.query(dto);
}
复制代码
- 相关的分类只要实现接口去实现自己的业务,这样既能统一管理又能更好的扩展.就当我为自己洋洋得意的时候,其他同事说有问题,我们现在是按4张表来开发的,也就是4个service类要包含13中类型,而我设计的这个,是根据beanName来进行策略的,而spring默认只有一个beanName,就是相当要有13个类才行,这样的开发很恶心(难搞啊!),没有后退可言!
- 现在就是要扩展spring原有的beanName让其支持一个bean多个name,查了一会发现spring提供自带的是不支持的,只能自己写,停下笔,想了好一会,突然灵光一现.
- 定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface BaseTypeMapping {
String[] types() default {};
}
复制代码
- 实现类使用
@Service
@BaseTypeMapping(types = {BaseStatisticalConstance.CLASS,BaseStatisticalConstance.GRADE,BaseStatisticalConstance.DEPARTMENT})
public class BaseStatisticalGroupServiceImpl extends ServiceImpl<BaseStatisticalGroupMapper, BaseStatisticalGroup>
implements BaseStatisticalGroupService , IBaseStatisticalService {
@Autowired
private BaseStatisticalGroupMapper baseStatisticalGroupMapper;
@Override
public StatisticalRespDTO query(StatisticalReqDTO dto) {
//业务代码
}
}
复制代码
- 实现ApplicationContextAware,完整代码如下
@Component
public class BaseStatisticalHandler implements ApplicationContextAware {
private final static Logger logger = LoggerFactory.getLogger(BaseStatisticalHandler.class);
private Map<String, IBaseStatisticalService> baseStatisticalServiceMap = new ConcurrentHashMap<>();
public StatisticalRespDTO query(StatisticalReqDTO dto) {
logger.info("BaseStatisticalHandler.query,dto:{}",dto);
if (Objects.isNull(dto)){
ExceptionEnum.throwException(ExceptionEnum.FAILED,"参数为空");
}
String key = BaseStatisticalConstance.BASE_STATISTICAL + dto.getType();
IBaseStatisticalService baseStatisticalService = baseStatisticalServiceMap.get(key);
if (Objects.isNull(baseStatisticalService)){
ExceptionEnum.throwException(ExceptionEnum.FAILED,"对应类型不存在");
}
return baseStatisticalService.query(dto);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, IBaseStatisticalService> map = applicationContext.getBeansOfType(IBaseStatisticalService.class);
for (Map.Entry<String, IBaseStatisticalService> entry : map.entrySet()) {
IBaseStatisticalService value = entry.getValue();
String key = entry.getKey();
logger.info("{}:{}:{}", key, value.getClass(), value.getClass().isAnnotationPresent(BaseTypeMapping.class));
BaseTypeMapping annotation = value.getClass().getAnnotation(BaseTypeMapping.class);
if (annotation == null) {
continue;
}
String[] types = annotation.types();
for (String type : types) {
logger.info("types:{},beanName:{},class:{}", types, key, value);
String basetKey = BaseStatisticalConstance.BASE_STATISTICAL+ type;
if (baseStatisticalServiceMap.containsKey(key)) {
//类已经存在
IBaseStatisticalService baseStatisticalService = baseStatisticalServiceMap.get(key);
logger.error("IBaseStatisticalService,type:{},beanName:{},class:{} 已经被定义", type, key, baseStatisticalService);
throw new BeanCurrentlyInCreationException(key);
}
baseStatisticalServiceMap.put(basetKey, value);
}
}
}
}
复制代码
自己本地试了一下,木有问题,开心!推广给同事,按这一套标准来实现,在联调的过程中也没发现问题,敲开心!
近期评论