springboot的if else过多解决方案
在实际开发工程中,常常会遇到多个ifelse的判断语句,对于简单的项目,还能够满足需求表。但是对于需求变更频繁的项目,这样会造成代码冗余同时且不易维护,不太建议采用这种方法。下面介绍一种springboot项目的解决方式。
1 基本代码
1.1service的接口代码
public interface OrderService {String handle(OrderDTO orderDTO);
}
1.2 OrderDTO代码
public class OrderDTO {private String code;private BigDecimal price;private String type;public String getType() {return type;}public void setType(String type) {this.type = type;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public BigDecimal getPrice() {return price;}public void setPrice(BigDecimal price) {this.price = price;}
}
2两种实现方式
2.1传统方式
public String traditionalHandle(OrderDTO orderDTO){String type = orderDTO.getType();if ("1".equals(type)){return "处理普通的类型";}if ("2".equals(type)){return "处理团购的类型";}if ("2".equals(type)){return "处理促销的类型";}return "错误处理";}
2.2策略模式
@Autowiredprivate HandlerContext handlerContext;@Overridepublic String handle(OrderDTO orderDTO) {AbstractHandler handler = handlerContext.getInstance(orderDTO.getType());return handler.handler(orderDTO);}
3 策略+applicationContext容器方式
3.1实现思路
- 扫描对应的抽象类的多个实现类
- 将对应的实现类存储在hashMap容器中,并对外封装提供处理类
- 调用处理类完成业务需求
3.2代码实现
3.2.1HandlerProcessor
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;/*** @author shuxibing* @date 2019/7/31 15:03* @uint d9lab* @Description: 该类主要指将扫描的信息注入applicationContext容器中*/
@Component
public class HandlerProcessor implements BeanFactoryPostProcessor {/*** 扫描hanglerMap注解兵注入容器中* @param beanFactory* @throws BeansException*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {Map<String,Class> handlerMap=new HashMap<>(3);ClassScaner.scan(Const.HANDLER_PACAGER,HandlerType.class).forEach(clazz->{String type = clazz.getAnnotation(HandlerType.class).value();handlerMap.put(type,clazz);});HandlerContext context=new HandlerContext(handlerMap);beanFactory.registerSingleton(HandlerContext.class.getName(),context);}
}
3.2.2 AbstractHandler 和实现类
public abstract class AbstractHandler {public abstract String handler(OrderDTO orderDTO);
}
@Component
@HandlerType("1")
public class NormalHandler extends AbstractHandler {@Overridepublic String handler(OrderDTO orderDTO) {return "处理普通订单";}
}
@Component
@HandlerType("2")
public class GroupHandler extends AbstractHandler {@Overridepublic String handler(OrderDTO orderDTO) {return "处理团购的类型";}
}
@Component
@HandlerType("3")
public class PromotionHandler extends AbstractHandler {@Overridepublic String handler(OrderDTO orderDTO) {return "处理团购订单";}
}
3.2.3 注解+扫描
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface HandlerType {String value();
}
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.ClassUtils;
import org.springframework.util.SystemPropertyUtils;import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.*;/*** @author shuxibing* @date 2019/7/31 15:07* @uint d9lab* @Description:*/
public class ClassScaner implements ResourceLoaderAware {private final List<TypeFilter> includeFilters=new LinkedList<>();private final List<TypeFilter> excludeFilters=new LinkedList<>();private ResourcePatternResolver resourcePatternResolver=new PathMatchingResourcePatternResolver();private MetadataReaderFactory metadataReaderFactory=new CachingMetadataReaderFactory(this.resourcePatternResolver);public static Set<Class<?>> scan(String[] basepackages, Class<? extends Annotation>...annoations) {ClassScaner cs=new ClassScaner();//需要扫描的注解if (ArrayUtils.isNotEmpty(annoations)){for (Class anno:annoations){cs.addIncludeFilter(new AnnotationTypeFilter(anno));}}Set<Class<?>> classes=new HashSet<>();for (String s:basepackages){classes.addAll(cs.doScan(s));}return classes;}public static Set<Class<?>> scan(String basePackage,Class<? extends Annotation> ...annoations){return scan(new String[]{basePackage},annoations);}private Set<Class<?>> doScan(String basePackage) {Set<Class<?>> classes=new HashSet<>();try {String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage)) + "/**/*.class";Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);for (Resource resource : resources) {if (resource.isReadable()){MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);if ((includeFilters.size()==0&&excludeFilters.size()==0)||matches(metadataReader)){try {classes.add(Class.forName(metadataReader.getClassMetadata().getClassName()));} catch (ClassNotFoundException e) {e.printStackTrace();}}}}}catch (IOException e){throw new BeanDefinitionStoreException("IO failure during classpath scanning",e);}return classes;}protected boolean matches(MetadataReader metadataReader) throws IOException {for(TypeFilter tf:this.excludeFilters){if (tf.match(metadataReader,this.metadataReaderFactory)){return false;}}for (TypeFilter tf:this.includeFilters){if (tf.match(metadataReader,this.metadataReaderFactory))return true;}return false;}/*** 设置解析器* @param resourceLoader*/@Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {this.resourcePatternResolver= ResourcePatternUtils.getResourcePatternResolver(resourceLoader);this.metadataReaderFactory=new CachingMetadataReaderFactory(resourceLoader);}public void addIncludeFilter(TypeFilter typeFilter){this.includeFilters.add(typeFilter);}public void addExcludeFilter(TypeFilter typeFilter){this.excludeFilters.add(0,typeFilter);}public final ResourceLoader getResourceLoader(){return this.resourcePatternResolver;}public void resetResourceLoader(){this.includeFilters.clear();this.excludeFilters.clear();}
}
3.2.4 封装获取applicationContext的对象类
@Component
public class BeanTool implements ApplicationContextAware {private static ApplicationContext applicationContext;//自动初始化注入applicationContext@Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException {if (applicationContext==null){applicationContext=context;}}/**通过bean的缩写的方式获取类型** @param name* @return*/public static Object getBean(String name){return applicationContext.getBean(name);}public static <T> T getBean(Class<T> clazz){return applicationContext.getBean(clazz);}
}
3.2.5 策略模式处理类
public class HandlerContext {private Map<String,Class> handlerMap;public HandlerContext(Map<String, Class> handlerMap) {this.handlerMap = handlerMap;}public AbstractHandler getInstance(String type){Class clazz=handlerMap.get(type);if (clazz==null){throw new IllegalArgumentException("输入的参数类型有问题:"+type);}return (AbstractHandler) BeanTool.getBean(clazz);}
}
3.2.6 参数类
public class Const {public static final String HANDLER_PACAGER="com.shu.example.strategymodel";
}
springboot的if else过多解决方案相关推荐
- 详解SpringBoot应用跨域访问解决方案
详解SpringBoot应用跨域访问解决方案 参考文章: (1)详解SpringBoot应用跨域访问解决方案 (2)https://www.cnblogs.com/zimug/p/11832737.h ...
- 第一百一十期:详解SpringBoot应用跨域访问解决方案
说到跨域访问,必须先解释一个名词:同源策略.所谓同源策略就是在浏览器端出于安全考量,向服务端发起请求必须满足:协议相同.Host(ip)相同.端口相同的条件,否则访问将被禁止,该访问也就被称为跨域访问 ...
- SpringApplication:SpringBoot程序启动的一站式解决方案
我们说SpringBoot是Spring框架对"约定优先于配置(Convention Over Configuration)"理念的最佳实践的产物,一个典型的SpringBoot应 ...
- springboot返回时间有错解决方案
问题 有些人做springboot项目会遇到一个问题:前端写一个时间,然后传到后台莫名其妙的就少了一天,也就是实际存进数据库的时间比你前端写的时间少 原因和解决方案 原因一:可能你spring时区忘记 ...
- SpringBoot多数据源及事务解决方案
目录 1. 背景 2. 数据源切换原理 3. 配置文件解决方案 3.1 创建数据源 3.2 AOP处理 3.3 方案不足 4. 数据库表解决方案 4.1 设计数据源表 4.2 自定义数据源管理 4.2 ...
- SpringBoot 定时任务动态管理通用解决方案
欢迎关注方志朋的博客,回复"666"获面试宝典 一.功能说明 SpringBoot的定时任务的加强工具,实现对SpringBoot原生的定时任务进行动态管理,完全兼容原生@Sche ...
- springboot搭建文件预览解决方案,支持目前主流格式office文件,txt文件,png,jpg等图片以及压缩文件的在线预览功能
应用场景及实现思路 应用场景:给定一个网址,输入网址后立即显示预览文件. 实现思路: 1.将文件下载到本地,存储到某个指定目录 2.进行文件转换,此处是重点 3.进行文件展示 实现过程 首 ...
- Mysql sleep线程过多解决方案
一.sleep连接过多,会对mysql服务器造成什么影响? 严重消耗mysql服务器资源(主要是cpu, 内存),并可能导致mysql崩溃.https://www.cndba.cn/hbhe0316/ ...
- hive 小文件过多解决方案
目录 一.小文件产生原因 二.小文件过多产生的影响 三.怎么解决小文件过多 1. 使用 hive 自带的 concatenate 命令,自动合并小文件 2. 调整参数减少Map数量 3. 减少Redu ...
- Spring @Autowired注解在非Controller注入为null,Springboot @Reference注入为null解决方案
今天使用activiti的执行流程,使用dubbo想要去调用service,发现@Reference为null,研究了好久,尝试直接连接dao层,注入的也为null.. 可能是我的这个不是contro ...
最新文章
- centos中的mysql安装配置,Linux下安装配置MySQL
- MySQL性能优化(八)
- 【django】配置文件
- 分布式消息系统Kafka初步
- NET问答: 说说你对 LookupTKey, TElement 的看法 ?
- Java 8 Friday:不再需要ORM
- 握手失败_主人用吃的训练小柴犬握手,老柯基看到后的表现出了吃货的本能!...
- Linux下面MariaDB 管理命令基础使用
- CocoaPods 基础知识--------安装 及 使用第三方库
- 利用idea构建hibernate
- 反爬虫破解——百度翻译
- js获取某年某月某天是第几周
- Vue3动态引入图片
- dm服务器未能启动,救命啊!IDES无法启动了!!!!
- 看完李宏毅的视频我决定学好英语了
- 关于直播电商平台的一些数据
- colorkey口红怎么样_colorkey镜面唇釉怎么样 唇釉和口红有什么区别
- 曙光服务器管理系统,曙光Gridview服务器管理系统单机版v2.0用户手册.pdf
- 京东 java 待遇_【深圳京东工资】java开发工程师待遇-看准网
- Ableton Max for Live Collection ALP 音频MIDI效果合成控制设备拓展合集
热门文章
- jsp注册里密码强弱怎么弄_JavaScript注册时密码强度校验代码
- Python:内置类型
- 阿里云云计算 38 PolarDB MySQL的数据管理
- 用大数据挑选出国外最值得看的前50条swift教程(v.2019)
- 分治法实现最大子数组
- JavaWeb检测注册内容是否在数据库中有相同的内容
- 华为堡垒机_案例:任正非曾为小灵通痛苦8到10年,促进了华为终端公司诞生
- 《基 于 N Gram 的无词典 中文分词算法》 n-gram读感
- python____Django实战(1)
- spring报“Could not resolve placeholder”错误