wu-sheng closed pull request #1993: Support webflux and spring mvc 5 plugin
URL: https://github.com/apache/incubator-skywalking/pull/1993
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

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 f1b95a3ca1..ae7380939e 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 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 1d66adff7a..bf891d53f3 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 @@
 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 0000000000..9f94946861
--- /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>6.0.0-beta-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 0000000000..f32ca40638
--- /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 0000000000..a2e2144b0e
--- /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 0000000000..5fe377563d
--- /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,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.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.DeclaredInstanceMethodsInterceptPoint;
+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 DeclaredInstanceMethodsInterceptPoint() {
+                @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 DeclaredInstanceMethodsInterceptPoint() {
+                @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-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/AbstractSpring5Instrumentation.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
new file mode 100644
index 0000000000..e7126c871b
--- /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/AbstractSpring5Instrumentation.java
@@ -0,0 +1,30 @@
+/*
+ * 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 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+
+public abstract class AbstractSpring5Instrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
+    public static final String WITHNESS_CLASSES = 
"org.springframework.web.servlet.resource.HttpResource";
+
+    @Override
+    protected final String[] witnessClasses() {
+        return new String[] {WITHNESS_CLASSES};
+    }
+}
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/ControllerInstrumentation.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
new file mode 100644
index 0000000000..c0643382a3
--- /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/ControllerInstrumentation.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+public class ControllerInstrumentation extends 
AbstractControllerInstrumentation {
+
+    public static final String ENHANCE_ANNOTATION = 
"org.springframework.stereotype.Controller";
+
+    @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 0000000000..537c3c43c9
--- /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-sdk-plugin/spring-plugins/mvc-annotation-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/v5/define/RestControllerInstrumentation.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
new file mode 100644
index 0000000000..a7ae800c3e
--- /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/RestControllerInstrumentation.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+public class RestControllerInstrumentation extends 
AbstractControllerInstrumentation {
+
+    public static final String ENHANCE_ANNOTATION = 
"org.springframework.web.bind.annotation.RestController";
+
+    @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 0000000000..fa3b452c17
--- /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 1ac245018e..114f8c2d4e 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 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 b83eea8617..d9eef03719 100644
--- a/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml
@@ -36,6 +36,8 @@
         <module>core-patch</module>
         <module>mvc-annotation-commons</module>
         <module>spring-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 0000000000..ba2fabd1b5
--- /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>6.0.0-beta-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 0000000000..da9dae605f
--- /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 0000000000..d8a5566d49
--- /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 0000000000..e568f9fb8f
--- /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 0000000000..947cd794fc
--- /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 0000000000..d439ce137b
--- /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 0000000000..8e45035ff8
--- /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 0000000000..496b57e197
--- /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 0000000000..3bace06cec
--- /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 0000000000..064671c272
--- /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 0000000000..e2717657af
--- /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 0000000000..2d415731be
--- /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,114 @@
+/*
+ * 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.DeclaredInstanceMethodsInterceptPoint;
+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 DeclaredInstanceMethodsInterceptPoint() {
+                @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 DeclaredInstanceMethodsInterceptPoint() {
+                @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/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/AbstractSpringWebflux5Instrumentation.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
new file mode 100644
index 0000000000..7559e729b9
--- /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/AbstractSpringWebflux5Instrumentation.java
@@ -0,0 +1,30 @@
+/*
+ * 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 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+
+public abstract class AbstractSpringWebflux5Instrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
+    public static final String WITHNESS_CLASSES = 
"org.springframework.web.reactive.BindingContext";
+
+    @Override
+    protected final String[] witnessClasses() {
+        return new String[] {WITHNESS_CLASSES};
+    }
+}
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/ControllerInstrumentation.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
new file mode 100644
index 0000000000..d977064e73
--- /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/ControllerInstrumentation.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+public class ControllerInstrumentation extends 
AbstractControllerInstrumentation {
+
+    public static final String ENHANCE_ANNOTATION = 
"org.springframework.stereotype.Controller";
+
+    @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 0000000000..bd26e37e5f
--- /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 0000000000..3d19bbe93c
--- /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-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/define/RestControllerInstrumentation.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
new file mode 100644
index 0000000000..fb405b0642
--- /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/RestControllerInstrumentation.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+public class RestControllerInstrumentation extends 
AbstractControllerInstrumentation {
+
+    public static final String ENHANCE_ANNOTATION = 
"org.springframework.web.bind.annotation.RestController";
+
+    @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 0000000000..54affbeabf
--- /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/en/setup/service-agent/java-agent/Supported-list.md 
b/docs/en/setup/service-agent/java-agent/Supported-list.md
index 7573ae72f9..ac836b0350 100644
--- a/docs/en/setup/service-agent/java-agent/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


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to