diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java
index a945909edf..905abe718c 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboService.java
@@ -257,7 +257,17 @@ public @interface DubboService {
String[] listener() default {};
/**
- * Customized parameter key-value pair, for example: {key1, value1, key2, value2}
+ * Customized parameter key-value pair, for example:
+ *
+ * ["a","b"] ==> {a=b}
+ * [" a "," b "] ==> {a=b}
+ * ["a=b"] ==>{a=b}
+ * ["a:b"] ==>{a=b}
+ * ["a=b","c","d"] ==>{a=b,c=d}
+ * ["a","a:b"] ==>{a="a:b"}
+ * ["a","a,b"] ==>{a="a,b"}
+ *
+ * @see org.apache.dubbo.config.spring.util.DubboAnnotationUtils#convertParameters(java.lang.String[])
*/
String[] parameters() default {};
@@ -327,4 +337,21 @@ public @interface DubboService {
* Payload max length.
*/
String payload() default "";
+
+ /**
+ * The serialization type
+ */
+ String serialization() default "";
+
+ /**
+ * If the parameter has a value, the consumer will read the parameter first.
+ * If the Dubbo Sdk you are using contains the serialization type, the serialization method specified by the argument is used.
+ *
+ * When this parameter is null or the serialization type specified by this parameter does not exist in the Dubbo SDK, the serialization type specified by serialization is used.
+ * If the Dubbo SDK if still does not exist, the default type of the Dubbo SDK is used.
+ * For Dubbo SDK >= 3.2, preferSerialization takes precedence over serialization
+ *
+ * The configuration supports multiple, which are separated by commas.Such as:fastjson2,fastjson,hessian2
+ */
+ String preferSerialization() default "";
}
diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml
index e0be936386..63ed7f1e4d 100644
--- a/dubbo-config/dubbo-config-api/pom.xml
+++ b/dubbo-config/dubbo-config-api/pom.xml
@@ -135,6 +135,13 @@
test
+
+ org.apache.dubbo
+ dubbo-serialization-jdk
+ ${project.parent.version}
+ test
+
+
org.apache.dubbo
dubbo-registry-multicast
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java
index a37044cdca..728aa21845 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java
@@ -132,6 +132,7 @@ import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
import static org.apache.dubbo.remoting.Constants.DISPATCHER_KEY;
import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
+import static org.apache.dubbo.remoting.Constants.PREFER_SERIALIZATION_KEY;
import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
import static org.apache.dubbo.remoting.Constants.TELNET_KEY;
@@ -602,6 +603,11 @@ public class ConfigValidationUtils {
checkMultiExtension(config.getScopeModel(), Codec2.class, CODEC_KEY, config.getCodec());
checkMultiExtension(
config.getScopeModel(), Serialization.class, SERIALIZATION_KEY, config.getSerialization());
+ checkMultiExtension(
+ config.getScopeModel(),
+ Serialization.class,
+ PREFER_SERIALIZATION_KEY,
+ config.getPreferSerialization());
checkMultiExtension(config.getScopeModel(), Transporter.class, SERVER_KEY, config.getServer());
checkMultiExtension(config.getScopeModel(), Transporter.class, CLIENT_KEY, config.getClient());
}
@@ -623,6 +629,9 @@ public class ConfigValidationUtils {
checkMultiExtension(config.getScopeModel(), StatusChecker.class, STATUS_KEY, config.getStatus());
checkExtension(config.getScopeModel(), Transporter.class, TRANSPORTER_KEY, config.getTransporter());
checkExtension(config.getScopeModel(), Exchanger.class, EXCHANGER_KEY, config.getExchanger());
+ checkMultiExtension(config.getScopeModel(), Serialization.class, SERIALIZATION_KEY, config.getSerialization());
+ checkMultiExtension(
+ config.getScopeModel(), Serialization.class, PREFER_SERIALIZATION_KEY, config.getPreferSerialization());
}
public static void validateConsumerConfig(ConsumerConfig config) {
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
index edaa1955b4..963e44eb28 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
@@ -70,6 +70,31 @@ class AbstractConfigTest {
ConfigValidationUtils.validateProtocolConfig(protocolConfig);
}
+ @Test
+ void testValidateProtocolConfigSerialization() {
+ ProtocolConfig protocolConfig = new ProtocolConfig();
+ protocolConfig.setCodec("exchange");
+ protocolConfig.setName("dubbo");
+ protocolConfig.setHost("host");
+ protocolConfig.setSerialization("fastjson2");
+ protocolConfig.setPreferSerialization("hessian2,java,compactedjava,nativejava");
+ ConfigValidationUtils.validateProtocolConfig(protocolConfig);
+ }
+
+ @Test
+ void testValidateProtocolConfigViolateSerialization() {
+
+ Assertions.assertThrowsExactly(IllegalStateException.class, () -> {
+ ProtocolConfig protocolConfig = new ProtocolConfig();
+ protocolConfig.setCodec("exchange");
+ protocolConfig.setName("dubbo");
+ protocolConfig.setHost("host");
+ protocolConfig.setSerialization("violate");
+ protocolConfig.setPreferSerialization("violate");
+ ConfigValidationUtils.validateProtocolConfig(protocolConfig);
+ });
+ }
+
@Test
void testAppendParameters1() {
Map parameters = new HashMap();
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
index fe791af7c0..df8a81224c 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
@@ -316,21 +316,6 @@ class DubboBootstrapTest {
registryConfig.setUseAsMetadataCenter(false);
registryConfig.setUseAsConfigCenter(false);
- Exception exception = null;
- try {
- DubboBootstrap.getInstance()
- .application(applicationConfig)
- .registry(registryConfig)
- .protocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, -1))
- .service(service)
- .start();
- } catch (Exception e) {
- exception = e;
- DubboBootstrap.reset();
- }
-
- Assertions.assertNotNull(exception);
-
DubboBootstrap.getInstance()
.application(applicationConfig)
.registry(registryConfig)
@@ -342,6 +327,33 @@ class DubboBootstrapTest {
assertMetadataService(DubboBootstrap.getInstance(), availablePort, false);
}
+ @Test
+ void testRemoteMetadataServiceExporterCheckMetadataType() {
+
+ Assertions.assertThrowsExactly(IllegalStateException.class, () -> {
+ ServiceConfig service = new ServiceConfig<>();
+ service.setInterface(DemoService.class);
+ service.setRef(new DemoServiceImpl());
+
+ int availablePort = NetUtils.getAvailablePort();
+
+ ApplicationConfig applicationConfig = new ApplicationConfig("bootstrap-test");
+ applicationConfig.setMetadataServicePort(availablePort);
+ applicationConfig.setMetadataType(REMOTE_METADATA_STORAGE_TYPE);
+
+ RegistryConfig registryConfig = new RegistryConfig(zkServerAddress);
+ registryConfig.setUseAsMetadataCenter(false);
+ registryConfig.setUseAsConfigCenter(false);
+
+ DubboBootstrap.getInstance()
+ .application(applicationConfig)
+ .registry(registryConfig)
+ .protocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, -1))
+ .service(service)
+ .start();
+ });
+ }
+
private ExporterDeployListener getListener(ApplicationModel model) {
return (ExporterDeployListener)
model.getExtensionLoader(ApplicationDeployListener.class).getExtension("exporter");
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java
index 08a46a67f4..a255c1042f 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java
@@ -138,7 +138,7 @@ public class DubboAnnotationUtils {
* be split in anytime.It will throw IllegalArgumentException If converted array length isn't
* even number.
* The convert cases below work in right way,which are best practice.
- *
+ *
* (array->map)
* ["a","b"] ==> {a=b}
* [" a "," b "] ==> {a=b}
@@ -147,7 +147,7 @@ public class DubboAnnotationUtils {
* ["a=b","c","d"] ==>{a=b,c=d}
* ["a","a:b"] ==>{a="a:b"}
* ["a","a,b"] ==>{a="a,b"}
- *
+ *
*
* @param parameters
* @return