zuul源码分析--Filter注册

最近项目中使用zuul,zuul网上资料较少,顺便把源码看一遍分析一下。网上有几篇相关文章,已转载在博客中,这里再补充一点东西,应该就差不多了。这里讲的有点跳,如果zuul不熟悉,建议先看下zuul源码分析之Request生命周期管理 这篇文章。

zuul开启

首先由@EnableZuulProxy 注解是开启zuul的注解。

@EnableCircuitBreaker
@EnableDiscoveryClient
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
//引入zuul配置
@Import({ZuulProxyConfiguration.class})
public @interface EnableZuulProxy {
}

ZuulProxyConfiguration 继承了ZuulConfiguration

//该配置等同于xml中的beans
@Configuration
public class ZuulProxyConfiguration extends ZuulConfiguration {
@Configuration
@EnableConfigurationProperties({ZuulProperties.class})
//加载了ZuulServlet后才会加载该配置
@ConditionalOnClass({ZuulServlet.class})
@Import({ServerPropertiesAutoConfiguration.class})
public class ZuulConfiguration {

这两个类主要加载了四类东西:

1,注册zuulServlet,ZuulController 这是后面调用一些列zuulFilter的入口。

//ZuulController实现ServletWrappingController
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView var3;
    try {
       //此处调用zuulServlet中的方法
        var3 = super.handleRequestInternal(request, response);
    } finally {
        RequestContext.getCurrentContext().unset();
    }

    return var3;
}

2,加载zuul各种自带的filter,比如preDecorationFilter、ribbonRoutingFilter等等

  我这个版本中(1.1.2.RELEASE),zuul默认加载的filter有: pre类型的filter5个,route的3个,post的2个,共10个filter。  每个filter的功能这里就不详述了。

一些场景下,我们想要禁用掉部分过滤器,此时该怎么办呢?在网上看到了这个方法:

只需设置zuul.<SimpleClassName>.<filterType>.disable=true ,即可禁用SimpleClassName所对应的过滤器。以过滤器org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter为例,只需设置zuul.SendResponseFilter.post.disable=true ,即可禁用该过滤器。

3,加载ZuulFilterConfiguration,这个是定义在ZuulConfiguration中的Configuration。这个配置是将所有filter由ZuulFilterInitializer收集到FilterRegistry中。调用时,filter都是从这当中取的。

@Configuration
protected static class ZuulFilterConfiguration {
//按类型将所有ZuulFilter注入到map中
    @Autowired
    private Map<String, ZuulFilter> filters;

    protected ZuulFilterConfiguration() {
    }

    @Bean
    public ZuulFilterInitializer zuulFilterInitializer() {
        return new ZuulFilterInitializer(this.filters);
    }
}

4,加载ZuulRefreshListener、ZuulDiscoveryRefreshListener用于动态刷新zuul配置

p.s. 当应用启动时,加载顺序是:Configuration配置》ConditionalOnClass注解的bean》Configuration中的Configuration》自定义bean》Configuration中的bean》Configuration中的Configuration中的bean

zuul之filter调用

基本的调用顺序就不细说了,转载文章中介绍的比较详细。这里说一下zuul一个有点绕的地方。在ZuulServlet中

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    try {
        this.init((HttpServletRequest)servletRequest, (HttpServletResponse)servletResponse);
        RequestContext e = RequestContext.getCurrentContext();
        e.setZuulEngineRan();

        try {
            this.preRoute();
        } catch (ZuulException var12) {
            this.error(var12);
            this.postRoute();
            return;
        }

        try {
            this.route();
        } catch (ZuulException var13) {
            this.error(var13);
            this.postRoute();
            return;
        }

        try {
            this.postRoute();
        } catch (ZuulException var11) {
            this.error(var11);
        }
    } catch (Throwable var14) {
        this.error(new ZuulException(var14, 500, "UNHANDLED_EXCEPTION_" + var14.getClass().getName()));
    } finally {
       //清空上下文
        RequestContext.getCurrentContext().unset();
    }
}

如果执行pre类型的filter抛出ZuulException则执行error类型的filter,再执行post类型的filter

如果执行route类型的filter抛出ZuulException则执行error类型的filter,再执行post类型的filter

如果执行post类型的filter抛出ZuulException则执行error类型的filter

如果在抛出其他异常,或者在catch ZuulException后执行发生异常,则执行error类型的filter

这里有点绕,如果使用的时候需要注意一下。另外zuul许多默认的filter,虽然是zuul开发人员考虑周到,但在我们自己定制功能中,也可能造成麻烦。

转载于:https://my.oschina.net/u/3300636/blog/851984

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值