@EnableZuulProxy 在 servlet 2.5 容器下不起作用。是否有任何解决方法可以让 spring-cloud zuul 在servet 2.5 容器下工作?
我也找不到@EnableZuulProxy 的注释处理器。请提供支持 @EnableZuulProxy 的类,以便我可以更好地理解这个注释的真正作用。
2 回答
@EnableZuulProxy
来自 Spring Cloud,它基于 Servlet 3.0 及更高版本的 Spring Boot。如果您需要使用 Servlet 2.5,您可以直接使用 Netflix API。
@EnableZuulProxy
是元注释@Import(ZuulProxyConfiguration.class)
所以我想这就是你说“propesses”时的意思?如果您不知道 an@Import
是什么,请阅读 Spring。
Spring Cloud 旨在在 servlet 3.0 上运行。话虽如此,可以在 servlet 2.5 上运行 @EnableZuulProxy。我必须为此想出一个技巧,因为我必须让它在 Tomcat 6 中工作。
主要问题是由于 ZuulConfiguration.class 具有以下方法:
@Bean
@ConditionalOnMissingBean(name = "zuulServlet")
public ServletRegistrationBean zuulServlet() { ... }
这里的问题是ServletRegistrationBean
uses 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()
方法。这是因为ZuulProxyConfiguration
extends 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