当用户在EmbeddedServletContainerFactory中定义压缩策略时,只有当application.properties中存在任何启用的压缩配置时,才应覆盖压缩策略
[spring-projects/spring-boot]仅在启用时自定义压缩
回答
我注意到这个问题已经在2.x中修复了,但是1.5.x仍然存在这个问题,有计划在1.5.x中修复这个问题吗?
事实上,这个问题仍然存在。
我已经像这样定义了一个 EmbeddedServletContainerFactory ,但没有在 application.properties 中定义任何内容server.compression
。
@Bean
public EmbeddedServletContainerFactory tomcatContainer(@Value("${serverBindAddress:0.0.0.0}") final String serverBindAddress,
@Value("${httpPort:8080}") final String httpPort, @Value("${httpsPort:8443}") final String httpsPort,
@Value("${sslKeystoreFilePath}") final String sslKeystoreFilePath) {
logger.debug("Using serverBindAddress --> {}", serverBindAddress);
logger.debug("Using HTTP Port --> {}", httpPort);
logger.debug("Using HTTPS Port --> {}", httpsPort);
logger.debug("Using SSL keystore file path --> {}", sslKeystoreFilePath);
final TomcatEmbeddedServletContainerFactory tomcatContainerFactory = new TomcatEmbeddedServletContainerFactory();
tomcatContainerFactory.setPort(Integer.valueOf(httpPort).intValue());
final Compression compression = new Compression();
compression.setEnabled(true);
final String[] mimeTypes = {"xyz"};
compression.setMimeTypes(mimeTypes);
compression.setMinResponseSize(10);
tomcatContainerFactory.setCompression(compression);
final Connector sslConnector = this.createSSLConnector(serverBindAddress, httpsPort, sslKeystoreFilePath);
if (sslConnector != null) {
tomcatContainerFactory.addAdditionalTomcatConnectors(sslConnector);
}
return tomcatContainerFactory;
}
问题在于ServerProperties.java
,
@NestedConfigurationProperty
private Compression compression = new Compression();
这compression
永远不会为空,并且它总是覆盖EmbeddedServletContainerFactory
.
所以这个改变还是有必要的。或者只是更改配置加载以不创建默认
Compression
对象。
谢谢,杰克
ServerProperties
我明白你的意思,不幸的是,当你尝试直接配置时,我们没有一个好的方法来禁用它。您可以尝试在此 PR 中添加针对您的特定用例的测试吗?
我将在周末添加测试用例,并且我创建了一个问题https://github.com/spring-projects/spring-boot/issues/14803
谢谢,我将关闭该问题,我们将仅使用此 PR 进行讨论。
我们可以退一步,您能描述一下您实际面临的问题吗?Compression
如果自定义被禁用,则此更改将阻止设置自定义。这根本不是一个坏的举动,因为三个实现(Tomcat、Jetty、Undertow)必须检查压缩对象是否为非空以及是否启用了压缩。
它们都这样做,因此您添加的测试是人为的,并且只有在您有ConfigurableEmbeddedServletContainer
不检查enabled
标志的自定义实现时才会导致问题。是这样吗?如果没有,您可以分享一个显示问题的示例吗?
问题是我想以编程方式配置 mime 类型以进行压缩,因此我必须进行自定义EmbeddedServletContainerFactory
才能实现此目的,并且默认压缩对象会ServerProperties.java
覆盖我的更改。
我同意你的担忧,我确实认为解决这个问题的最好方法是不为任何配置创建这个默认对象,但我不知道 Spring Boot 中有多少地方实现了相同的,我认为这个问题存在在 Spring Boot 2.x 中也是如此。
实际上,还有另一种方法可以实现我想要做的事情是获取实例ServerProperties
并修改它,但我不确定这是否是我应该做的事情。
这样做是因为您的定制器未订购。我们的订单是 0,因此如果您想在此之后运行,您需要实现Ordered
并提供高于 0 的订单。或者,您可以使用@Order(1)
(或类似的东西)标记您的定制器。
我还不确定是否值得更改当前的定制器。您能尝试一下并告诉我们吗?
不,他们@Order(Ordered.HIGHEST_PRECEDENCE)
没有达到目的。
默认顺序是Ordered.LOWEST_PRECEDENCE
这样,任何没有明确配置顺序的定制器都应该在我们的定制器之后运行。
无论如何,这里似乎不涉及用户配置的定制器。EmbeddedServletContainerFactory
@wenjiezhang2013 提供了一个自定义工厂 bean。 Boot 的ServerProperties
bean 由于是一个,因此会覆盖在自定义bean 定义EmbeddedServletContainerCustomizer
中完成的一些自定义。EmbeddedServletContainerFactory
@wenjiezhang2013 您应该能够通过将自定义移动到EmbeddedServletContainerCustomizer
作为 bean 公开的实现中来解决当前的行为。如果您不给它指定顺序,则默认情况下它将以最低优先级排序,然后应在 执行的自定义之后运行ServerProperties
。
哦,我认为误解了@snicoll 的观点,对此感到抱歉。
@wilkinsona,这种方法有效,现在的问题是我们应该关闭这个 PR 吗?
由于您使用的是 1.5,并且我们试图将其中的更改保持在最低限度,所以让我们关闭此版本。我很高兴你有一个解决方法。
我同意我们不必在 1.5.x 中修复这个问题,但是 2.x 呢,我查看了 2.x 中的代码,我认为它也有同样的问题。
@wenjiezhang2013 以正确的顺序注册定制器不是解决方法,而是推荐的方法。它在2.0.x
和中master
也有效。