Spring Cloud之服务入口Gateway之自定义过滤器

Spring Cloud之服务入口Gateway之自定义过滤器

目录

过滤器执行顺序

自定义过滤器

自定义GatewayFilter

定义GatewayFilter

配置过滤器

启动服务并访问

自定义GlobalFilter

定义GlobalFilter

启动服务并访问

服务部署


过滤器执行顺序

如果⼀个项⽬中, 既有GatewayFilter, ⼜有 GlobalFilter时, 执⾏的先后顺序是什么呢?

请求路由后, ⽹关会把当前项⽬中的GatewayFilter和GlobalFilter合并到⼀个过滤器链(集合)中, 并进⾏排序, 依次执⾏过滤器.

每⼀个过滤器都必须指定⼀个int类型的order值, 默认值为0, 表⽰该过滤的优先级. order值越⼩,优先级越⾼,执⾏顺序越靠前.

• Filter通过实现Order接⼝或者添加@Order注解来指定order值.
• Spring Cloud Gateway提供的Filter由Spring指定. ⽤⼾也可以⾃定义Filter, 由⽤⼾指定.
• 当过滤器的order值⼀样时, 会按照 defaultFilter > GatewayFilter > GlobalFilter的顺序执⾏.

自定义过滤器

Spring Cloud Gateway提供了过滤器的扩展功能, 开发者可以根据实际业务来⾃定义过滤器, 同样⾃定义过滤器也⽀持GatewayFilter 和 GlobalFilter两种.

自定义GatewayFilter

⾃定义GatewayFilter, 需要去实现对应的接⼝ GatewayFilterFactory , Spring Boot 默认帮我们
实现的抽象类是 AbstractGatewayFilterFactory , 我们可以直接使⽤.

定义GatewayFilter
package gateway;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.***ponent;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@***ponent
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomConfig> implements Ordered {
    public CustomGatewayFilterFactory() {
        super(CustomConfig.class);
    }

    @Override
    public GatewayFilter apply(CustomConfig config) {
        return new GatewayFilter() {
            /**
             * ServerWebExchange: HTTP 请求-响应交互契约, 提供了对HTTP请求和响应的访问
             * GatewayFilterChain: 过滤器链
             * Mono: Reactor的核心类, 数据流发布者,Mono最多只能触发一个事件.可以把Mono用在异步完成任务时,发出通知
             * chain.filter(exchange)  执行请求
             * Mono.fromRunnable()  创建一个包含Runnable元素的数据流
             */
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //Pre类型   执行请求   Post类型
                log.info("Pre Filter, config:{} ",config);  //Pre类型过滤器代码逻辑
                return chain.filter(exchange).then(Mono.fromRunnable(()->{
                    log.info("Post Filter....");  //Post类型过滤器代码逻辑
                }));
            }
        };
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

针对这个Filter的配置, 使⽤CustomConfig 定义

package gateway;

import lombok.Data;

@Data
public class CustomConfig {
    private String name;
}

代码说明

1. 类名统⼀以GatewayFilterFactory结尾, 因为默认情况下, 过滤器的name会采⽤该定义类的前缀. 这⾥的name=Custom(yml配置中使⽤)
2. apply⽅法中, 同时包含Pre和Post过滤, then⽅法中是请求执⾏结束之后处理的
3. CustomConfig 是⼀个配置类, 该类只有⼀个属性name, 和yml的配置对应
4. 该类需要交给Spring管理, 所以需要加 @Service 注解
5. getOrder表⽰该过滤器的优先级, 值越⼤, 优先级越低

配置过滤器
spring:
  cloud:
    gateway:
      routes:
        - id: order-service   #路由规则id, 随便起, 不重复即可
          uri: lb://order-service/ #目标服务地址
          predicates:   #路由条件
            - Path=/order/**,/feign/**
          filters:
            - AddRequestParameter=userName, xiaoming
            - name: Custom    #过滤器名称
              args:
                name: test_custom
启动服务并访问
自定义GlobalFilter
GlobalFilter的实现⽐较简单, 它不需要额外的配置, 只需要实现GlobalFilter接⼝, ⾃动会过滤所有的
Filter.
定义GlobalFilter
package gateway;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.***ponent;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@***ponent
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("Pre Global Filter");
        return chain.filter(exchange).then(Mono.fromRunnable(()->{
            log.info("Post Global Filter...");
        }));
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}
启动服务并访问

从日志中可以看出,当GatewayFilter和GlobalFilter过滤器的order一样时,会先执行GatewayFilter,然后再执行GlobalFilter。其中会先执行 Pre GatewayFilter,然后执行 Pre GlobalFilter,然后执行 Post GlobalFilter,最后执行 Post GatewayFilter。

服务部署

1. 修改数据库, Nacos等相关配置
2. 对三个服务进⾏打包: product-service, order-service, gateway
3. 上传jar到Linux服务器
4. 启动Nacos
启动前最好把data数据删除掉.
5. 启动服务

#后台启动order-service, 并设置输出⽇志到logs/order.log
nohup java -jar order-service.jar >logs/order.log &


#后台启动product-service, 并设置输出⽇志到logs/order.log
nohup java -jar product-service.jar >logs/product-9090.log &


#启动⽹关
nohup java -jar gateway.jar >logs/gateway.log &

观察日志:

转载请说明出处内容投诉
CSS教程网 » Spring Cloud之服务入口Gateway之自定义过滤器

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买