springboot,策略模式-注解实例管理、统一异常处理、参数校验, 参数化IOC

 DisposableBean

DisposableBean是一个接口,为Spring bean提供了一种释放资源的方式 ,只有一个扩展方法destroy()
实现DisposableBean接口,并重写destroy(),可以在Spring容器销毁bean的时候获得一次回调
destroy()的回调执行时机是Spring容器关闭,需要销毁所有的bean时

 

@RestControllerAdvice 统一异常处理

统一异常处理、参数校验
    @PostMapping(value = "/my")
//    @ResponseBody
    public ResultVo myRequest(@RequestBody @Validated MyRequest myRequest){
        log.info("******myRequest********:"+myRequest);
        if(true){
            throw new BusinessException(101,"测试异常xxx");
        }
        return new ResultVo(200,"success");
    }
    //表单方式提交
    @PostMapping(value = "/my2")
    @ResponseBody
    public ResultVo myRequest2( MyRequest myRequest){
        log.info("******myRequest********:"+myRequest);
        return new ResultVo(200,"success");
    }

@Data
public class MyRequest {
    @NotBlank(message = "姓名不能为空")
    private String name;
    private int age;
}

	<!-- 参数校验 -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.7.16</version>
        </dependency>

@Slf4j
@RestControllerAdvice("com.xmh.action")
public class GlobalExceptionHandler {
    /**
     * 表单提交时 参数转换异常
     * 对方法参数校验异常处理方法
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(BindException.class)
    public ResultVo handlerNotValidException(BindException exception) {
        log.error("handlerNotValidException",exception);
        BindingResult result = exception.getBindingResult();
        Map<String, Object> maps;
        if (result.hasErrors()) {
            List<FieldError> fieldErrors = result.getFieldErrors();
            maps = new HashMap<>(fieldErrors.size());
            fieldErrors.forEach(error -> {
                maps.put(error.getField(), error.getDefaultMessage());
            });
            return new ResultVo(10,fieldErrors.get(0).getField()+":"+fieldErrors.get(0).getDefaultMessage());
        } else {
            maps = Collections.EMPTY_MAP;
        }
        log.info("resolve argument exception end,result:{}", maps);
        return new ResultVo(9,"9message");
//        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(maps);
    }
    /**
     * 自定义参数错误异常处理器
     * @param e 自定义参数
     * @return ResponseInfo
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({BusinessException.class})
    public ResultVo paramExceptionHandler(BusinessException e) {
        log.error("BusinessException", e);
        // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
        if (!StringUtils.isEmpty(e.getMessage())) {
            return new ResultVo(6, e.getMessage());
        }
        return new ResultVo(7,"7error");
    }
    /**
     * 参数缺失校验
     * @param e 忽略参数异常
     * @return ResponseResult
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ResultVo parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
        log.error("MissingServletRequestParameterException", e);
        return new ResultVo(2, "请求参数 " + e.getParameterName() + " 不能为空");
    }
    /**
     * 缺少请求体异常处理器
     * @param e 缺少请求体异常
     * @return ResponseResult
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResultVo parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
        log.error("HttpMessageNotReadableException", e);
        return new ResultVo(3, "参数体不能为空");
    }
    /**
     * 参数效验异常处理器
     * @param e 参数验证异常
     * @return ResponseInfo
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultVo parameterExceptionHandler(MethodArgumentNotValidException e) {
        log.error("MethodArgumentNotValidException**", e);
        // 获取异常信息
        BindingResult exceptions = e.getBindingResult();
        // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
        if (exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
                // 这里列出了全部错误参数,按正常逻辑,只需要第一条错误即可
                FieldError fieldError = (FieldError) errors.get(0);
                return new ResultVo(4, fieldError.getDefaultMessage());
            }
        }
        return new ResultVo(5,"5error");
    }

@Data
public class BusinessException extends RuntimeException {
    private String message;
    private Integer code;
    public BusinessException(Integer code,String message) {
        this.message = message;
        this.code = code;
    }

@Data
public class ResultVo<T>  implements Serializable {
    private static final long serialVersionUID = -6217026000953354515L;
    private int code;
    private String message;
    private T data;
    public ResultVo(int code, String message) {
        this.code = code;
        this.message = message;
    }
}
      

 

@Service
@ConditionalOnProperty(prefix = "desp.message", name = "role", havingValue = "master")  //按参数加载
desp:
  message:
   role: master

 至简方案 

@RequestMapping(value = "/query", method = RequestMethod.GET)
public Object order() {
businessManage.doBusiness(StrategyEnum.STRATEGY_ONE);
return "订单查询成功";
}

@Component
public class BusinessManage {
    private static Map<StrategyEnum, IBusinessService> businessMap = new HashMap<>();
    @Autowired
    public void init(List<IBusinessService> businessServices) {
        businessServices.forEach(businessService -> {
            // 注册策略
            businessMap.put(businessService.getStrategy(), businessService);
        });
    }
    public void doBusiness(StrategyEnum strategy) {
        // 策略模式
        businessMap.get(strategy).doBusiness();
    }
}

public interface IBusinessService {
    void doBusiness();
    StrategyEnum getStrategy();
}
@Service
public class BusinessTwoServiceImpl implements IBusinessService {
    @Override
    public void doBusiness() {
        System.out.println("执行业务2");
    }
    @Override
    public StrategyEnum getStrategy() {
        return StrategyEnum.STRATEGY_TWO;
    }
}

@Service
public class BusinessOneServiceImpl implements IBusinessService {
    @Override
    public void doBusiness() {
        System.out.println("执行业务1");
    }
    @Override
    public StrategyEnum getStrategy() {
        return StrategyEnum.STRATEGY_ONE;
    }
}

 

 第一种方案 

1、注册接口到内存 枚举map
2、获取接口
3、调用业务

@Autowired
StrategyManage strategyManage;

@GetMapping(value = "/test")
public String test(String xmh){
strategyManage.initData(SourceEnum.TYPE_TWO);
return xmh;
}

@Service
public class StrategyManage {
    private EnumMap<SourceEnum,StrategyService> map = new EnumMap(SourceEnum.class);
    @Autowired
    void initEnummap(List<StrategyService> strategyServices){
        for(StrategyService strategyService:strategyServices){
            map.put(strategyService.getClass().getAnnotation(Strategy.class).source(),strategyService);
        }
    }
    public void initData(SourceEnum sourceEnum){
       map.get(sourceEnum).initData();
    }

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Strategy {
    SourceEnum  source();
}

@Strategy(source = SourceEnum.TYPE_ONE)
@Service
public class StrategyA implements StrategyService {
    @Override
    public void initData() {
        System.out.println("initData***********StrategyA");
    }
}
@Strategy(source = SourceEnum.TYPE_TWO)
@Service
public class StrategyB implements StrategyService {
    @Override
    public void initData() {
        System.out.println("initData***********StrategyB");
    }
}
public enum SourceEnum {
    TYPE_ONE("TT","单点"),TYPE_TWO("TO","点");
    private String code;
    private String name;

 第二种方案

    @GetMapping(value = "/test")
    public String test(String xmh){
        businessManager.doBusiness(StrategyInit.getStrategy(StrategyEnum.STRATEGY_ONE));
        return xmh;
    }

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) //接口、类、枚举
public @interface Strategy {
    StrategyEnum value() ;
}

public enum StrategyEnum {
    STRATEGY_ONE("myStrategyOne","这是策略1"),
    STRATEGY_TWO("myStrategyTwo","这是策略2"),
    STRATEGY_THREE("myStrategyThree","这是策略3");
    private String strategy;
    private String desc;
    StrategyEnum(String strategy, String desc) {
        this.strategy = strategy;
        this.desc = desc;
    }

@Service
public class BusinessManager {
    public void doBusiness(IMyStrategy strategy) {
        strategy.process("abc");
    }
}

@Component
public class StrategyInit implements BeanPostProcessor {
    private static ConcurrentHashMap<StrategyEnum, Object> map = new ConcurrentHashMap<>();
    public static IMyStrategy getStrategy(StrategyEnum name){
        return (IMyStrategy) map.get(name);
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if(bean instanceof IMyStrategy){
            Strategy annotation = bean.getClass().getAnnotation(Strategy.class);
            if(annotation != null){
                map.put(annotation.value(), bean);
            }
        }
        return bean;
    }

@Service
@Strategy(StrategyEnum.STRATEGY_TWO)
public class MyStrategyTwoImpl implements IMyStrategy {
    @Override
    public void process(String params) {
        System.out.println("策略2实现类执行: " + params);
    }
}
@Service
@Strategy(StrategyEnum.STRATEGY_ONE)
public class MyStrategyOneImpl implements IMyStrategy {
    @Override
    public void process(String params) {
        System.out.println("策略1实现类执行: " + params);
    }
}

public interface IMyStrategy {
    public void process(String params);
}

 

posted @ 2023-11-24 17:28  XUMT111  阅读(17)  评论(0)    收藏  举报