diff --git a/spring-web/src/main/java/org/springframework/web/filter/reactive/ServerWebExchangeContextFilter.java b/spring-web/src/main/java/org/springframework/web/filter/reactive/ServerWebExchangeContextFilter.java
new file mode 100644
index 00000000000..db376c70192
--- /dev/null
+++ b/spring-web/src/main/java/org/springframework/web/filter/reactive/ServerWebExchangeContextFilter.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2002-2019 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.web.filter.reactive;
+
+import java.util.Optional;
+
+import reactor.core.publisher.Mono;
+import reactor.util.context.Context;
+
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+
+/**
+ * Inserts an attribute in the Reactor {@link Context} that makes the current
+ * {@link ServerWebExchange} available under the attribute name
+ * {@link #EXCHANGE_CONTEXT_ATTRIBUTE}. This is useful for access to the
+ * exchange without explicitly passing it to components that participate in
+ * request processing.
+ *
+ *
The convenience method {@link #get(Context)} looks up the exchange.
+ *
+ * @author Rossen Stoyanchev
+ * @since 5.2
+ */
+public class ServerWebExchangeContextFilter implements WebFilter {
+
+ /** Attribute name under which the exchange is saved in the context. */
+ public static final String EXCHANGE_CONTEXT_ATTRIBUTE =
+ ServerWebExchangeContextFilter.class.getName() + ".EXCHANGE_CONTEXT";
+
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {
+ return chain.filter(exchange)
+ .subscriberContext(cxt -> cxt.put(EXCHANGE_CONTEXT_ATTRIBUTE, exchange));
+ }
+
+
+ /**
+ * Access the {@link ServerWebExchange} from the Reactor Context, if available,
+ * which is if {@link ServerWebExchangeContextFilter} is configured for use
+ * and the give context was obtained from a request processing chain.
+ * @param context the context in which to access the exchange
+ * @return the exchange
+ */
+ public static Optional get(Context context) {
+ return context.getOrEmpty(EXCHANGE_CONTEXT_ATTRIBUTE);
+ }
+
+}
diff --git a/spring-web/src/test/java/org/springframework/web/filter/reactive/ServerWebExchangeContextFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/reactive/ServerWebExchangeContextFilterTests.java
new file mode 100644
index 00000000000..a804e9d4e4f
--- /dev/null
+++ b/spring-web/src/test/java/org/springframework/web/filter/reactive/ServerWebExchangeContextFilterTests.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2002-2019 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.web.filter.reactive;
+
+import java.time.Duration;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.Test;
+import reactor.core.publisher.Mono;
+
+import org.springframework.http.server.reactive.HttpHandler;
+import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
+import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
+
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests for {@link ServerWebExchangeContextFilter}.
+ * @author Rossen Stoyanchev
+ */
+public class ServerWebExchangeContextFilterTests {
+
+ @Test
+ public void extractServerWebExchangeFromContext() {
+ MyService service = new MyService();
+
+ HttpHandler httpHandler = WebHttpHandlerBuilder
+ .webHandler(exchange -> service.service().then())
+ .filter(new ServerWebExchangeContextFilter())
+ .build();
+
+ httpHandler.handle(MockServerHttpRequest.get("/path").build(), new MockServerHttpResponse())
+ .block(Duration.ofSeconds(5));
+
+ assertNotNull(service.getExchange());
+ }
+
+
+ private static class MyService {
+
+ private final AtomicReference exchangeRef = new AtomicReference<>();
+
+
+ public ServerWebExchange getExchange() {
+ return this.exchangeRef.get();
+ }
+
+ public Mono service() {
+ return Mono.just("result").subscriberContext(context -> {
+ ServerWebExchangeContextFilter.get(context).ifPresent(exchangeRef::set);
+ return context;
+ });
+ }
+ }
+
+}