1. 小心配置内置predicateFactory和filterFactory
- 这两个factory的简称是NameUtils类中的normalizeRoutePredicateName和normalizeFilterFactoryName来获取的,即直接替换后缀。
- 具体调用在RouteDefinitionRouteLocator#initFactories可以发现。就是将容器中所有的Factory存储在HashMap中
- 在存储hashmap的时候,并没有忽略大小写,所以我们在配置的时候,一定要正确的类名key来配置。否则就会报出异常
routes:
- id: 1
uri: http://www.baidu.com
predicates:
- After=2018-01-20T06:06:06+08:00[Asia/Shanghai]
# 即After就等于AfterRoutePredicateFactory
2.规范自定义predicateFactory和filterFactory
- 自定义需要继承AbstractRoutePredicateFactory或者AbstractGatewayFilterFactory
- 自定义的类名,注意规范类名是这样: predicate以RoutePredicateFactory, filter以GatewayFilterFactory结尾。这样就会以
简称来代表对应得到factory了,在NameUtils类中可以得出 - 不过你想个性,不按照这样也行,key就等于类名getSimpleName。
比如配置一个规范的predicate, HahaRoutePredicateFactory,这样就可以以Haha来配置
predicates:
- Haha=xx
如果你没有配置规范的,比如Hahaqwer extends AbstractRoutePredicateFactory,那么就只能通过getSimpleName来配置
predicates:
- Hahaqwer=xx
3. 可以配置多个predicates,多个相同的都可以
代表同时满足,才会满足条件。即多个predicate是 and的关系
配置N个filters,就会执行N个filter调用链
4.predicates和filters配置解析
- 看了PredicateDefinition和FilterDefinition的代码和构造函数,可以得出,都有一个name和args属性。name是工厂的名字,args代表配置的值。
并且配置都是以key=value键值对配置的。并且value可以以逗号分隔,代表多个 - 因为args是用hashmap存储的,文件中配置都是value,所以gateway就动态创建key(NameUtils#generateName查看)
以前缀genkey作为key:
public static final String GENERATED_NAME_PREFIX = "_genkey_";
public static String generateName(int i) {
return GENERATED_NAME_PREFIX + i;
}
predicates:
- After=2018-01-20T06:06:06+08:00[Asia/Shanghai]
filters:
- StripPrefix=qq,aa
#上面这个配置,所以最后解析转换的对象是:
PredicateDefinition(name=After, args={ "_genkey_0" : "2018-01-20T06:06:06+08:00[Asia/Shanghai]" })
FilterDefinition(name=StripPrefix, args={ "_genkey_0" : "qq" , "_genkey_1" : "aa" })
5. 泛型配置类转换ShortcutConfigurable
gateway解析将创建的args参数绑定到GatewayFilterFactory或者GatewayFilterFactory如下这个泛型参数中。
要想绑定,那肯定就是反射实例化,然后对属性设置值,对吧,下面的ShortcutType就是对配置args进行动态key和泛型T的属性一一对应
interface GatewayFilterFactory<T>{}
interface GatewayFilterFactory<T>{}
ShortcutType
首先该类有一个ShortcutType的枚举类,包括三种类型
DEFAULT 可查看AfterRoutePredicateFactory
GATHER_LIST 可查看HostRoutePredicateFactory
GATHER_LIST_TAIL_FLAG 可查看PathRoutePredicateFactory
- DEFAULT
- 就是根据接口的default List shortcutFieldOrder(){} 来一一对应args的参数进行设置
比如第三步,解析的对象是FilterDefinition(name=xx, args={ "_genkey_0" : "qq" , "_genkey_1" : "aa" })
如下是xx的工厂类的实现
public List<String> shortcutFieldOrder() {
return Arrays.asList("k1","k2"); //这里k1属性,对应args的_genkey_0
//这里k2属性,对应args的_genkey_1
}
- 最后解析得到对象,转换为json就是:
{
"k1":"qq",
"k2":"aa"
}
- GATHER_LIST
- 如果用这个,shortcutFieldOrder接口实现返回的list,必须是size=1
同样拿第三步创建解析的对象是FilterDefinition(name=xx, args={ "_genkey_0" : "qq" , "_genkey_1" : "aa" })
public List<String> shortcutFieldOrder() {
return Arrays.asList("k1"); // 这里必须只能返回一个size
}
public ShortcutType shortcutType() {
return ShortcutType.GATHER_LIST;
}
- GATHER_LIST是采集集合,其实原理就是hashmap.values()方法,最终获得对象就是如下json
{
"k1":["qq","aa"]
}
- GATHER_LIST_TAIL_FLAG
- shortcutFieldOrder 必须返回size=2的集合
public List<String> shortcutFieldOrder() {
return Arrays.asList("k1","k2"); // 这里必须返回size=2的集合
}
- 同样也是采集集合list,不同的是,多了一个尾部的boolean标识
-
如果args最后一个值,不是true或者false,就是跟 GATHER_LIST一样,得到json如下,然后第二个key就无效
{ "k1":["qq","aa"] }
-
如果args最后一个值,是true或者false
也就是args={ “_genkey_0” : “qq” , “_genkey_1” : “aa” ,"_genkey_2":“true”}){ "k1":["qq","aa"], "k2":true }
-
数据绑定到Configurable接口的泛型类上
- 得到上面解析的json之后,最后通过反射绑定到factory的泛型T类上就可以了