diff --git a/dubbo-samples-rpccontext/README.md b/dubbo-samples-rpccontext/README.md
new file mode 100644
index 0000000000..2bf4ab19de
--- /dev/null
+++ b/dubbo-samples-rpccontext/README.md
@@ -0,0 +1,2 @@
+## 隐式参数
+可以通过 RpcContext 上的 setAttachment 和 getAttachment 在服务消费方和提供方之间进行参数的隐式传递。
\ No newline at end of file
diff --git a/dubbo-samples-rpccontext/case-configuration.yml b/dubbo-samples-rpccontext/case-configuration.yml
new file mode 100644
index 0000000000..709e741d9c
--- /dev/null
+++ b/dubbo-samples-rpccontext/case-configuration.yml
@@ -0,0 +1,65 @@
+# 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.
+
+services:
+ zookeeper:
+ image: zookeeper:latest
+
+ dubbo-samples-rpccontext-provider2:
+ type: app
+ basedir: .
+ mainClass: org.apache.dubbo.samples.rpccontext.RpcContextProvider2
+ systemProps:
+ - zookeeper.address=zookeeper
+ waitPortsBeforeRun:
+ - zookeeper:2181
+ checkPorts:
+ - 20882
+ checkLog: "Rpc context provider2 started"
+ depends_on:
+ - zookeeper
+
+
+ dubbo-samples-rpccontext-provider:
+ type: app
+ basedir: .
+ mainClass: org.apache.dubbo.samples.rpccontext.RpcContextProvider1
+ systemProps:
+ - zookeeper.address=zookeeper
+ waitPortsBeforeRun:
+ - zookeeper:2181
+ checkPorts:
+ - 20880
+ checkLog: "Rpc context provider1 started"
+ depends_on:
+ - zookeeper
+ - dubbo-samples-rpccontext-provider2
+
+ dubbo-samples-rpccontext-consumer:
+ type: test
+ basedir: .
+ tests:
+ - "**/*IT.class"
+ systemProps:
+ - zookeeper.address=zookeeper
+ waitPortsBeforeRun:
+ - zookeeper:2181
+ - dubbo-samples-rpccontext-provider:20880
+ - dubbo-samples-rpccontext-provider2:20882
+ depends_on:
+ - zookeeper
+ - dubbo-samples-rpccontext-provider
+ - dubbo-samples-rpccontext-provider2
diff --git a/dubbo-samples-rpccontext/case-versions.conf b/dubbo-samples-rpccontext/case-versions.conf
new file mode 100644
index 0000000000..a226141fc7
--- /dev/null
+++ b/dubbo-samples-rpccontext/case-versions.conf
@@ -0,0 +1,24 @@
+#
+#
+# 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.
+#
+
+
+# Supported component versions of the test case
+
+# Spring app
+dubbo.version= [ >= 3.2.0 ]
+spring.version=4.*, 5.*
diff --git a/dubbo-samples-rpccontext/pom.xml b/dubbo-samples-rpccontext/pom.xml
new file mode 100644
index 0000000000..ee604b3815
--- /dev/null
+++ b/dubbo-samples-rpccontext/pom.xml
@@ -0,0 +1,128 @@
+
+
+
+
+ * Register an error handler via {@link #setErrorHandler} in order to handle
+ * any exceptions thrown during startup or execution.
+ */
+ @Override
+ public synchronized void start() {
+ if (zkServerThread == null) {
+ zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter");
+ zkServerThread.setDaemon(daemon);
+ zkServerThread.start();
+ }
+ }
+
+ /**
+ * Shutdown the ZooKeeper server.
+ */
+ @Override
+ public synchronized void stop() {
+ if (zkServerThread != null) {
+ // The shutdown method is protected...thus this hack to invoke it.
+ // This will log an exception on shutdown; see
+ // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details.
+ try {
+ Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown");
+ shutdown.setAccessible(true);
+ shutdown.invoke(zkServer);
+ }
+
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ // It is expected that the thread will exit after
+ // the server is shutdown; this will block until
+ // the shutdown is complete.
+ try {
+ zkServerThread.join(5000);
+ zkServerThread = null;
+ }
+ catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ logger.warn("Interrupted while waiting for embedded ZooKeeper to exit");
+ // abandoning zk thread
+ zkServerThread = null;
+ }
+ }
+ }
+
+ /**
+ * Stop the server if running and invoke the callback when complete.
+ */
+ @Override
+ public void stop(Runnable callback) {
+ stop();
+ callback.run();
+ }
+
+ /**
+ * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none
+ * is provided, only error-level logging will occur.
+ *
+ * @param errorHandler the {@link ErrorHandler} to be invoked
+ */
+ public void setErrorHandler(ErrorHandler errorHandler) {
+ this.errorHandler = errorHandler;
+ }
+
+ /**
+ * Runnable implementation that starts the ZooKeeper server.
+ */
+ private class ServerRunnable implements Runnable {
+
+ @Override
+ public void run() {
+ try {
+ Properties properties = new Properties();
+ File file = new File(System.getProperty("java.io.tmpdir")
+ + File.separator + UUID.randomUUID());
+ file.deleteOnExit();
+ properties.setProperty("dataDir", file.getAbsolutePath());
+ properties.setProperty("clientPort", String.valueOf(clientPort));
+
+ QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig();
+ quorumPeerConfig.parseProperties(properties);
+
+ zkServer = new ZooKeeperServerMain();
+ ServerConfig configuration = new ServerConfig();
+ configuration.readFrom(quorumPeerConfig);
+
+ zkServer.runFromConfig(configuration);
+ }
+ catch (Exception e) {
+ if (errorHandler != null) {
+ errorHandler.handleError(e);
+ }
+ else {
+ logger.error("Exception running embedded ZooKeeper", e);
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextConsumer.java b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextConsumer.java
new file mode 100644
index 0000000000..44f01b19f4
--- /dev/null
+++ b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextConsumer.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.dubbo.samples.rpccontext;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.samples.rpccontext.api.RpcContextService1;
+
+import org.apache.dubbo.samples.rpccontext.utils.RpcContextUtils;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+
+public class RpcContextConsumer {
+ public static void main(String[] args) {
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-rpccontext-consumer.xml");
+ context.start();
+ RpcContextService1 rpcContextService1 = context.getBean("consumerService", RpcContextService1.class);
+ rpcContextService1.sayHello();
+ }
+}
diff --git a/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextProvider1.java b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextProvider1.java
new file mode 100644
index 0000000000..8129e70011
--- /dev/null
+++ b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextProvider1.java
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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.dubbo.samples.rpccontext;
+
+import org.apache.dubbo.config.*;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.samples.rpccontext.api.RpcContextService1;
+import org.apache.dubbo.samples.rpccontext.impl.RpcContextImpl1;
+import org.apache.dubbo.samples.rpccontext.utils.RpcContextUtils;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+
+
+public class RpcContextProvider1 {
+ public static void main(String[] args) throws Exception {
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-rpccontext-provider1.xml");
+ context.start();
+ System.out.println("Rpc context provider1 started");
+ new CountDownLatch(1).await();
+ }
+}
diff --git a/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextProvider2.java b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextProvider2.java
new file mode 100644
index 0000000000..b0cc6360b7
--- /dev/null
+++ b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/RpcContextProvider2.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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.dubbo.samples.rpccontext;
+
+import org.apache.dubbo.config.*;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.samples.rpccontext.api.RpcContextService1;
+import org.apache.dubbo.samples.rpccontext.api.RpcContextService2;
+import org.apache.dubbo.samples.rpccontext.impl.RpcContextImpl1;
+import org.apache.dubbo.samples.rpccontext.impl.RpcContextImpl2;
+import org.apache.dubbo.samples.rpccontext.utils.RpcContextUtils;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+
+
+public class RpcContextProvider2 {
+ public static void main(String[] args) throws Exception {
+ new EmbeddedZooKeeper(2181, false).start();
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-rpccontext-provider2.xml");
+ context.start();
+ System.out.println("Rpc context provider2 started");
+ new CountDownLatch(1).await();
+ }
+}
diff --git a/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/api/RpcContextService1.java b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/api/RpcContextService1.java
new file mode 100644
index 0000000000..00dabe94f7
--- /dev/null
+++ b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/api/RpcContextService1.java
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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.dubbo.samples.rpccontext.api;
+
+
+import org.apache.dubbo.samples.rpccontext.dto.Service1DTO;
+
+public interface RpcContextService1 {
+ Service1DTO sayHello();
+}
diff --git a/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/api/RpcContextService2.java b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/api/RpcContextService2.java
new file mode 100644
index 0000000000..453f269911
--- /dev/null
+++ b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/api/RpcContextService2.java
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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.dubbo.samples.rpccontext.api;
+
+
+import org.apache.dubbo.samples.rpccontext.dto.Service2DTO;
+
+public interface RpcContextService2 {
+ Service2DTO sayHi();
+}
diff --git a/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/dto/Service1DTO.java b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/dto/Service1DTO.java
new file mode 100644
index 0000000000..e09b8e6b23
--- /dev/null
+++ b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/dto/Service1DTO.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.dubbo.samples.rpccontext.dto;
+
+import java.io.Serializable;
+
+public class Service1DTO implements Serializable {
+ private String consumerReq;
+ private String provider2Res;
+
+ private Service2DTO service2DTO;
+
+ public Service2DTO getService2DTO() {
+ return service2DTO;
+ }
+
+ public void setService2DTO(Service2DTO service2DTO) {
+ this.service2DTO = service2DTO;
+ }
+
+ public String getConsumerReq() {
+ return consumerReq;
+ }
+
+ public void setConsumerReq(String consumerReq) {
+ this.consumerReq = consumerReq;
+ }
+
+ public String getProvider2Res() {
+ return provider2Res;
+ }
+
+ public void setProvider2Res(String provider2Res) {
+ this.provider2Res = provider2Res;
+ }
+}
diff --git a/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/dto/Service2DTO.java b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/dto/Service2DTO.java
new file mode 100644
index 0000000000..954f093be5
--- /dev/null
+++ b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/dto/Service2DTO.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.dubbo.samples.rpccontext.dto;
+
+import java.io.Serializable;
+
+public class Service2DTO implements Serializable {
+ private String consumerReq;
+ private String provider1Req;
+
+ public String getConsumerReq() {
+ return consumerReq;
+ }
+
+ public void setConsumerReq(String consumerReq) {
+ this.consumerReq = consumerReq;
+ }
+
+ public String getProvider1Req() {
+ return provider1Req;
+ }
+
+ public void setProvider1Req(String provider1Req) {
+ this.provider1Req = provider1Req;
+ }
+}
diff --git a/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/impl/PenetrateAttachmentSelectorImpl1.java b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/impl/PenetrateAttachmentSelectorImpl1.java
new file mode 100644
index 0000000000..056c4c1259
--- /dev/null
+++ b/dubbo-samples-rpccontext/src/main/java/org/apache/dubbo/samples/rpccontext/impl/PenetrateAttachmentSelectorImpl1.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * 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.dubbo.samples.rpccontext.impl;
+
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.PenetrateAttachmentSelector;
+import org.apache.dubbo.rpc.RpcContextAttachment;
+
+import java.util.Map;
+
+public class PenetrateAttachmentSelectorImpl1 implements PenetrateAttachmentSelector {
+
+ @Override
+ public Map