You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2018/12/14 17:26:54 UTC

[incubator-skywalking] branch 5.x updated: Support spring mvc 5.x and spring webflux (#2047)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch 5.x
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git


The following commit(s) were added to refs/heads/5.x by this push:
     new 1e5ca15  Support spring mvc 5.x and spring webflux (#2047)
1e5ca15 is described below

commit 1e5ca15b25f277fd5e94aa78f1cad8271f25bb55
Author: Xin,Zhang <zh...@apache.org>
AuthorDate: Sat Dec 15 01:26:48 2018 +0800

    Support spring mvc 5.x and spring webflux (#2047)
    
    * Support spring mvc 5.x and spring webflux
    
    * Fix CI failed
---
 .../core/conf/RuntimeContextConfiguration.java     |   3 +-
 .../v4/define/AbstractSpring4Instrumentation.java  |   4 +-
 .../mvc-annotation-5.x-plugin/pom.xml              |  64 ++++++++++++
 .../mvc/v5/ControllerConstructorInterceptor.java   |  58 +++++++++++
 .../plugin/spring/mvc/v5/GetBeanInterceptor.java   |  59 +++++++++++
 .../define/AbstractControllerInstrumentation.java  | 112 ++++++++++++++++++++
 .../v5/define/AbstractSpring5Instrumentation.java} |  13 ++-
 .../mvc/v5/define/ControllerInstrumentation.java}  |  22 ++--
 .../v5/define/HandlerMethodInstrumentation.java    |  71 +++++++++++++
 .../v5/define/RestControllerInstrumentation.java}  |  17 ++--
 .../src/main/resources/skywalking-plugin.def       |  19 ++++
 .../apm/plugin/spring/mvc/commons/Constants.java   |   2 +
 apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml  |   2 +
 .../spring-plugins/webflux-5.x-plugin/pom.xml      |  59 +++++++++++
 .../webflux/v5/AbstractMethodInterceptor.java      | 102 +++++++++++++++++++
 .../spring/webflux/v5/ConstructorInterceptor.java  |  33 ++++++
 .../v5/ConstructorWithHttpRequestInterceptor.java  |  33 ++++++
 .../v5/ControllerConstructorInterceptor.java       |  57 +++++++++++
 .../webflux/v5/OnInboundNextInterceptor.java       |  66 ++++++++++++
 .../webflux/v5/OnOutboundCompleteInterceptor.java  |  50 +++++++++
 .../webflux/v5/OnOutboundErrorInterceptor.java     |  51 ++++++++++
 .../v5/RequestMappingMethodInterceptor.java        |  42 ++++++++
 .../webflux/v5/RestMappingMethodInterceptor.java   |  77 ++++++++++++++
 .../spring/webflux/v5/StatusInterceptor.java       |  50 +++++++++
 .../define/AbstractControllerInstrumentation.java  | 113 +++++++++++++++++++++
 .../AbstractSpringWebflux5Instrumentation.java}    |  13 ++-
 .../v5/define/ControllerInstrumentation.java}      |  22 ++--
 .../HttpServerOperations20xInstrumentation.java    | 107 +++++++++++++++++++
 .../HttpServerOperations21xInstrumentation.java    | 107 +++++++++++++++++++
 .../v5/define/RestControllerInstrumentation.java}  |  22 ++--
 .../src/main/resources/skywalking-plugin.def       |  20 ++++
 docs/Supported-list.md                             |   3 +-
 .../service-agent/java-agent}/Supported-list.md    |   7 +-
 33 files changed, 1419 insertions(+), 61 deletions(-)

diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
index f1b95a3..ae73809 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
@@ -23,6 +23,7 @@ public class RuntimeContextConfiguration {
 
     public static String[] NEED_PROPAGATE_CONTEXT_KEY = new String[] {
         "SW_REQUEST",
-        "SW_RESPONSE"
+        "SW_RESPONSE",
+        "SW_WEBFLUX_REQUEST_KEY"
     };
 }
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java
index 1d66adf..bf891d5 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java
@@ -22,10 +22,10 @@ package org.apache.skywalking.apm.plugin.spring.mvc.v4.define;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
 
 public abstract class AbstractSpring4Instrumentation extends ClassInstanceMethodsEnhancePluginDefine {
-    public static final String WITHNESS_CLASSES = "org.springframework.web.servlet.tags.ArgumentTag";
+    public static final String WITHNESS_CLASSES = "org.springframework.cache.interceptor.SimpleKey";
 
     @Override
     protected final String[] witnessClasses() {
-        return new String[] {WITHNESS_CLASSES};
+        return new String[] {WITHNESS_CLASSES, "org.springframework.cache.interceptor.DefaultKeyGenerator"};
     }
 }
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/pom.xml
new file mode 100644
index 0000000..46d786e
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/pom.xml
@@ -0,0 +1,64 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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
+  ~
+  ~      http://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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>spring-plugins</artifactId>
+        <groupId>org.apache.skywalking</groupId>
+        <version>5.1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>apm-springmvc-annotation-5.x-plugin</artifactId>
+    <packaging>jar</packaging>
+
+    <name>mvc-annotation-5.x-plugin</name>
+    <url>http://maven.apache.org</url>
+
+    <properties>
+        <spring-core.version>5.0.0.RELEASE</spring-core.version>
+        <spring-webmvc.version>5.0.0.RELEASE</spring-webmvc.version>
+        <javax-servlet-api.version>3.0.1</javax-servlet-api.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <version>${spring-core.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>${spring-webmvc.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>${javax-servlet-api.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>apm-springmvc-annotation-commons</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/ControllerConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/ControllerConstructorInterceptor.java
new file mode 100644
index 0000000..f32ca40
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/ControllerConstructorInterceptor.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *     http://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.apache.skywalking.apm.plugin.spring.mvc.v5;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache;
+import org.apache.skywalking.apm.plugin.spring.mvc.commons.PathMappingCache;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * The <code>ControllerConstructorInterceptor</code> intercepts the Controller's constructor, in order to acquire the
+ * mapping annotation, if exist.
+ *
+ * But, you can see we only use the first mapping value, <B>Why?</B>
+ *
+ * Right now, we intercept the controller by annotation as you known, so we CAN'T know which uri patten is actually
+ * matched. Even we know, that costs a lot.
+ *
+ * If we want to resolve that, we must intercept the Spring MVC core codes, that is not a good choice for now.
+ *
+ * Comment by @wu-sheng
+ */
+public class ControllerConstructorInterceptor implements InstanceConstructorInterceptor {
+
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+        String basePath = "";
+        RequestMapping basePathRequestMapping = objInst.getClass().getAnnotation(RequestMapping.class);
+        if (basePathRequestMapping != null) {
+            if (basePathRequestMapping.value().length > 0) {
+                basePath = basePathRequestMapping.value()[0];
+            } else if (basePathRequestMapping.path().length > 0) {
+                basePath = basePathRequestMapping.path()[0];
+            }
+        }
+        EnhanceRequireObjectCache enhanceRequireObjectCache = new EnhanceRequireObjectCache();
+        enhanceRequireObjectCache.setPathMappingCache(new PathMappingCache(basePath));
+        objInst.setSkyWalkingDynamicField(enhanceRequireObjectCache);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/GetBeanInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/GetBeanInterceptor.java
new file mode 100644
index 0000000..a2e2144
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/GetBeanInterceptor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.mvc.v5;
+
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT;
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT;
+
+/**
+ * {@link GetBeanInterceptor} pass the {@link NativeWebRequest} object into the {@link
+ * org.springframework.stereotype.Controller} object.
+ *
+ * @author zhangxin
+ */
+public class GetBeanInterceptor implements InstanceMethodsAroundInterceptor {
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        Object ret) throws Throwable {
+        if (ret instanceof EnhancedInstance) {
+            ContextManager.getRuntimeContext().put(REQUEST_KEY_IN_RUNTIME_CONTEXT, ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest());
+            ContextManager.getRuntimeContext().put(RESPONSE_KEY_IN_RUNTIME_CONTEXT, ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse());
+        }
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/AbstractControllerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/AbstractControllerInstrumentation.java
new file mode 100644
index 0000000..f089339
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/AbstractControllerInstrumentation.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.mvc.v5.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassAnnotationMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants;
+
+import static net.bytebuddy.matcher.ElementMatchers.*;
+
+/**
+ * {@link ControllerInstrumentation} enhance all constructor and method annotated with
+ * <code>org.springframework.web.bind.annotation.RequestMapping</code> that class has
+ * <code>org.springframework.stereotype.Controller</code> annotation.
+ *
+ * <code>ControllerConstructorInterceptor</code> set the controller base path to
+ * dynamic field before execute constructor.
+ *
+ * <code>org.apache.skywalking.apm.plugin.spring.mvc.v4.RequestMappingMethodInterceptor</code> get the request path from
+ * dynamic field first, if not found, <code>RequestMappingMethodInterceptor</code> generate request path  that
+ * combine the path value of current annotation on current method and the base path and set the new path to the dynamic
+ * filed
+ *
+ * @author zhangxin
+ */
+public abstract class AbstractControllerInstrumentation extends AbstractSpring5Instrumentation {
+    @Override
+    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[] {
+            new ConstructorInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getConstructorMatcher() {
+                    return any();
+                }
+
+                @Override
+                public String getConstructorInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.mvc.v5.ControllerConstructorInterceptor";
+                }
+            }
+        };
+    }
+
+    @Override
+    protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[] {
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return isAnnotatedWith(named("org.springframework.web.bind.annotation.RequestMapping"));
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return Constants.REQUEST_MAPPING_METHOD_INTERCEPTOR;
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return isAnnotatedWith(named("org.springframework.web.bind.annotation.GetMapping"))
+                        .or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PostMapping")))
+                        .or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PutMapping")))
+                        .or(isAnnotatedWith(named("org.springframework.web.bind.annotation.DeleteMapping")))
+                        .or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PatchMapping")));
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return Constants.REST_MAPPING_METHOD_INTERCEPTOR;
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            }
+        };
+    }
+
+    @Override
+    protected ClassMatch enhanceClass() {
+        return ClassAnnotationMatch.byClassAnnotationMatch(getEnhanceAnnotations());
+    }
+
+    protected abstract String[] getEnhanceAnnotations();
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/AbstractSpring5Instrumentation.java
similarity index 75%
copy from apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java
copy to apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/AbstractSpring5Instrumentation.java
index 1d66adf..e7126c8 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/AbstractSpring5Instrumentation.java
@@ -6,23 +6,22 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://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.
- *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 
-package org.apache.skywalking.apm.plugin.spring.mvc.v4.define;
+package org.apache.skywalking.apm.plugin.spring.mvc.v5.define;
 
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
 
-public abstract class AbstractSpring4Instrumentation extends ClassInstanceMethodsEnhancePluginDefine {
-    public static final String WITHNESS_CLASSES = "org.springframework.web.servlet.tags.ArgumentTag";
+public abstract class AbstractSpring5Instrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+    public static final String WITHNESS_CLASSES = "org.springframework.web.servlet.resource.HttpResource";
 
     @Override
     protected final String[] witnessClasses() {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/ControllerInstrumentation.java
similarity index 55%
copy from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
copy to apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/ControllerInstrumentation.java
index f1b95a3..c064338 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/ControllerInstrumentation.java
@@ -6,23 +6,23 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *    http://www.apache.org/licenses/LICENSE-2.0
+ *      http://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.
- *
- *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
-package org.apache.skywalking.apm.agent.core.conf;
 
-public class RuntimeContextConfiguration {
+package org.apache.skywalking.apm.plugin.spring.mvc.v5.define;
+
+public class ControllerInstrumentation extends AbstractControllerInstrumentation {
+
+    public static final String ENHANCE_ANNOTATION = "org.springframework.stereotype.Controller";
 
-    public static String[] NEED_PROPAGATE_CONTEXT_KEY = new String[] {
-        "SW_REQUEST",
-        "SW_RESPONSE"
-    };
+    @Override protected String[] getEnhanceAnnotations() {
+        return new String[] {ENHANCE_ANNOTATION};
+    }
 }
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/HandlerMethodInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/HandlerMethodInstrumentation.java
new file mode 100644
index 0000000..537c3c4
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/HandlerMethodInstrumentation.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.mvc.v5.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * {@link HandlerMethodInstrumentation} intercept the <code>getBean</code> method in the
+ * <code>org.springframework.web.method.HandlerMethod</code> class.
+ *
+ * @author zhangxin
+ */
+public class HandlerMethodInstrumentation extends AbstractSpring5Instrumentation {
+
+    public static final String ENHANCE_METHOD = "getBean";
+    public static final String ENHANCE_CLASS = "org.springframework.web.method.HandlerMethod";
+
+    @Override
+    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[0];
+    }
+
+    @Override
+    protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[] {
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named(ENHANCE_METHOD);
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.mvc.v5.GetBeanInterceptor";
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            }
+        };
+    }
+
+    @Override
+    protected ClassMatch enhanceClass() {
+        return NameMatch.byName(ENHANCE_CLASS);
+    }
+}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/RestControllerInstrumentation.java
similarity index 64%
copy from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
copy to apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/RestControllerInstrumentation.java
index f1b95a3..a7ae800 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/RestControllerInstrumentation.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *    http://www.apache.org/licenses/LICENSE-2.0
+ *     http://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,
@@ -14,15 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- *
  */
 
-package org.apache.skywalking.apm.agent.core.conf;
 
-public class RuntimeContextConfiguration {
+package org.apache.skywalking.apm.plugin.spring.mvc.v5.define;
+
+public class RestControllerInstrumentation extends AbstractControllerInstrumentation {
+
+    public static final String ENHANCE_ANNOTATION = "org.springframework.web.bind.annotation.RestController";
 
-    public static String[] NEED_PROPAGATE_CONTEXT_KEY = new String[] {
-        "SW_REQUEST",
-        "SW_RESPONSE"
-    };
+    @Override protected String[] getEnhanceAnnotations() {
+        return new String[] {ENHANCE_ANNOTATION};
+    }
 }
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 0000000..fa3b452
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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
+#
+#     http://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.
+
+spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.ControllerInstrumentation
+spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.RestControllerInstrumentation
+spring-mvc-annotation-5.x=org.apache.skywalking.apm.plugin.spring.mvc.v5.define.HandlerMethodInstrumentation
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/Constants.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/Constants.java
index 1ac2450..114f8c2 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/Constants.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/Constants.java
@@ -37,4 +37,6 @@ public class Constants {
     public static final String RESPONSE_KEY_IN_RUNTIME_CONTEXT = "SW_RESPONSE";
 
     public static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG";
+
+    public static final String WEBFLUX_REQUEST_KEY = "SW_WEBFLUX_REQUEST_KEY";
 }
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml
index f681263..46011d3 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml
@@ -35,6 +35,8 @@
         <module>mvc-annotation-3.x-plugin</module>
         <module>core-patch</module>
         <module>mvc-annotation-commons</module>
+        <module>mvc-annotation-5.x-plugin</module>
+        <module>webflux-5.x-plugin</module>
     </modules>
     <packaging>pom</packaging>
 
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/pom.xml
new file mode 100644
index 0000000..3fadda4
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/pom.xml
@@ -0,0 +1,59 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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
+  ~
+  ~      http://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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>spring-plugins</artifactId>
+        <groupId>org.apache.skywalking</groupId>
+        <version>5.1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>apm-webflux-5.x-plugin</artifactId>
+    <packaging>jar</packaging>
+
+    <name>webflux-5.x-plugin</name>
+    <url>http://maven.apache.org</url>
+
+    <properties>
+        <javax-servlet-api.version>3.0.1</javax-servlet-api.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webflux</artifactId>
+            <version>5.0.0.RELEASE</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>${javax-servlet-api.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>apm-springmvc-annotation-commons</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/AbstractMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/AbstractMethodInterceptor.java
new file mode 100644
index 0000000..da9dae6
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/AbstractMethodInterceptor.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import io.netty.handler.codec.http.HttpRequest;
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.context.CarrierItem;
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache;
+
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.FORWARD_REQUEST_FLAG;
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.WEBFLUX_REQUEST_KEY;
+
+/**
+ * the abstract method inteceptor
+ */
+public abstract class AbstractMethodInterceptor implements InstanceMethodsAroundInterceptor {
+    public abstract String getRequestURL(Method method);
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+
+        Boolean forwardRequestFlag = (Boolean)ContextManager.getRuntimeContext().get(FORWARD_REQUEST_FLAG);
+        /**
+         * Spring MVC plugin do nothing if current request is forward request.
+         * Ref: https://github.com/apache/incubator-skywalking/pull/1325
+         */
+        if (forwardRequestFlag != null && forwardRequestFlag) {
+            return;
+        }
+
+        EnhanceRequireObjectCache pathMappingCache = (EnhanceRequireObjectCache)objInst.getSkyWalkingDynamicField();
+        String requestURL = pathMappingCache.findPathMapping(method);
+        if (requestURL == null) {
+            requestURL = getRequestURL(method);
+            pathMappingCache.addPathMapping(method, requestURL);
+            requestURL = pathMappingCache.findPathMapping(method);
+        }
+
+        HttpRequest request = (HttpRequest)ContextManager.getRuntimeContext().get(WEBFLUX_REQUEST_KEY);
+        if (request != null) {
+            ContextCarrier contextCarrier = new ContextCarrier();
+            CarrierItem next = contextCarrier.items();
+            while (next.hasNext()) {
+                next = next.next();
+                next.setHeadValue(request.headers().get(next.getHeadKey()));
+            }
+
+            AbstractSpan span = ContextManager.createEntrySpan(requestURL, contextCarrier);
+            Tags.URL.set(span, request.uri().toString());
+            Tags.HTTP.METHOD.set(span, request.method().name());
+            span.setComponent(ComponentsDefine.SPRING_MVC_ANNOTATION);
+            SpanLayer.asHttp(span);
+        }
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        Object ret) throws Throwable {
+        Boolean forwardRequestFlag = (Boolean)ContextManager.getRuntimeContext().get(FORWARD_REQUEST_FLAG);
+        /**
+         * Spring MVC plugin do nothing if current request is forward request.
+         * Ref: https://github.com/apache/incubator-skywalking/pull/1325
+         */
+        if (forwardRequestFlag != null && forwardRequestFlag) {
+            return ret;
+        }
+
+        ContextManager.stopSpan();
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+        ContextManager.activeSpan().errorOccurred().log(t);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ConstructorInterceptor.java
new file mode 100644
index 0000000..d8a5566
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ConstructorInterceptor.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import io.netty.handler.codec.http.HttpRequest;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.WEBFLUX_REQUEST_KEY;
+
+public class ConstructorInterceptor implements InstanceConstructorInterceptor {
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+        HttpRequest httpRequest = (HttpRequest)allArguments[3];
+        ContextManager.getRuntimeContext().put(WEBFLUX_REQUEST_KEY, httpRequest);
+    }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ConstructorWithHttpRequestInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ConstructorWithHttpRequestInterceptor.java
new file mode 100644
index 0000000..e568f9f
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ConstructorWithHttpRequestInterceptor.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import io.netty.handler.codec.http.HttpRequest;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.WEBFLUX_REQUEST_KEY;
+
+public class ConstructorWithHttpRequestInterceptor implements InstanceConstructorInterceptor {
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+        HttpRequest httpRequest = (HttpRequest)allArguments[4];
+        ContextManager.getRuntimeContext().put(WEBFLUX_REQUEST_KEY, httpRequest);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ControllerConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ControllerConstructorInterceptor.java
new file mode 100644
index 0000000..947cd79
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/ControllerConstructorInterceptor.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache;
+import org.apache.skywalking.apm.plugin.spring.mvc.commons.PathMappingCache;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * The <code>ControllerConstructorInterceptor</code> intercepts the Controller's constructor, in order to acquire the
+ * mapping annotation, if exist.
+ *
+ * But, you can see we only use the first mapping value, <B>Why?</B>
+ *
+ * Right now, we intercept the controller by annotation as you known, so we CAN'T know which uri patten is actually
+ * matched. Even we know, that costs a lot.
+ *
+ * If we want to resolve that, we must intercept the Spring MVC core codes, that is not a good choice for now.
+ *
+ * Comment by @wu-sheng
+ */
+public class ControllerConstructorInterceptor implements InstanceConstructorInterceptor {
+
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+        String basePath = "";
+        RequestMapping basePathRequestMapping = objInst.getClass().getAnnotation(RequestMapping.class);
+        if (basePathRequestMapping != null) {
+            if (basePathRequestMapping.value().length > 0) {
+                basePath = basePathRequestMapping.value()[0];
+            } else if (basePathRequestMapping.path().length > 0) {
+                basePath = basePathRequestMapping.path()[0];
+            }
+        }
+        EnhanceRequireObjectCache enhanceRequireObjectCache = new EnhanceRequireObjectCache();
+        enhanceRequireObjectCache.setPathMappingCache(new PathMappingCache(basePath));
+        objInst.setSkyWalkingDynamicField(enhanceRequireObjectCache);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnInboundNextInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnInboundNextInterceptor.java
new file mode 100644
index 0000000..d439ce1
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnInboundNextInterceptor.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import io.netty.handler.codec.http.HttpRequest;
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.context.CarrierItem;
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.WEBFLUX_REQUEST_KEY;
+
+public class OnInboundNextInterceptor implements InstanceMethodsAroundInterceptor {
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+        HttpRequest request = (HttpRequest)ContextManager.getRuntimeContext().get(WEBFLUX_REQUEST_KEY);
+        if (request != null) {
+            ContextCarrier contextCarrier = new ContextCarrier();
+            CarrierItem next = contextCarrier.items();
+            while (next.hasNext()) {
+                next = next.next();
+                next.setHeadValue(request.headers().get(next.getHeadKey()));
+            }
+
+            AbstractSpan span = ContextManager.createEntrySpan(request.uri(), contextCarrier);
+            Tags.URL.set(span, request.uri());
+            Tags.HTTP.METHOD.set(span, request.method().name());
+            span.setComponent(ComponentsDefine.SPRING_MVC_ANNOTATION);
+            SpanLayer.asHttp(span);
+        }
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        Object ret) throws Throwable {
+        return ret;
+    }
+
+    @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+        ContextManager.activeSpan().errorOccurred().log(t);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnOutboundCompleteInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnOutboundCompleteInterceptor.java
new file mode 100644
index 0000000..8e45035
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnOutboundCompleteInterceptor.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import io.netty.handler.codec.http.HttpRequest;
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.WEBFLUX_REQUEST_KEY;
+
+public class OnOutboundCompleteInterceptor implements InstanceMethodsAroundInterceptor {
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        Object ret) throws Throwable {
+        HttpRequest request = (HttpRequest)ContextManager.getRuntimeContext().get(WEBFLUX_REQUEST_KEY);
+        if (request != null) {
+            ContextManager.stopSpan();
+            ContextManager.getRuntimeContext().remove(WEBFLUX_REQUEST_KEY);
+        }
+        return ret;
+    }
+
+    @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+        ContextManager.activeSpan().errorOccurred().log(t);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnOutboundErrorInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnOutboundErrorInterceptor.java
new file mode 100644
index 0000000..496b57e
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/OnOutboundErrorInterceptor.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import io.netty.handler.codec.http.HttpRequest;
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.WEBFLUX_REQUEST_KEY;
+
+public class OnOutboundErrorInterceptor implements InstanceMethodsAroundInterceptor {
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+        Throwable exception = (Throwable)allArguments[0];
+        HttpRequest request = (HttpRequest)ContextManager.getRuntimeContext().get(WEBFLUX_REQUEST_KEY);
+        if (request != null) {
+            ContextManager.activeSpan().errorOccurred().log(exception);
+        }
+
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        Object ret) throws Throwable {
+        return ret;
+    }
+
+    @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RequestMappingMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RequestMappingMethodInterceptor.java
new file mode 100644
index 0000000..3bace06
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RequestMappingMethodInterceptor.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import java.lang.reflect.Method;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * The <code>RequestMappingMethodInterceptor</code> only use the first mapping value. it will inteceptor with
+ * <code>@RequestMapping</code>
+ *
+ * @author clevertension
+ */
+public class RequestMappingMethodInterceptor extends AbstractMethodInterceptor {
+    @Override
+    public String getRequestURL(Method method) {
+        String requestURL = "";
+        RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class);
+        if (methodRequestMapping.value().length > 0) {
+            requestURL = methodRequestMapping.value()[0];
+        } else if (methodRequestMapping.path().length > 0) {
+            requestURL = methodRequestMapping.path()[0];
+        }
+        return requestURL;
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RestMappingMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RestMappingMethodInterceptor.java
new file mode 100644
index 0000000..064671c
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RestMappingMethodInterceptor.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import java.lang.reflect.Method;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+
+/**
+ * The <code>RestMappingMethodInterceptor</code> only use the first mapping value. it will inteceptor with
+ * <code>@GetMapping</code>, <code>@PostMapping</code>, <code>@PutMapping</code>
+ * <code>@DeleteMapping</code>, <code>@PatchMapping</code>
+ *
+ * @author clevertension
+ */
+public class RestMappingMethodInterceptor extends AbstractMethodInterceptor {
+    @Override
+    public String getRequestURL(Method method) {
+        String requestURL = "";
+        GetMapping getMapping = method.getAnnotation(GetMapping.class);
+        PostMapping postMapping = method.getAnnotation(PostMapping.class);
+        PutMapping putMapping = method.getAnnotation(PutMapping.class);
+        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
+        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
+        if (getMapping != null) {
+            if (getMapping.value().length > 0) {
+                requestURL = getMapping.value()[0];
+            } else if (getMapping.path().length > 0) {
+                requestURL = getMapping.path()[0];
+            }
+        } else if (postMapping != null) {
+            if (postMapping.value().length > 0) {
+                requestURL = postMapping.value()[0];
+            } else if (postMapping.path().length > 0) {
+                requestURL = postMapping.path()[0];
+            }
+        } else if (putMapping != null) {
+            if (putMapping.value().length > 0) {
+                requestURL = putMapping.value()[0];
+            } else if (putMapping.path().length > 0) {
+                requestURL = putMapping.path()[0];
+            }
+        } else if (deleteMapping != null) {
+            if (deleteMapping.value().length > 0) {
+                requestURL = deleteMapping.value()[0];
+            } else if (deleteMapping.path().length > 0) {
+                requestURL = deleteMapping.path()[0];
+            }
+        } else if (patchMapping != null) {
+            if (patchMapping.value().length > 0) {
+                requestURL = patchMapping.value()[0];
+            } else if (patchMapping.path().length > 0) {
+                requestURL = patchMapping.path()[0];
+            }
+        }
+        return requestURL;
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/StatusInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/StatusInterceptor.java
new file mode 100644
index 0000000..e271765
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/StatusInterceptor.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5;
+
+import io.netty.handler.codec.http.HttpResponseStatus;
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+
+public class StatusInterceptor implements InstanceMethodsAroundInterceptor {
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        MethodInterceptResult result) throws Throwable {
+        HttpResponseStatus status = (HttpResponseStatus)allArguments[0];
+        if (status.code() > 400) {
+            ContextManager.activeSpan().errorOccurred();
+            Tags.STATUS_CODE.set(ContextManager.activeSpan(), String.valueOf(status.code()));
+        }
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
+        Object ret) throws Throwable {
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+        Class<?>[] argumentsTypes, Throwable t) {
+        ContextManager.activeSpan().errorOccurred().log(t);
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/AbstractControllerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/AbstractControllerInstrumentation.java
new file mode 100644
index 0000000..be8e56f
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/AbstractControllerInstrumentation.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassAnnotationMatch;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.any;
+import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * {@link ControllerInstrumentation} enhance all constructor and method annotated with
+ * <code>org.springframework.web.bind.annotation.RequestMapping</code> that class has
+ * <code>org.springframework.stereotype.Controller</code> annotation.
+ *
+ * <code>ControllerConstructorInterceptor</code> set the controller base path to
+ * dynamic field before execute constructor.
+ *
+ * <code>org.apache.skywalking.apm.plugin.spring.mvc.v4.RequestMappingMethodInterceptor</code> get the request path
+ * from dynamic field first, if not found, <code>RequestMappingMethodInterceptor</code> generate request path  that
+ * combine the path value of current annotation on current method and the base path and set the new path to the dynamic
+ * filed
+ *
+ * @author zhangxin
+ */
+public abstract class AbstractControllerInstrumentation extends AbstractSpringWebflux5Instrumentation {
+    @Override
+    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[] {
+            new ConstructorInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getConstructorMatcher() {
+                    return any();
+                }
+
+                @Override
+                public String getConstructorInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.ControllerConstructorInterceptor";
+                }
+            }
+        };
+    }
+
+    @Override
+    protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[] {
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return isAnnotatedWith(named("org.springframework.web.bind.annotation.RequestMapping"));
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.RequestMappingMethodInterceptor";
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return isAnnotatedWith(named("org.springframework.web.bind.annotation.GetMapping"))
+                        .or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PostMapping")))
+                        .or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PutMapping")))
+                        .or(isAnnotatedWith(named("org.springframework.web.bind.annotation.DeleteMapping")))
+                        .or(isAnnotatedWith(named("org.springframework.web.bind.annotation.PatchMapping")));
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.RestMappingMethodInterceptor";
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            }
+        };
+    }
+
+    @Override
+    protected ClassMatch enhanceClass() {
+        return ClassAnnotationMatch.byClassAnnotationMatch(getEnhanceAnnotations());
+    }
+
+    protected abstract String[] getEnhanceAnnotations();
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/AbstractSpringWebflux5Instrumentation.java
similarity index 71%
copy from apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java
copy to apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/AbstractSpringWebflux5Instrumentation.java
index 1d66adf..7559e72 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v4/define/AbstractSpring4Instrumentation.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/AbstractSpringWebflux5Instrumentation.java
@@ -6,23 +6,22 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://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.
- *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 
-package org.apache.skywalking.apm.plugin.spring.mvc.v4.define;
+package org.apache.skywalking.apm.plugin.spring.webflux.v5.define;
 
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
 
-public abstract class AbstractSpring4Instrumentation extends ClassInstanceMethodsEnhancePluginDefine {
-    public static final String WITHNESS_CLASSES = "org.springframework.web.servlet.tags.ArgumentTag";
+public abstract class AbstractSpringWebflux5Instrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+    public static final String WITHNESS_CLASSES = "org.springframework.web.reactive.BindingContext";
 
     @Override
     protected final String[] witnessClasses() {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/ControllerInstrumentation.java
similarity index 55%
copy from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
copy to apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/ControllerInstrumentation.java
index f1b95a3..d977064 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/ControllerInstrumentation.java
@@ -6,23 +6,23 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *    http://www.apache.org/licenses/LICENSE-2.0
+ *      http://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.
- *
- *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
-package org.apache.skywalking.apm.agent.core.conf;
 
-public class RuntimeContextConfiguration {
+package org.apache.skywalking.apm.plugin.spring.webflux.v5.define;
+
+public class ControllerInstrumentation extends AbstractControllerInstrumentation {
+
+    public static final String ENHANCE_ANNOTATION = "org.springframework.stereotype.Controller";
 
-    public static String[] NEED_PROPAGATE_CONTEXT_KEY = new String[] {
-        "SW_REQUEST",
-        "SW_RESPONSE"
-    };
+    @Override protected String[] getEnhanceAnnotations() {
+        return new String[] {ENHANCE_ANNOTATION};
+    }
 }
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/HttpServerOperations20xInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/HttpServerOperations20xInstrumentation.java
new file mode 100644
index 0000000..bd26e37
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/HttpServerOperations20xInstrumentation.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
+import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+public class HttpServerOperations20xInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+    @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[] {
+            new ConstructorInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getConstructorMatcher() {
+                    return takesArgumentWithType(4, "io.netty.handler.codec.http.HttpRequest");
+                }
+
+                @Override public String getConstructorInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.ConstructorWithHttpRequestInterceptor";
+                }
+            }
+        };
+    }
+
+    @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[] {
+            new InstanceMethodsInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("status").and(takesArguments(1));
+                }
+
+                @Override public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.StatusInterceptor";
+                }
+
+                @Override public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("onInboundNext");
+                }
+
+                @Override public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.OnInboundNextInterceptor";
+                }
+
+                @Override public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("onOutboundComplete");
+                }
+
+                @Override public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.OnOutboundCompleteInterceptor";
+                }
+
+                @Override public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("onOutboundError");
+                }
+
+                @Override public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.OnOutboundErrorInterceptor";
+                }
+
+                @Override public boolean isOverrideArgs() {
+                    return false;
+                }
+            }
+        };
+    }
+
+    @Override protected ClassMatch enhanceClass() {
+        return byName("reactor.ipc.netty.http.server.HttpServerOperations");
+    }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/HttpServerOperations21xInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/HttpServerOperations21xInstrumentation.java
new file mode 100644
index 0000000..3d19bbe
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/HttpServerOperations21xInstrumentation.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.apache.skywalking.apm.plugin.spring.webflux.v5.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
+import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+public class HttpServerOperations21xInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+    @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[] {
+            new ConstructorInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getConstructorMatcher() {
+                    return takesArgumentWithType(3, "io.netty.handler.codec.http.HttpRequest");
+                }
+
+                @Override public String getConstructorInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.ConstructorInterceptor";
+                }
+            }
+        };
+    }
+
+    @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[] {
+            new InstanceMethodsInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("status").and(takesArguments(1));
+                }
+
+                @Override public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.StatusInterceptor";
+                }
+
+                @Override public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("onInboundNext");
+                }
+
+                @Override public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.OnInboundNextInterceptor";
+                }
+
+                @Override public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("onOutboundComplete");
+                }
+
+                @Override public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.OnOutboundCompleteInterceptor";
+                }
+
+                @Override public boolean isOverrideArgs() {
+                    return false;
+                }
+            },
+            new InstanceMethodsInterceptPoint() {
+                @Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("onOutboundError");
+                }
+
+                @Override public String getMethodsInterceptor() {
+                    return "org.apache.skywalking.apm.plugin.spring.webflux.v5.OnOutboundErrorInterceptor";
+                }
+
+                @Override public boolean isOverrideArgs() {
+                    return false;
+                }
+            }
+        };
+    }
+
+    @Override protected ClassMatch enhanceClass() {
+        return byName("reactor.netty.http.server.HttpServerOperations");
+    }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/RestControllerInstrumentation.java
similarity index 54%
copy from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
copy to apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/RestControllerInstrumentation.java
index f1b95a3..fb405b0 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/RuntimeContextConfiguration.java
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/RestControllerInstrumentation.java
@@ -6,23 +6,23 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *    http://www.apache.org/licenses/LICENSE-2.0
+ *      http://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.
- *
- *
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
-package org.apache.skywalking.apm.agent.core.conf;
 
-public class RuntimeContextConfiguration {
+package org.apache.skywalking.apm.plugin.spring.webflux.v5.define;
+
+public class RestControllerInstrumentation extends AbstractControllerInstrumentation {
+
+    public static final String ENHANCE_ANNOTATION = "org.springframework.web.bind.annotation.RestController";
 
-    public static String[] NEED_PROPAGATE_CONTEXT_KEY = new String[] {
-        "SW_REQUEST",
-        "SW_RESPONSE"
-    };
+    @Override protected String[] getEnhanceAnnotations() {
+        return new String[] {ENHANCE_ANNOTATION};
+    }
 }
diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 0000000..54affbe
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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
+#
+#     http://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.
+
+spring-webflux-5.x=org.apache.skywalking.apm.plugin.spring.webflux.v5.define.HttpServerOperations20xInstrumentation
+spring-webflux-5.x=org.apache.skywalking.apm.plugin.spring.webflux.v5.define.HttpServerOperations21xInstrumentation
+spring-webflux-5.x=org.apache.skywalking.apm.plugin.spring.webflux.v5.define.ControllerInstrumentation
+spring-webflux-5.x=org.apache.skywalking.apm.plugin.spring.webflux.v5.define.RestControllerInstrumentation
diff --git a/docs/Supported-list.md b/docs/Supported-list.md
index b2fc63e..1765c2c 100644
--- a/docs/Supported-list.md
+++ b/docs/Supported-list.md
@@ -3,7 +3,8 @@
   * [Tomcat](https://github.com/apache/tomcat) 8
   * [Tomcat](https://github.com/apache/tomcat) 9
   * [Spring Boot](https://github.com/spring-projects/spring-boot) Web 4.x
-  * Spring MVC 3.x, 4.x with servlet 3.x
+  * Spring MVC 3.x, 4.x,5.x with servlet 3.x
+  * [Spring Webflux](https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html)
   * [Nutz Web Framework](https://github.com/nutzam/nutz)  1.x
   * [Struts2 MVC](http://struts.apache.org/)  2.3.x -> 2.5.x
   * [Resin](http://www.caucho.com/resin-4.0/) 3 (Optional¹)
diff --git a/docs/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md
similarity index 87%
copy from docs/Supported-list.md
copy to docs/en/setup/service-agent/java-agent/Supported-list.md
index b2fc63e..ac836b0 100644
--- a/docs/Supported-list.md
+++ b/docs/en/setup/service-agent/java-agent/Supported-list.md
@@ -3,12 +3,13 @@
   * [Tomcat](https://github.com/apache/tomcat) 8
   * [Tomcat](https://github.com/apache/tomcat) 9
   * [Spring Boot](https://github.com/spring-projects/spring-boot) Web 4.x
-  * Spring MVC 3.x, 4.x with servlet 3.x
+  * Spring MVC 3.x, 4.x 5.x with servlet 3.x
   * [Nutz Web Framework](https://github.com/nutzam/nutz)  1.x
   * [Struts2 MVC](http://struts.apache.org/)  2.3.x -> 2.5.x
   * [Resin](http://www.caucho.com/resin-4.0/) 3 (Optional¹)
   * [Resin](http://www.caucho.com/resin-4.0/) 4 (Optional¹)
   * [Jetty Server](http://www.eclipse.org/jetty/) 9
+  * [Spring Webflux](https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html) 5.x
   * [Undertow](http://undertow.io/)  2.0.0.Final -> 2.0.13.Final
 * HTTP Client
   * [Feign](https://github.com/OpenFeign/feign) 9.x
@@ -35,6 +36,7 @@
   * [RocketMQ](https://github.com/apache/rocketmq) 4.x
   * [Kafka](http://kafka.apache.org) 0.11.0.0 -> 1.0
   * [ActiveMQ](https://github.com/apache/activemq) 5.x
+  * [RabbitMQ](https://www.rabbitmq.com/) 5.x
 * NoSQL
   * Redis
     * [Jedis](https://github.com/xetorthio/jedis) 2.x
@@ -54,6 +56,7 @@
   * [Elastic Job](https://github.com/elasticjob/elastic-job) 2.x
 * OpenTracing community supported
 
-¹Required dependencies for these components must be first manually downloaded before being built, due to license incompatibilities. For this reason these components are not by default included in the SkyWalking releases.
+¹Due to license incompatibilities/restrictions these plugins are hosted and released in 3rd part repository, 
+ go to [OpenSkywalking java plugin extension repository](https://github.com/OpenSkywalking/java-plugin-extensions) to get these.
 
 ²These plugins affect the performance or must be used under some conditions, from experiences. So only released in `/optional-plugins`, copy to `/plugins` in order to make them work.