美文网首页
API-Server构建指南(2)-使用注解作为功能开关

API-Server构建指南(2)-使用注解作为功能开关

作者: 东阿 | 来源:发表于2019-12-06 10:55 被阅读0次

    Filter 写好了,那么就需要配置上去,我们需要的 优雅的 功能开关,毕竟不是每个项目都要默认启用此FIlter。
    听起来最简单的是,读取配置,根据配置项来决定是否注入 某Filter。
    遗憾的是,我看到了一个 更装逼,更优雅的方式。
    注解。

    @UrlParamCheck // 只需要增加这个注解,就可以启用 UrlParamFilter。反之,不启用
    public class App  {
    
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    
    }
    

    现在开始动手实现。

    第一步 肯定是 定义注解

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)  // 此注解作用于类 上
    @Documented
    @Import(UrlParamCheckConfigRegistrar.class)
    public @interface UrlParamCheck {
        int order() default Ordered.LOWEST_PRECEDENCE;
    }
    
    
    

    第二步 编写一个工具类,用于 将一个filter 转换为 一份 Bean声明,并注册到 spring bean 声明的注册中心去。

    @UtilityClass
    @Slf4j
    public class BeanDefinitionUtils {
    
        /**
         * 注册一个 filter
         * @param registry  注册中心 ,待传入
         * @param order  Filter的挂载顺序
         * @param name  spring bean 的名称,全局唯一
         * @param urlPatterns  url过滤规则
         * @param filter  待注册的filter
         */
        public static void registerFilter(BeanDefinitionRegistry registry, int order, String name, Collection<String> urlPatterns, Object filter) {
            if (registry.containsBeanDefinition(name)) {
                log.warn("duplicate beanName, the bean exist in spring IOC,will skip :" + name);
                return;
            }
            BeanDefinition annotationProcessor = BeanDefinitionBuilder
                .genericBeanDefinition(FilterRegistrationBean.class)
                .addPropertyValue("urlPatterns", urlPatterns)
                .addPropertyValue("name", name)
                .addPropertyValue("order", order)
                .addPropertyValue("filter", filter)
                .getBeanDefinition();
            registry.registerBeanDefinition(name, annotationProcessor);
        }
    }
    
    

    第三步,也是最重要的一步 编写 一个bean 声明 注册器

    public class UrlParamCheckConfigRegistrar implements ImportBeanDefinitionRegistrar {
    
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            AnnotationAttributes attributes = AnnotationAttributes   //固定写法,用于后续获取 此注解使用时所 定义的属性的值
                .fromMap(importingClassMetadata
                .getAnnotationAttributes(UrlParamCheck.class.getName()));
            int order = attributes.getNumber("order"); // 通过attributes 可以获取注解所定义的属性的值
            // 使用钢材声明的工具类,将 UrlParamCheckFilter 注册进spring
            BeanDefinitionUtils.registerFilter(registry, order, "urlParamCheckFilter", Collections.singleton("/*"), new UrlParamCheckFilter());
        }
    }
    

    实现完毕,最核心的就是 通过 注解上的 @Import(UrlParamCheckConfigRegistrar.class) 来引导spring 导入新的注册器,再通过注册器,注册一份新的 bean 声明,此处声明的是一个filter bean。其他的bean可以同样处理。

    相关文章

      网友评论

          本文标题:API-Server构建指南(2)-使用注解作为功能开关

          本文链接:https://www.haomeiwen.com/subject/brvsgctx.html