1.项目中注入SpringBeanUtils
springBoot理念就是约定大于配置,其实经常写代码我们经常看到if else代码,今天介绍一种约定大于配置的方法减少if else。首先项目中要拿到Spring的ApplicationContext ,方便我们后面获取容器中的Bean
public class SpringBeanContextUtil implements ApplicationContextAware{
/** */
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
if (SpringBeanContextUtil.applicationContext == null) {
SpringBeanContextUtil.applicationContext = applicationContext;
}
}
/**
* @return xx
*/
public static ApplicationContext getApplicationContext() {
return SpringBeanContextUtil.applicationContext;
}
/**
* @param name xx
* @return xx
*/
public static Object getBean(final String name) {
Object obj = null;
try {
obj = getApplicationContext().getBean(name);
} catch (BeansException e) {
return obj;
}
return obj;
}
/**
* @param <T> xx
* @param clazz xx
* @return xx
*/
public static <T> T getBean(final Class<T> clazz) {
T obj = null;
try {
obj = getApplicationContext().getBean(clazz);
} catch (BeansException e) {
return obj;
}
return obj;
}
/**
* @param <T> xx
* @param name xx
* @param clazz xx
* @return xx
*/
public static <T> T getBean(final String name, final Class<T> clazz) {
T obj = null;
try {
obj = getApplicationContext().getBean(name, clazz);
} catch (BeansException e) {
return obj;
}
return obj;
}
}
2.示例代码
if (SaleOrderStatusEnum.WAITING_PAY.getCode()==orderInfo.getOrderStatus()){
// 处理待支付逻辑
}else if(SaleOrderStatusEnum.WAITING_DELIVERY.getCode()==orderInfo.getOrderStatus()){
// 处理待发货逻辑
}else if(SaleOrderStatusEnum.WAITING_AUDIT.getCode()==orderInfo.getOrderStatus()){
// 处理审核逻辑
}
上面代码大概就是根据订单状态处理业务逻辑,尤其很多判断的时候需要写很多if else;
3. 改造代码
- 现在我们发现每种状态都需要判断之后,然后处理逻辑,我们需要将这些逻辑抽象为一个接口
public interface OrderStatusDealService {
// 事件处理服务
void executeBusinessByOrderStatus(OrderInfo orderInfo)
}
- 实现上面的接口,将上面的if else中的内容抽象成一个一个组件,相当于策略模式中的具体策略
// 处理待支付服务
@Slf4j
@Service("OrderStatusService_"+"WaitPay")
public class WaitPayOrderService implements OrderStatusDealService {
@Override
public void executeBusinessByOrderStatus(OrderInfo orderInfo){
//处理待支付逻辑
}
}
// 处理待发货服务
@Slf4j
@Service("OrderStatusService_"+"WaitDelivery")
public class WaitDeliveryOrderService implements OrderStatusDealService {
@Override
public void executeBusinessByOrderStatus(OrderInfo orderInfo){
//处理待发货逻辑
}
}
注意@Service对组件的命名,其中WaitDelivery,WaitPay为上面if中判断的状态,其实就是订单的状态(实际中可能是数字,可以做一层转换或者可以利用前缀+状态命名好各个组件)
4.如何使用这些业务组件
在业务代码中直接根据订单状态获取Spring容器中对应的Bean进行处理业务处理
// 业务使用地方,直接根据订单状态获取容器中对应的处理类
public void dealBusiness(OrderInfo orderInfo){
OrderStatusDealService orderStatusDealService = SpringBeanContextUtil.getBean("OrderStatusService_" + orderInfo.getOrderStatus(), OrderStatusDealService.class);
// 处理业务
orderStatusDealService.executeBusinessByOrderStatus(OrderInfo orderInfo);
}
好处:
- 比如传入了订单状态是WaitPay,那么获取到的组件是OrderStatusService_WaitPay。这样就拿到我们的待支付处理组件。避免写了大量的if else,
- 后面我们开发另外一种订单状态处理业务直接根据约定的(配置好名称名称)去开发,而不要去维护if else判断,这里业务组件相当于策略模式中的具体策略,尤其是当我们有大量状态判断之后再去处理业务逻辑的时候。约定好我们的Bean名称以某种自定义规则命名。
- 代码结构更清晰
5.总结
- 约定大于配置,约定我们所有的bean的名字是前缀+订单状态,获取的时候根据订单状态拼接获取Bean处理业务。
- 注入到组件到Spring管理,实现ApplicationContextAware拿到applicationContext,然后业务需要使用的时候直接根据名称获取组件。
- 如果是数字的订单状态,我们可以转换为字符串或者利用枚举映射好组件的名称,总之就是约定大于配置(这里约定我们各个状态的组件按照OrderStatusService_加上状态名称)。后续开发状态组件不需要维护if else,只专注开发对应的状态组件