• 责任链例子



    import com.google.common.collect.Lists;
    import org.springframework.beans.BeansException;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.core.annotation.AnnotationAwareOrderComparator;
    import org.springframework.stereotype.Component;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.List;
    @Component
    public class FiledCheckHandlerFactory implements CommandLineRunner, ApplicationContextAware {

    private ApplicationContext applicationContext;

    private static AbstractFiledCheckHandler handlers;


    /**
    * 拼接变种责任链
    * @param args
    */
    @Override
    public void run(String... args) {
    Collection<AbstractFiledCheckHandler> checkHandlers = this.applicationContext.getBeansOfType(AbstractFiledCheckHandler.class).values();
    List<AbstractFiledCheckHandler> list = Lists.newArrayList(checkHandlers);
    Collections.sort(list, AnnotationAwareOrderComparator.INSTANCE);
    for (int i = 0; i < list.size() - 1; i++) {
    list.get(i).setNextHandler(list.get(i + 1));
    }
    setHandlers(list.get(0));
    }

    public static void setHandlers(AbstractFiledCheckHandler handlers) {
    FiledCheckHandlerFactory.handlers = handlers;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
    }

    /**
    * 执行方法校验
    * @param filedCheckDto
    */
    public static void processHandler(FiledCheckDto filedCheckDto) {
    handlers.handler(filedCheckDto);
    }
    }
    import lombok.Builder;
    import lombok.Data;
    import java.util.List;
    import java.util.Map;
    @Data
    @Builder
    public class FiledCheckDto {
    private List<FiledCheckEnum> checkEnums;
    private List<ModelPropertyResultDto> properties;
    private Map<String, Object> argument;
    private String modelCode;
    }
    import lombok.Data;
    @Data
    public abstract class AbstractFiledCheckHandler {
    protected AbstractFiledCheckHandler nextHandler = null;
    public abstract FiledCheckEnum getType();
    /**
    * 检测字段是否符合规范
    */
    public void handler(FiledCheckDto filedCheckDto) {
    //匹配到该类型
    if (filedCheckDto.getCheckEnums().contains(getType())) {
    checkHandler(filedCheckDto);
    }
    if (null == nextHandler) {
    return;
    }
    nextHandler.handler(filedCheckDto);
    }

    /**
    * 子类具体校验
    *
    * @param filedCheckDto
    */
    public abstract void checkHandler(FiledCheckDto filedCheckDto);
    }

    @Getter
    @AllArgsConstructor
    public enum FiledCheckEnum {
    // 检查字段是否存在
    CHECK_FILED_EXSIT(0, "存在校验"),
    CHECK_FILED_NULL(1, "非空校验"),
    CHECK_FILED_SEARCH(2, "搜索校验"),
    CHECK_FILED_EDIT(3, "编辑校验"),
    CHECK_FILED_IMPORT(4, "导入校验"),
    CHECK_FILED_SORT(5, "排序校验"),
    CHECK_FILED_TYPE(6,"类型校验"),
    CHECK_FILED_UNIQUE(7,"唯一校验"),
    CHECK_FILED_DEFAULT(8,"默认值校验"),
    ;
    private Integer code;
    private String value;

    public static String getValueByCode(Integer code) {
    FiledCheckEnum[] values = FiledCheckEnum.values();
    for (FiledCheckEnum type : values) {
    if (type.code.equals(code)) {
    return type.value;
    }
    }
    return null;
    }

    public static List<Integer> getCodes() {
    List<Integer> codes = Lists.newArrayList();
    FiledCheckEnum[] values = FiledCheckEnum.values();
    for (FiledCheckEnum type : values) {
    codes.add(type.getCode());
    }
    return codes;
    }

    public static Integer getCodeByValue(String value) {
    FiledCheckEnum[] values = FiledCheckEnum.values();
    for (FiledCheckEnum type : values) {
    if (type.value.equalsIgnoreCase(value)) {
    return type.code;
    }
    }
    return null;
    }
    }

    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;

    @Order(7)
    @Component
    @Slf4j
    public class FiledCheckDefaultHandler extends AbstractFiledCheckHandler {
    @Override
    public FiledCheckEnum getType() {
    return FiledCheckEnum.CHECK_FILED_DEFAULT;
    }

    /**
    * 如果值为空且有默认值,设置进去
    * @param filedCheckDto
    */
    @Override
    public void checkHandler(FiledCheckDto filedCheckDto) {
        // ...
    }
    }
    
    
    @Order(1)
    @Component
    @Slf4j
    public class FiledCheckExsitHandler extends AbstractFiledCheckHandler {
    @Override
    public FiledCheckEnum getType() {
    return FiledCheckEnum.CHECK_FILED_EXSIT;
    }

    /**
    * 检测字段是否符合规范
    *
    * @param filedCheckDto
    */
    @Override
    public void checkHandler(FiledCheckDto filedCheckDto) {
    // ...
    }
    }

    @RestController
    @RequestMapping("/a")
    public class AController {
      @PostMapping("/{modelCode}/add")
    @ResourceCheck(value = {FiledCheckEnum.CHECK_FILED_EXSIT, FiledCheckEnum.CHECK_FILED_NULL,
    FiledCheckEnum.CHECK_FILED_TYPE, FiledCheckEnum.CHECK_FILED_UNIQUE})
    public ApiResponse<String> add(
    @PathVariable("modelCode") String modelCode,
    @RequestBody Map<String, Object> params) {
    // ...
    return new ApiResponse<String>().success();
    }
    }

    @Target({ ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface ResourceCheck {

    FiledCheckEnum[] value() default {};

    }

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.aop.support.AopUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.annotation.AnnotationUtils;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import org.springframework.util.CollectionUtils;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    @Aspect
    @Component
    @Order(4)
    public class ResourceCheckAspect {
    @Autowired
    private ModelService modelService;

    @Pointcut("@annotation(com.aaa.ResourceCheck)")
    public void resourceCheckAspect() {
    // 切面位置以及方法定义
    }

    @Before("resourceCheckAspect()")
    public void doBefore(JoinPoint joinPoint) {
    // 拿到被注解的方法签名
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    // 拿到被注解的方法
    Method method = signature.getMethod();
    Method targetMethod = AopUtils.getMostSpecificMethod(method, joinPoint.getTarget().getClass());
    // 拿到注解类的参数
    Object[] arguments = joinPoint.getArgs();
    if (null == arguments || arguments.length <= 0) {
    throw new BizException(BaseCode.PARAM_ERROR);
    }
    ResourceCheck resourceCheck = AnnotationUtils.findAnnotation(targetMethod, ResourceCheck.class);
    // 先匹配方法名
    String modelCode = (String) arguments[0];
    Map<String, Object> argument = (Map<String, Object>) arguments[1];
    // 获取了所有字段
    List<ModelPropertyResultDto> properties = // ...
    if (null == resourceCheck || resourceCheck.value().length <= 0) {
    return;
    }
    FiledCheckDto build = FiledCheckDto.builder()
    .argument(argument)
    .properties(properties)
    .checkEnums(Arrays.asList(resourceCheck.value()))
    .modelCode(modelCode)
    .build();
    FiledCheckHandlerFactory.processHandler(build);
    }
    }
    
    
  • 相关阅读:
    阿里云oss云存储-----ossutil工具的使用
    Saltstack的安装
    SaltStack自定义modules模块
    Hadoop综合大作业
    理解MapReduce
    熟悉常用的HBase操作
    熟悉常用的HDFS操作
    爬虫大作业
    Hadoop综合大作业
    理解MapReduce
  • 原文地址:https://www.cnblogs.com/ladeng19/p/15716217.html
Copyright © 2020-2023  润新知