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 2022/09/23 09:26:25 UTC

[servicecomb-java-chassis] branch master updated: [SCB-2424]RpcReference support setter injection (#3358)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new eb2961c6b [SCB-2424]RpcReference support setter injection (#3358)
eb2961c6b is described below

commit eb2961c6b4339c1c34622241cfb5f730fcd35a13
Author: liubao68 <bi...@qq.com>
AuthorDate: Fri Sep 23 17:26:18 2022 +0800

    [SCB-2424]RpcReference support setter injection (#3358)
---
 .../client/TestRpcReferenceMethodInjection.java    | 47 ++++++++++++++++++++++
 .../src/main/resources/microservice.yaml           |  4 +-
 .../servicecomb/provider/pojo/RpcReference.java    |  3 +-
 .../pojo/reference/RpcReferenceProcessor.java      | 35 +++++++++++++---
 4 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestRpcReferenceMethodInjection.java b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestRpcReferenceMethodInjection.java
new file mode 100644
index 000000000..92308e6b6
--- /dev/null
+++ b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/TestRpcReferenceMethodInjection.java
@@ -0,0 +1,47 @@
+/*
+ * 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.demo.pojo.client;
+
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.springframework.stereotype.Component;
+
+@Component
+public class TestRpcReferenceMethodInjection implements CategorizedTestCase {
+
+  private SchemeInterfacePojo pojo;
+
+  private SchemeInterfacePojo pojoValue;
+
+  @RpcReference(microserviceName = "pojo", schemaId = "SchemeInterfacePojoImpl")
+  public void setSchemeInterfacePojo(SchemeInterfacePojo pojo) {
+    this.pojo = pojo;
+  }
+
+  @RpcReference(microserviceName = "${servicecomb.provider.name}", schemaId = "SchemeInterfacePojoImpl")
+  public void setSchemeInterfacePojoValue(SchemeInterfacePojo pojoValue) {
+    this.pojoValue = pojoValue;
+  }
+
+  @Override
+  public void testAllTransport() throws Exception {
+    TestMgr.check(-1, pojo.reduce(1, 2));
+    TestMgr.check(-1, pojoValue.reduce(1, 2));
+  }
+}
diff --git a/demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml b/demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml
index 3f68ea60a..fea413156 100644
--- a/demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml
+++ b/demo/demo-pojo/pojo-client/src/main/resources/microservice.yaml
@@ -52,4 +52,6 @@ servicecomb:
           pojo:
             FlowControlClientSchema:
               foo: 3
-              bar: 3000
\ No newline at end of file
+              bar: 3000
+  provider:
+    name: pojo
\ No newline at end of file
diff --git a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/RpcReference.java b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/RpcReference.java
index 3a70176b3..a800b3f24 100644
--- a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/RpcReference.java
+++ b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/RpcReference.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.provider.pojo;
 
 import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
 import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import java.lang.annotation.Documented;
@@ -27,7 +28,7 @@ import java.lang.annotation.Target;
 
 @Documented
 @Retention(RUNTIME)
-@Target({FIELD, ANNOTATION_TYPE})
+@Target({FIELD, METHOD, ANNOTATION_TYPE})
 public @interface RpcReference {
   String microserviceName();
 
diff --git a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/reference/RpcReferenceProcessor.java b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/reference/RpcReferenceProcessor.java
index fb7482003..0663ac001 100644
--- a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/reference/RpcReferenceProcessor.java
+++ b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/reference/RpcReferenceProcessor.java
@@ -17,9 +17,11 @@
 package org.apache.servicecomb.provider.pojo.reference;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 
 import org.apache.servicecomb.provider.pojo.RpcReference;
 import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanCreationException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.context.EmbeddedValueResolverAware;
 import org.springframework.stereotype.Component;
@@ -34,7 +36,7 @@ public class RpcReferenceProcessor implements BeanPostProcessor, EmbeddedValueRe
   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
     // 扫描所有field,处理扩展的field标注
     ReflectionUtils.doWithFields(bean.getClass(), field -> processConsumerField(bean, field));
-
+    ReflectionUtils.doWithMethods(bean.getClass(), method -> processConsumerMethod(bean, beanName, method));
     return bean;
   }
 
@@ -43,6 +45,14 @@ public class RpcReferenceProcessor implements BeanPostProcessor, EmbeddedValueRe
     return bean;
   }
 
+  protected void processConsumerMethod(Object bean, String beanName, Method method) throws BeansException {
+    RpcReference reference = method.getAnnotation(RpcReference.class);
+    if (reference == null) {
+      return;
+    }
+    handleReferenceMethod(bean, beanName, method, reference);
+  }
+
   protected void processConsumerField(Object bean, Field field) {
     RpcReference reference = field.getAnnotation(RpcReference.class);
     if (reference == null) {
@@ -57,19 +67,32 @@ public class RpcReferenceProcessor implements BeanPostProcessor, EmbeddedValueRe
     this.resolver = resolver;
   }
 
+  private void handleReferenceMethod(Object bean, String beanName, Method method, RpcReference reference)
+      throws BeansException {
+    try {
+      PojoReferenceMeta pojoReference = createPojoReferenceMeta(reference, method.getParameterTypes()[0]);
+      method.invoke(bean, pojoReference.getProxy());
+    } catch (Exception e) {
+      throw new BeanCreationException(beanName, "", e);
+    }
+  }
+
   private void handleReferenceField(Object obj, Field field,
       RpcReference reference) {
+    PojoReferenceMeta pojoReference = createPojoReferenceMeta(reference, field.getType());
+    ReflectionUtils.makeAccessible(field);
+    ReflectionUtils.setField(field, obj, pojoReference.getProxy());
+  }
+
+  private PojoReferenceMeta createPojoReferenceMeta(RpcReference reference, Class<?> consumerInterface) {
     String microserviceName = reference.microserviceName();
     microserviceName = resolver.resolveStringValue(microserviceName);
 
     PojoReferenceMeta pojoReference = new PojoReferenceMeta();
     pojoReference.setMicroserviceName(microserviceName);
     pojoReference.setSchemaId(reference.schemaId());
-    pojoReference.setConsumerIntf(field.getType());
-
+    pojoReference.setConsumerIntf(consumerInterface);
     pojoReference.afterPropertiesSet();
-
-    ReflectionUtils.makeAccessible(field);
-    ReflectionUtils.setField(field, obj, pojoReference.getProxy());
+    return pojoReference;
   }
 }