diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java index 830165989d4..d5d73e8f891 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +73,7 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest private long connectionRequestTimeout = -1; + /** * Create a new instance of the {@code HttpComponentsClientHttpRequestFactory} * with a default {@link HttpClient} based on system properties. @@ -202,6 +203,7 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest this.httpContextFactory = httpContextFactory; } + @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { HttpClient client = getHttpClient(); @@ -309,8 +311,8 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest } /** - * Template method that allows for manipulating the {@link ClassicHttpRequest} before it is - * returned as part of a {@link HttpComponentsClientHttpRequest}. + * Template method that allows for manipulating the {@link ClassicHttpRequest} + * before it is returned as part of a {@link HttpComponentsClientHttpRequest}. *
The default implementation is empty.
* @param request the request to process
*/
@@ -331,8 +333,7 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest
/**
- * Shutdown hook that closes the underlying
- * {@link HttpClientConnectionManager ClientConnectionManager}'s
+ * Shutdown hook that closes the underlying {@link HttpClientConnectionManager}'s
* connection pool, if any.
*/
@Override
diff --git a/spring-web/src/main/java/org/springframework/http/client/ReactorResourceFactory.java b/spring-web/src/main/java/org/springframework/http/client/ReactorResourceFactory.java
index faed920cf66..3d1a0982acb 100644
--- a/spring-web/src/main/java/org/springframework/http/client/ReactorResourceFactory.java
+++ b/spring-web/src/main/java/org/springframework/http/client/ReactorResourceFactory.java
@@ -61,12 +61,12 @@ public class ReactorResourceFactory
private Supplier Lazily tries to start the resources on demand if not initialized yet.
+ * @see #start()
*/
public ConnectionProvider getConnectionProvider() {
- Assert.state(this.connectionProvider != null, "ConnectionProvider not initialized yet");
- return this.connectionProvider;
+ if (this.connectionProvider == null) {
+ start();
+ }
+ ConnectionProvider connectionProvider = this.connectionProvider;
+ Assert.state(connectionProvider != null, "ConnectionProvider not initialized");
+ return connectionProvider;
}
/**
* Use this when you don't want to participate in global resources and
* you want to customize the creation of the managed {@code LoopResources}.
- * By default, {@code LoopResources.create("reactor-http")} is used.
+ * By default, {@code LoopResources.create("webflux-http")} is used.
* Note that this option is ignored if {@code userGlobalResources=false} or
* {@link #setLoopResources(LoopResources)} is set.
* @param supplier the supplier to use
@@ -170,10 +176,16 @@ public class ReactorResourceFactory
/**
* Return the configured {@link LoopResources}.
+ * Lazily tries to start the resources on demand if not initialized yet.
+ * @see #start()
*/
public LoopResources getLoopResources() {
- Assert.state(this.loopResources != null, "LoopResources not initialized yet");
- return this.loopResources;
+ if (this.loopResources == null) {
+ start();
+ }
+ LoopResources loopResources = this.loopResources;
+ Assert.state(loopResources != null, "LoopResources not initialized");
+ return loopResources;
}
/**
@@ -220,6 +232,12 @@ public class ReactorResourceFactory
}
+ /**
+ * Starts the resources if initialized outside an ApplicationContext.
+ * This is for backwards compatibility; the preferred way is to rely on
+ * the ApplicationContext's {@link SmartLifecycle lifecycle management}.
+ * @see #start()
+ */
@Override
public void afterPropertiesSet() {
if (this.applicationContext == null) {
@@ -227,6 +245,12 @@ public class ReactorResourceFactory
}
}
+ /**
+ * Stops the resources if initialized outside an ApplicationContext.
+ * This is for backwards compatibility; the preferred way is to rely on
+ * the ApplicationContext's {@link SmartLifecycle lifecycle management}.
+ * @see #stop()
+ */
@Override
public void destroy() {
if (this.applicationContext == null) {
diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/ReactorNetty2ResourceFactory.java b/spring-web/src/main/java/org/springframework/http/client/reactive/ReactorNetty2ResourceFactory.java
index 05a8bebeb24..9555a1c67a8 100644
--- a/spring-web/src/main/java/org/springframework/http/client/reactive/ReactorNetty2ResourceFactory.java
+++ b/spring-web/src/main/java/org/springframework/http/client/reactive/ReactorNetty2ResourceFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -135,7 +135,7 @@ public class ReactorNetty2ResourceFactory implements InitializingBean, Disposabl
/**
* Use this when you don't want to participate in global resources and
* you want to customize the creation of the managed {@code LoopResources}.
- * By default, {@code LoopResources.create("reactor-http")} is used.
+ * By default, {@code LoopResources.create("webflux-http")} is used.
* Note that this option is ignored if {@code userGlobalResources=false} or
* {@link #setLoopResources(LoopResources)} is set.
* @param supplier the supplier to use
@@ -170,7 +170,6 @@ public class ReactorNetty2ResourceFactory implements InitializingBean, Disposabl
* can also be overridden with the system property
* {@link reactor.netty5.ReactorNetty#SHUTDOWN_QUIET_PERIOD
* ReactorNetty.SHUTDOWN_QUIET_PERIOD}.
- * @since 5.2.4
* @see #setShutdownTimeout(Duration)
*/
public void setShutdownQuietPeriod(Duration shutdownQuietPeriod) {
@@ -187,7 +186,6 @@ public class ReactorNetty2ResourceFactory implements InitializingBean, Disposabl
* can also be overridden with the system property
* {@link reactor.netty5.ReactorNetty#SHUTDOWN_TIMEOUT
* ReactorNetty.SHUTDOWN_TIMEOUT}.
- * @since 5.2.4
* @see #setShutdownQuietPeriod(Duration)
*/
public void setShutdownTimeout(Duration shutdownTimeout) {
diff --git a/spring-web/src/test/java/org/springframework/http/client/ReactorResourceFactoryTests.java b/spring-web/src/test/java/org/springframework/http/client/ReactorResourceFactoryTests.java
index a08c8983a6b..86d65e64ef9 100644
--- a/spring-web/src/test/java/org/springframework/http/client/ReactorResourceFactoryTests.java
+++ b/spring-web/src/test/java/org/springframework/http/client/ReactorResourceFactoryTests.java
@@ -261,4 +261,22 @@ class ReactorResourceFactoryTests {
assertThat(resourceFactory.isRunning()).isFalse();
}
+ @Test
+ void lazilyStartOnConnectionProviderAccess() {
+ assertThat(this.resourceFactory.isRunning()).isFalse();
+ this.resourceFactory.getConnectionProvider();
+ assertThat(this.resourceFactory.isRunning()).isTrue();
+ this.resourceFactory.stop();
+ assertThat(this.resourceFactory.isRunning()).isFalse();
+ }
+
+ @Test
+ void lazilyStartOnLoopResourcesAccess() {
+ assertThat(this.resourceFactory.isRunning()).isFalse();
+ this.resourceFactory.getLoopResources();
+ assertThat(this.resourceFactory.isRunning()).isTrue();
+ this.resourceFactory.stop();
+ assertThat(this.resourceFactory.isRunning()).isFalse();
+ }
+
}