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);
}

浙公网安备 33010602011771号