You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2019/05/14 07:02:32 UTC

[servicecomb-java-chassis] 01/03: [SCB-1269][WIP][WEAK] swaggerProducer arguments not depend on swagger interface

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

liubao pushed a commit to branch weak-contract-type
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit 8bc9ed5bb3236eda8b8aeee0c757151ad235fec3
Author: wujimin <wu...@huawei.com>
AuthorDate: Thu Apr 25 10:55:20 2019 +0800

    [SCB-1269][WIP][WEAK] swaggerProducer arguments not depend on swagger interface
---
 .../swagger/engine/SwaggerEnvironment.java         | 67 +++++++--------
 .../swagger/engine/SwaggerProducer.java            | 17 +---
 .../swagger/engine/SwaggerProducerOperation.java   | 21 ++---
 .../swagger/invocation/SwaggerInvocation.java      |  5 ++
 ...pper.java => ContextArgumentMapperFactory.java} | 16 +---
 .../arguments/producer/ProducerArgumentSame.java   |  9 +--
 .../producer/ProducerArgumentsMapper.java          |  4 +-
 .../producer/ProducerArgumentsMapperCreator.java   | 94 ++++++++++++++++++++++
 .../producer/ProducerBeanParamMapper.java          | 55 +++++++------
 ...a => ProducerContextArgumentMapperFactory.java} | 14 +---
 .../producer/ProducerInvocationContextMapper.java  |  1 -
 .../ProducerInvocationContextMapperFactory.java    |  8 +-
 ...ava => SwaggerBodyFieldToProducerArgument.java} | 24 +++---
 ...s.producer.ProducerContextArgumentMapperFactory | 18 +++++
 14 files changed, 210 insertions(+), 143 deletions(-)

diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java
index 1b6b2b0..03cf6da 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java
@@ -25,6 +25,7 @@ import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.foundation.common.utils.BeanUtils;
 import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
 import org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;
 import org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;
 import org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;
@@ -32,7 +33,8 @@ import org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerArgu
 import org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerArgumentsMapperCreator;
 import org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerContextArgumentMapperFactory;
 import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapper;
-import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapperFactory;
+import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapperCreator;
+import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory;
 import org.apache.servicecomb.swagger.invocation.response.ResponseMapperFactorys;
 import org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;
 import org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapperFactory;
@@ -107,43 +109,50 @@ public class SwaggerEnvironment {
     return apiOperationAnnotation.nickname();
   }
 
-  public SwaggerProducer createProducer(Object producerInstance, Class<?> swaggerIntf,
-      Map<String, Operation> swaggerOperationMap) {
+  public SwaggerProducer createProducer(Object producerInstance, Swagger swagger) {
+    if (swagger == null) {
+      Class<?> producerCls = BeanUtils.getImplClassFromBean(producerInstance);
+      swagger = SwaggerGenerator.generate(producerCls);
+    }
+
+    Map<Class<?>, ContextArgumentMapperFactory> contextFactorys = SPIServiceUtils
+        .getOrLoadSortedService(ProducerContextArgumentMapperFactory.class)
+        .stream()
+        .collect(Collectors.toMap(ProducerContextArgumentMapperFactory::getContextClass, Function.identity()));
+    SwaggerOperations swaggerOperations = new SwaggerOperations(swagger);
+
     Class<?> producerCls = BeanUtils.getImplClassFromBean(producerInstance);
     Map<String, Method> visibleProducerMethods = retrieveVisibleMethods(producerCls);
 
     SwaggerProducer producer = new SwaggerProducer();
     producer.setProducerCls(producerCls);
-    producer.setSwaggerIntf(swaggerIntf);
-    for (Method swaggerMethod : swaggerIntf.getMethods()) {
-      String methodName = swaggerMethod.getName();
+    for (SwaggerOperation swaggerOperation : swaggerOperations.getOperations().values()) {
+      String operationId = swaggerOperation.getOperationId();
       // producer参数不一定等于swagger参数
-      Method producerMethod = visibleProducerMethods.getOrDefault(methodName, null);
+      Method producerMethod = visibleProducerMethods.getOrDefault(operationId, null);
       if (producerMethod == null) {
         // producer未实现契约,非法
-        String msg = String.format("swagger method %s not exist in producer %s.",
-            methodName,
+        String msg = String.format("operationId %s not exist in producer %s.",
+            operationId,
             producerInstance.getClass().getName());
-        throw new Error(msg);
+        throw new IllegalStateException(msg);
       }
 
-      ArgumentsMapperConfig config = new ArgumentsMapperConfig();
-      config.setSwaggerMethod(swaggerMethod);
-      config.setProviderMethod(producerMethod);
-      config.setSwaggerOperation(swaggerOperationMap.get(methodName));
-
-      ProducerArgumentsMapperFactory argumentsMapperFactory = selectProducerArgumentsMapperFactory(config);
-      ProducerArgumentsMapper argsMapper = argumentsMapperFactory.createArgumentsMapper(config);
+      ProducerArgumentsMapperCreator creator = new ProducerArgumentsMapperCreator(
+          Json.mapper().getSerializationConfig(),
+          contextFactorys,
+          producerMethod,
+          swaggerOperation);
+      ProducerArgumentsMapper argsMapper = creator.createArgumentsMapper();
       ProducerResponseMapper responseMapper = producerResponseMapperFactorys.createResponseMapper(
           swaggerMethod.getGenericReturnType(),
           producerMethod.getGenericReturnType());
 
       SwaggerProducerOperation op = new SwaggerProducerOperation();
-      op.setName(methodName);
       op.setProducerClass(producerCls);
       op.setProducerInstance(producerInstance);
       op.setProducerMethod(producerMethod);
-      op.setSwaggerMethod(swaggerMethod);
+      op.setSwaggerOperation(swaggerOperation);
       op.setArgumentsMapper(argsMapper);
       op.setResponseMapper(responseMapper);
 
@@ -153,24 +162,10 @@ public class SwaggerEnvironment {
     return producer;
   }
 
-  ProducerArgumentsMapperFactory selectProducerArgumentsMapperFactory(ArgumentsMapperConfig config) {
-    ProducerArgumentsMapperFactory argumentsMapperFactory = null;
-    for (ProducerArgumentsMapperFactory producerArgumentsMapperFactory : this.producerArgumentsMapperFactoryList) {
-      if (producerArgumentsMapperFactory.canProcess(config)) {
-        argumentsMapperFactory = producerArgumentsMapperFactory;
-        break;
-      }
-    }
-    if (null == argumentsMapperFactory) {
-      argumentsMapperFactory = this.producerArgumentsFactory;
-    }
-    return argumentsMapperFactory;
-  }
-
   private Map<String, Method> retrieveVisibleMethods(Class<?> clazz) {
     Map<String, Method> visibleMethods = new HashMap<>();
     for (Method method : clazz.getMethods()) {
-      String methodName = method.getName();
+      String operationId = method.getName();
       ApiOperation apiOperationAnnotation = method.getAnnotation(ApiOperation.class);
       if (apiOperationAnnotation != null) {
         if (apiOperationAnnotation.hidden()) {
@@ -178,11 +173,11 @@ public class SwaggerEnvironment {
         }
 
         if (StringUtils.isNotEmpty(apiOperationAnnotation.nickname())) {
-          methodName = apiOperationAnnotation.nickname();
+          operationId = apiOperationAnnotation.nickname();
         }
       }
 
-      visibleMethods.put(methodName, method);
+      visibleMethods.put(operationId, method);
     }
     return visibleMethods;
   }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducer.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducer.java
index d1e9eef..32968f2 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducer.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducer.java
@@ -23,8 +23,7 @@ import java.util.Map;
 public class SwaggerProducer {
   private Class<?> producerCls;
 
-  private Class<?> swaggerIntf;
-
+  // key is operationId
   private Map<String, SwaggerProducerOperation> opMap = new HashMap<>();
 
   public Class<?> getProducerCls() {
@@ -35,20 +34,12 @@ public class SwaggerProducer {
     this.producerCls = producerCls;
   }
 
-  public Class<?> getSwaggerIntf() {
-    return swaggerIntf;
-  }
-
-  public void setSwaggerIntf(Class<?> swaggerIntf) {
-    this.swaggerIntf = swaggerIntf;
-  }
-
   public void addOperation(SwaggerProducerOperation op) {
-    opMap.put(op.getName(), op);
+    opMap.put(op.getOperationId(), op);
   }
 
-  public SwaggerProducerOperation findOperation(String name) {
-    return opMap.get(name);
+  public SwaggerProducerOperation findOperation(String operationId) {
+    return opMap.get(operationId);
   }
 
   public Collection<SwaggerProducerOperation> getAllOperations() {
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
index cca21c5..f174415 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
@@ -24,6 +24,7 @@ import java.util.concurrent.CompletableFuture;
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+import org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
@@ -36,8 +37,6 @@ import org.apache.servicecomb.swagger.invocation.extension.ProducerInvokeExtensi
 import org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;
 
 public class SwaggerProducerOperation {
-  private String name;
-
   // 因为存在aop场景,所以,producerClass不一定等于producerInstance.getClass()
   private Class<?> producerClass;
 
@@ -45,7 +44,7 @@ public class SwaggerProducerOperation {
 
   private Method producerMethod;
 
-  private Method swaggerMethod;
+  private SwaggerOperation swaggerOperation;
 
   private ProducerArgumentsMapper argumentsMapper;
 
@@ -54,12 +53,8 @@ public class SwaggerProducerOperation {
   private List<ProducerInvokeExtension> producerInvokeExtenstionList =
       SPIServiceUtils.getSortedService(ProducerInvokeExtension.class);
 
-  public String getName() {
-    return name;
-  }
-
-  public void setName(String name) {
-    this.name = name;
+  public String getOperationId() {
+    return swaggerOperation.getOperationId();
   }
 
   public Class<?> getProducerClass() {
@@ -86,12 +81,8 @@ public class SwaggerProducerOperation {
     this.producerMethod = producerMethod;
   }
 
-  public Method getSwaggerMethod() {
-    return swaggerMethod;
-  }
-
-  public void setSwaggerMethod(Method swaggerMethod) {
-    this.swaggerMethod = swaggerMethod;
+  public void setSwaggerOperation(SwaggerOperation swaggerOperation) {
+    this.swaggerOperation = swaggerOperation;
   }
 
   public ProducerArgumentsMapper getArgumentsMapper() {
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
index e4c4cb6..5301868 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
@@ -24,6 +24,11 @@ public class SwaggerInvocation extends InvocationContext {
   // 本实例是在consumer端,还是在provider端
   protected InvocationType invocationType;
 
+  // highway consumer and all producer need arguments
+  // only springmvc consumer no arguments
+  //
+  // so only adapt springmvc consumer to arguments mode
+  // not adapt all to http mode
   protected Object[] swaggerArguments;
 
   protected InvocationContext parentContext;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ContextArgumentMapperFactory.java
similarity index 65%
copy from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java
copy to swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ContextArgumentMapperFactory.java
index 251e994..a0a33b1 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/ContextArgumentMapperFactory.java
@@ -15,18 +15,10 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.invocation.arguments.producer;
+package org.apache.servicecomb.swagger.invocation.arguments;
 
-import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
+public interface ContextArgumentMapperFactory {
+  Class<?> getContextClass();
 
-public class ProducerInvocationContextMapper extends AbstractProducerContextArgMapper {
-
-  public ProducerInvocationContextMapper(int producerIdx) {
-    super(producerIdx);
-  }
-
-  @Override
-  public Object createContextArg(SwaggerInvocation invocation) {
-    return invocation;
-  }
+  ArgumentMapper create(int argumentIdx);
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentSame.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentSame.java
index 84c6466..4d07b2e 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentSame.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentSame.java
@@ -19,25 +19,20 @@ package org.apache.servicecomb.swagger.invocation.arguments.producer;
 
 import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
 import org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;
-import org.apache.servicecomb.swagger.invocation.converter.Converter;
 
 public class ProducerArgumentSame implements ArgumentMapper {
   private int swaggerIdx;
 
   private int producerIdx;
 
-  private Converter converter;
-
-  public ProducerArgumentSame(int swaggerIdx, int producerIdx, Converter converter) {
+  public ProducerArgumentSame(int swaggerIdx, int producerIdx) {
     this.swaggerIdx = swaggerIdx;
     this.producerIdx = producerIdx;
-    this.converter = converter;
   }
 
   @Override
   public void mapArgument(SwaggerInvocation invocation, Object[] producerArguments) {
     Object swaggerParam = invocation.getSwaggerArgument(swaggerIdx);
-    Object producerParam = converter.convert(swaggerParam);
-    producerArguments[producerIdx] = producerParam;
+    producerArguments[producerIdx] = swaggerParam;
   }
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapper.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapper.java
index 0a2eb1a..1ca2971 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapper.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapper.java
@@ -23,9 +23,7 @@ import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
 import org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;
 
 /**
- * 将契约参数转为producer原型
- * 比如契约原型是         int add(int x, int y)
- * 而producer原型是int add(HttpRequest request, int x, int y)
+ * map swagger arguments to producer arguments
  */
 public class ProducerArgumentsMapper {
   private List<ArgumentMapper> producerArgMapperList;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperCreator.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperCreator.java
new file mode 100644
index 0000000..b964a39
--- /dev/null
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperCreator.java
@@ -0,0 +1,94 @@
+/*
+ * 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.servicecomb.swagger.invocation.arguments.producer;
+
+import static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.collectParameterName;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;
+import org.apache.servicecomb.foundation.common.utils.bean.Setter;
+import org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;
+import org.apache.servicecomb.swagger.invocation.arguments.AbstractArgumentsMapperCreator;
+import org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;
+import org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+public class ProducerArgumentsMapperCreator extends AbstractArgumentsMapperCreator {
+  public ProducerArgumentsMapperCreator(SerializationConfig serializationConfig,
+      Map<Class<?>, ContextArgumentMapperFactory> contextFactorys,
+      Method producerMethod, SwaggerOperation swaggerOperation) {
+    super(serializationConfig, contextFactorys, producerMethod, swaggerOperation);
+  }
+
+  public ProducerArgumentsMapper createArgumentsMapper() {
+    doCreateArgumentsMapper();
+
+    return new ProducerArgumentsMapper(mappers, providerMethod.getParameterCount());
+  }
+
+  @Override
+  protected void processUnknownParameter(String parameterName) {
+    throw new IllegalStateException(String
+        .format("failed to find producer parameter in contract, method=%s:%s, parameter name=%s.",
+            providerMethod.getDeclaringClass().getName(), providerMethod.getName(), parameterName));
+  }
+
+  @Override
+  protected ArgumentMapper createKnownParameterMapper(int producerParamIdx, Integer swaggerIdx) {
+    return new ProducerArgumentSame(producerParamIdx, swaggerIdx);
+  }
+
+  @Override
+  protected ArgumentMapper createSwaggerBodyFieldMapper(int producerParamIdx, String parameterName,
+      int swaggerBodyIdx) {
+    return new SwaggerBodyFieldToProducerArgument(producerParamIdx, parameterName, swaggerBodyIdx);
+  }
+
+  @Override
+  protected void processBeanParameter(int producerParamIdx, Parameter producerParameter) {
+    ProducerBeanParamMapper mapper = new ProducerBeanParamMapper(producerParamIdx, producerParameter.getType());
+    JavaType producerType = TypeFactory.defaultInstance().constructType(producerParameter.getParameterizedType());
+    for (BeanPropertyDefinition propertyDefinition : serializationConfig.introspect(producerType)
+        .findProperties()) {
+      String parameterName = collectParameterName(providerMethod, propertyDefinition);
+      Integer swaggerIdx = findAndClearSwaggerParameterIndex(parameterName);
+      if (swaggerIdx == null) {
+        throw new IllegalStateException(String
+            .format("failed to find producer parameter in contract, method=%s:%s, bean parameter name=%s.",
+                providerMethod.getDeclaringClass().getName(), providerMethod.getName(), parameterName));
+      }
+
+      Setter<Object, Object> setter;
+      if (propertyDefinition.hasSetter()) {
+        setter = LambdaMetafactoryUtils.createLambda(propertyDefinition.getSetter().getAnnotated(), Setter.class);
+      } else {
+        setter = LambdaMetafactoryUtils.createSetter(propertyDefinition.getField().getAnnotated());
+      }
+
+      mapper.addField(swaggerIdx, setter);
+    }
+    mappers.add(mapper);
+  }
+}
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerBeanParamMapper.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerBeanParamMapper.java
index b5c404b..bf92549 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerBeanParamMapper.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerBeanParamMapper.java
@@ -17,47 +17,52 @@
 
 package org.apache.servicecomb.swagger.invocation.arguments.producer;
 
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.apache.servicecomb.foundation.common.utils.bean.Setter;
 import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
 import org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;
-import org.apache.servicecomb.swagger.invocation.converter.Converter;
-import org.apache.servicecomb.swagger.invocation.converter.impl.ConverterCommon;
 
 public class ProducerBeanParamMapper implements ArgumentMapper {
+  private class FieldMeta {
+    int swaggerIdx;
+
+    Setter<Object, Object> setter;
+
+    public FieldMeta(int swaggerIdx, Setter<Object, Object> setter) {
+      this.swaggerIdx = swaggerIdx;
+      this.setter = setter;
+    }
+  }
 
   private int producerIdx;
 
-  private Map<String, Integer> swaggerParamIndexMap;
+  private final Class<?> producerParamType;
 
-  private Converter converter;
+  private List<FieldMeta> fields = new ArrayList<>();
 
-  /**
-   * @param producerNameToSwaggerIndexMap name of the fields and setters defined in @BeanParam parameter to swagger
-   * param index
-   * @param producerIdx index of producer param
-   * @param producerParamType type of producer param
-   */
-  public ProducerBeanParamMapper(Map<String, Integer> producerNameToSwaggerIndexMap, int producerIdx,
-      Type producerParamType) {
+  public ProducerBeanParamMapper(int producerIdx, Class<?> producerParamType) {
     this.producerIdx = producerIdx;
-    this.swaggerParamIndexMap = new HashMap<>();
-    this.swaggerParamIndexMap.putAll(producerNameToSwaggerIndexMap);
-    converter = new ConverterCommon(producerParamType);
+    this.producerParamType = producerParamType;
+  }
+
+  public void addField(int swaggerIdx, Setter<Object, Object> setter) {
+    fields.add(new FieldMeta(swaggerIdx, setter));
   }
 
   @Override
   public void mapArgument(SwaggerInvocation invocation, Object[] producerArguments) {
-    Map<String, Object> jsonMap = new HashMap<>(swaggerParamIndexMap.size());
+    try {
+      Object paramInstance = producerParamType.newInstance();
+      producerArguments[producerIdx] = paramInstance;
 
-    for (Entry<String, Integer> swaggerIndexEntry : swaggerParamIndexMap.entrySet()) {
-      jsonMap.put(swaggerIndexEntry.getKey(), invocation.getSwaggerArgument(swaggerIndexEntry.getValue()));
+      for (FieldMeta fieldMeta : fields) {
+        Object value = invocation.getSwaggerArgument(fieldMeta.swaggerIdx);
+        fieldMeta.setter.set(paramInstance, value);
+      }
+    } catch (Throwable e) {
+      throw new IllegalStateException("failed to map bean param.", e);
     }
-
-    final Object producerParam = converter.convert(jsonMap);
-    producerArguments[producerIdx] = producerParam;
   }
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerContextArgumentMapperFactory.java
similarity index 71%
copy from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java
copy to swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerContextArgumentMapperFactory.java
index 251e994..64e569f 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerContextArgumentMapperFactory.java
@@ -14,19 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.servicecomb.swagger.invocation.arguments.producer;
 
-import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
-
-public class ProducerInvocationContextMapper extends AbstractProducerContextArgMapper {
-
-  public ProducerInvocationContextMapper(int producerIdx) {
-    super(producerIdx);
-  }
+import org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;
 
-  @Override
-  public Object createContextArg(SwaggerInvocation invocation) {
-    return invocation;
-  }
+public interface ProducerContextArgumentMapperFactory extends ContextArgumentMapperFactory {
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java
index 251e994..658cda0 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapper.java
@@ -20,7 +20,6 @@ package org.apache.servicecomb.swagger.invocation.arguments.producer;
 import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
 
 public class ProducerInvocationContextMapper extends AbstractProducerContextArgMapper {
-
   public ProducerInvocationContextMapper(int producerIdx) {
     super(producerIdx);
   }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapperFactory.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapperFactory.java
index d370627..258ce65 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapperFactory.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerInvocationContextMapperFactory.java
@@ -18,15 +18,9 @@
 package org.apache.servicecomb.swagger.invocation.arguments.producer;
 
 import org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;
-import org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;
 import org.apache.servicecomb.swagger.invocation.context.InvocationContext;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-
-@Component
-@Qualifier("producer")
-public class ProducerInvocationContextMapperFactory implements ContextArgumentMapperFactory {
 
+public class ProducerInvocationContextMapperFactory implements ProducerContextArgumentMapperFactory {
   @Override
   public Class<?> getContextClass() {
     return InvocationContext.class;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentSame.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/SwaggerBodyFieldToProducerArgument.java
similarity index 65%
copy from swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentSame.java
copy to swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/SwaggerBodyFieldToProducerArgument.java
index 84c6466..474de65 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentSame.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/SwaggerBodyFieldToProducerArgument.java
@@ -17,27 +17,27 @@
 
 package org.apache.servicecomb.swagger.invocation.arguments.producer;
 
+import java.util.Map;
+
 import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
 import org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;
-import org.apache.servicecomb.swagger.invocation.converter.Converter;
 
-public class ProducerArgumentSame implements ArgumentMapper {
-  private int swaggerIdx;
+public class SwaggerBodyFieldToProducerArgument implements ArgumentMapper {
+  private final int producerParamIdx;
 
-  private int producerIdx;
+  private final String parameterName;
 
-  private Converter converter;
+  private final int swaggerBodyIdx;
 
-  public ProducerArgumentSame(int swaggerIdx, int producerIdx, Converter converter) {
-    this.swaggerIdx = swaggerIdx;
-    this.producerIdx = producerIdx;
-    this.converter = converter;
+  public SwaggerBodyFieldToProducerArgument(int producerParamIdx, String parameterName, int swaggerBodyIdx) {
+    this.producerParamIdx = producerParamIdx;
+    this.parameterName = parameterName;
+    this.swaggerBodyIdx = swaggerBodyIdx;
   }
 
   @Override
   public void mapArgument(SwaggerInvocation invocation, Object[] producerArguments) {
-    Object swaggerParam = invocation.getSwaggerArgument(swaggerIdx);
-    Object producerParam = converter.convert(swaggerParam);
-    producerArguments[producerIdx] = producerParam;
+    Map<String, Object> body = invocation.getSwaggerArgument(swaggerBodyIdx);
+    producerArguments[producerParamIdx] = body.get(parameterName);
   }
 }
diff --git a/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory b/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory
new file mode 100644
index 0000000..f1b9e50
--- /dev/null
+++ b/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerContextArgumentMapperFactory
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerInvocationContextMapperFactory
\ No newline at end of file