1
  1. @EnableZuulProxy 在 servlet 2.5 容器下不起作用。是否有任何解决方法可以让 spring-cloud zuul 在servet 2.5 容器下工作?

  2. 我也找不到@EnableZuulProxy 的注释处理器。请提供支持 @EnableZuulProxy 的类,以便我可以更好地理解这个注释的真正作用。

4

2 回答 2

2

@EnableZuulProxy来自 Spring Cloud,它基于 Servlet 3.0 及更高版本的 Spring Boot。如果您需要使用 Servlet 2.5,您可以直接使用 Netflix API。

@EnableZuulProxy是元注释@Import(ZuulProxyConfiguration.class)所以我想这就是你说“propesses”时的意思?如果您不知道 an@Import是什么,请阅读 Spring。

于 2015-12-22T15:41:47.813 回答
2

Spring Cloud 旨在在 servlet 3.0 上运行。话虽如此,可以在 servlet 2.5 上运行 @EnableZuulProxy。我必须为此想出一个技巧,因为我必须让它在 Tomcat 6 中工作。

主要问题是由于 ZuulConfiguration.class 具有以下方法:

@Bean
@ConditionalOnMissingBean(name = "zuulServlet")    
public ServletRegistrationBean zuulServlet() { ... }

这里的问题是ServletRegistrationBeanuses javax.servlet.Registration$Dynamic,直到 Servlet 3.0 才可用。这导致一个NoClassDefFoundError.

要解决此问题,请使用spring-boot-legacy项目首先注册一个 DispatcherServlet。其次,您必须手动创建一个 zuul servlet。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.dm.gateway.microservicegateway.Application</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.boot.legacy.context.web.SpringBootContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>ContextLifecycleFilter</filter-name>
        <filter-class>com.netflix.zuul.context.ContextLifecycleFilter</filter-class>
    </filter>


    <filter-mapping>
        <filter-name>ContextLifecycleFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextAttribute</param-name>
            <param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>zuul</servlet-name>
        <servlet-class>com.netflix.zuul.http.ZuulServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

我发现删除自动 servlet 注册的最佳方法是制作ZuulConfig 被调用的逐字副本ZuulOverrideConfig,然后删除该zuulServlet()方法。这是因为ZuulProxyConfigurationextends ZuulConfiguration,即使我试图覆盖它,它似乎也创建了 bean。我不是 100% 了解这背后的机制,所以可能有更好的方法。

我所做的第二个更改ZuulOverrideConfig是调用 的扩展实现ZuulFilterInitializer,称为“LegacyZuulFilterInitializer”。这是因为由于某种原因,Zuul servlet 被装箱,并且能够被调用,但没有引导过滤器。这个扩展是一种让过滤器引导的 hacky 方法。

ZuulProxyConfiguration接下来,我创建了一个被调用的副本ZuulLegacyProxyConfiguraiton,并让它扩展ZuulOverrideConfig.class

最后,我将 Application 类注释如下。

@EnableCircuitBreaker
@EnableDiscoveryClient
@Import(ZuulLegacyProxyConfiguration.class)
@SpringBootApplication
public class Application {....}

在所有这些黑客攻击之后,实施最终按预期工作。我不建议长时间使用它,因为它很hacky。迁移到新版本时,您不会自动获得配置类更新,而且我不能保证某些东西不会随机中断!

这是使用 Spring Cloud 1.1.4.RELEASE

所有代码的要点。

于 2016-07-19T19:20:58.753 回答