dubbo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From GitBox <...@apache.org>
Subject [GitHub] beiwei30 closed pull request #1511: Add feature:require Reference service dynamically
Date Sun, 08 Apr 2018 07:53:28 GMT
beiwei30 closed pull request #1511: Add feature:require Reference service dynamically
URL: https://github.com/apache/incubator-dubbo/pull/1511
 
 
   

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/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/RefConf.java
b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/RefConf.java
new file mode 100644
index 0000000000..6f78245775
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/RefConf.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 1999-2012 Alibaba Group.
+ *  
+ * Licensed 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 com.alibaba.dubbo.config;
+
+/**
+ * Reference  注解对应的实体配置类
+ * 
+ * @author zhouzhipeng
+ */
+public class RefConf {
+
+   public Class<?> interfaceClass = void.class;
+
+   public String interfaceName = "";
+
+   public String version = "";
+
+   public String group = "";
+
+   public String url = "";
+
+   public String client = "";
+
+   public boolean generic = false;
+
+   public boolean injvm = false;
+
+   public boolean check = true;
+
+   public boolean init = false;
+
+   public boolean lazy = false;
+
+   public boolean stubevent = false;
+
+   public String reconnect = "";
+
+   public boolean sticky = false;
+
+   public String proxy = "";
+
+   public String stub = "";
+
+   public String cluster = "";
+
+   public int connections = 0;
+
+   public int callbacks = 0;
+
+   public String onconnect = "";
+
+   public String ondisconnect = "";
+
+   public String owner = "";
+
+   public String layer = "";
+
+   public int retries = 0;
+
+   public String loadbalance = "";
+
+   public boolean async = false;
+
+   public int actives = 0;
+
+   public boolean sent = false;
+
+   public String mock = "";
+
+   public String validation = "";
+
+   public int timeout = 0;
+
+   public String cache = "";
+
+   public String[] filter = {};
+
+   public String[] listener = {};
+
+   public String[] parameters = {};
+
+   public String application = "";
+
+   public String module = "";
+
+   public String consumer = "";
+
+   public String monitor = "";
+
+   public String protocol = "";
+
+   public String[] registry = {};
+
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ReferenceConfig.java
b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ReferenceConfig.java
index 1cb58ae28d..f0c734763d 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ReferenceConfig.java
@@ -21,10 +21,7 @@
 import com.alibaba.dubbo.common.Version;
 import com.alibaba.dubbo.common.bytecode.Wrapper;
 import com.alibaba.dubbo.common.extension.ExtensionLoader;
-import com.alibaba.dubbo.common.utils.ConfigUtils;
-import com.alibaba.dubbo.common.utils.NetUtils;
-import com.alibaba.dubbo.common.utils.ReflectUtils;
-import com.alibaba.dubbo.common.utils.StringUtils;
+import com.alibaba.dubbo.common.utils.*;
 import com.alibaba.dubbo.config.annotation.Reference;
 import com.alibaba.dubbo.config.model.ApplicationModel;
 import com.alibaba.dubbo.config.model.ConsumerModel;
@@ -44,7 +41,9 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -114,6 +113,46 @@ public ReferenceConfig(Reference reference) {
         appendAnnotation(Reference.class, reference);
     }
 
+
+    /**
+     * 新增构造函数,支持RefConf配置实体类
+     * @param referenceConf
+     */
+    public ReferenceConfig(RefConf referenceConf) {
+        Field[] fields = referenceConf.getClass().getFields();
+        for (Field field : fields) {
+            if (field.getType() != void.class
+                    && ! Modifier.isStatic(field.getModifiers())) {
+                try {
+                    String property = field.getName();
+                    if ("interfaceClass".equals(property) || "interfaceName".equals(property))
{
+                        property = "interface";
+                    }
+                    String setter = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
+                    Object value = field.get(referenceConf);
+                    if (value != null && ! (value instanceof Class && ((Class)
value).getName().equals("void")) ) {
+                        Class<?> parameterType = ReflectUtils.getBoxedClass(field.getType());
+                        if ("filter".equals(property) || "listener".equals(property)) {
+                            parameterType = String.class;
+                            value = StringUtils.join((String[]) value, ",");
+                        } else if ("parameters".equals(property)) {
+                            parameterType = Map.class;
+                            value = CollectionUtils.toStringMap((String[]) value);
+                        }
+                        try {
+                            Method setterMethod = getClass().getMethod(setter, new Class<?>[]
{ parameterType });
+                            setterMethod.invoke(this, new Object[] { value });
+                        } catch (NoSuchMethodException e) {
+                            // ignore
+                        }
+                    }
+                } catch (Throwable e) {
+                    logger.error(e.getMessage(), e);
+                }
+            }
+        }
+    }
+
     private static void checkAndConvertImplicitConfig(MethodConfig method, Map<String,
String> map, Map<Object, Object> attributes) {
         //check config conflict
         if (Boolean.FALSE.equals(method.isReturn()) && (method.getOnreturn() != null
|| method.getOnthrow() != null)) {
@@ -183,7 +222,8 @@ public synchronized void destroy() {
     }
 
     private void init() {
-        if (initialized) {
+        //附加判断 ref !=null : 防止ReferenceConfig动态创建时可能无效问题
+        if (initialized && ref!=null) {
             return;
         }
         initialized = true;
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java
b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java
index 93168d0893..d831ae6c6b 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/AnnotationBean.java
@@ -34,6 +34,7 @@
 import org.springframework.context.ApplicationContextAware;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
@@ -96,6 +97,14 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
                 // spring 2.0
             }
         }
+
+
+        //
+        if(!beanFactory.containsBean(DynamicReferenceService.class.getName())) {
+            //注册服务bean
+            beanFactory.registerSingleton(DynamicReferenceService.class.getName(), new DynamicReferenceService(this));
+        }
+
     }
 
     public void destroy() throws Exception {
@@ -229,50 +238,78 @@ public Object postProcessBeforeInitialization(Object bean, String beanName)
     }
 
     private Object refer(Reference reference, Class<?> referenceClass) { //method.getParameterTypes()[0]
+        RefConf refConf=new RefConf();
+
+        //将注解类reference上的属性复制到refConf
+        for(Field field:refConf.getClass().getFields()){
+            for(Method method:reference.getClass().getMethods()){
+                if(method.getName().equals(field.getName())){
+                    try {
+                        field.set(refConf,method.invoke(reference));
+                    } catch (IllegalAccessException e) {
+                        logger.error("error @Reference or RefConf definition");
+                    } catch (InvocationTargetException e) {
+                        logger.error("error @Reference or RefConf definition");
+                    }
+                }
+            }
+        }
+
+        return referNew(refConf,referenceClass);
+    }
+
+    /**
+     * refer 方法的公开版,将注解参数Reference换为 RefConf 类
+     * @param reference
+     * @param referenceClass
+     * @return
+     */
+    public Object referNew(RefConf reference, Class<?> referenceClass) { //method.getParameterTypes()[0]
         String interfaceName;
-        if (!"".equals(reference.interfaceName())) {
-            interfaceName = reference.interfaceName();
-        } else if (!void.class.equals(reference.interfaceClass())) {
-            interfaceName = reference.interfaceClass().getName();
+
+        if (! "".equals( reference.interfaceName)) {
+            interfaceName =  reference.interfaceName;
+        } else if (! void.class.equals( reference.interfaceClass)) {
+            interfaceName =  reference.interfaceClass.getName();
         } else if (referenceClass.isInterface()) {
             interfaceName = referenceClass.getName();
         } else {
             throw new IllegalStateException("The @Reference undefined interfaceClass or interfaceName,
and the property type " + referenceClass.getName() + " is not a interface.");
         }
-        String key = reference.group() + "/" + interfaceName + ":" + reference.version();
+        String key =  reference.group + "/" + interfaceName + ":" +  reference.version;
         ReferenceBean<?> referenceConfig = referenceConfigs.get(key);
         if (referenceConfig == null) {
             referenceConfig = new ReferenceBean<Object>(reference);
-            if (void.class.equals(reference.interfaceClass())
-                    && "".equals(reference.interfaceName())
+            if (void.class.equals( reference.interfaceClass)
+                    && "".equals( reference.interfaceName)
                     && referenceClass.isInterface()) {
                 referenceConfig.setInterface(referenceClass);
             }
             if (applicationContext != null) {
                 referenceConfig.setApplicationContext(applicationContext);
-                if (reference.registry() != null && reference.registry().length >
0) {
+                if ( reference.registry != null &&  reference.registry.length >
0) {
                     List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
-                    for (String registryId : reference.registry()) {
+                    for (String registryId :  reference.registry) {
                         if (registryId != null && registryId.length() > 0) {
-                            registryConfigs.add((RegistryConfig) applicationContext.getBean(registryId,
RegistryConfig.class));
+                            registryConfigs.add((RegistryConfig)applicationContext.getBean(registryId,
RegistryConfig.class));
                         }
                     }
                     referenceConfig.setRegistries(registryConfigs);
                 }
-                if (reference.consumer() != null && reference.consumer().length()
> 0) {
-                    referenceConfig.setConsumer((ConsumerConfig) applicationContext.getBean(reference.consumer(),
ConsumerConfig.class));
+                if ( reference.consumer != null &&  reference.consumer.length() >
0) {
+                    referenceConfig.setConsumer((ConsumerConfig)applicationContext.getBean(
reference.consumer, ConsumerConfig.class));
                 }
-                if (reference.monitor() != null && reference.monitor().length() >
0) {
-                    referenceConfig.setMonitor((MonitorConfig) applicationContext.getBean(reference.monitor(),
MonitorConfig.class));
+                if ( reference.monitor != null &&  reference.monitor.length() >
0) {
+                    referenceConfig.setMonitor((MonitorConfig)applicationContext.getBean(
reference.monitor, MonitorConfig.class));
                 }
-                if (reference.application() != null && reference.application().length()
> 0) {
-                    referenceConfig.setApplication((ApplicationConfig) applicationContext.getBean(reference.application(),
ApplicationConfig.class));
+                if ( reference.application != null &&  reference.application.length()
> 0) {
+                    referenceConfig.setApplication((ApplicationConfig)applicationContext.getBean(
reference.application, ApplicationConfig.class));
                 }
-                if (reference.module() != null && reference.module().length() >
0) {
-                    referenceConfig.setModule((ModuleConfig) applicationContext.getBean(reference.module(),
ModuleConfig.class));
+                if ( reference.module != null &&  reference.module.length() >
0) {
+                    referenceConfig.setModule((ModuleConfig)applicationContext.getBean( reference.module,
ModuleConfig.class));
                 }
-                if (reference.consumer() != null && reference.consumer().length()
> 0) {
-                    referenceConfig.setConsumer((ConsumerConfig) applicationContext.getBean(reference.consumer(),
ConsumerConfig.class));
+                if ( reference.consumer != null &&  reference.consumer.length() >
0) {
+                    referenceConfig.setConsumer((ConsumerConfig)applicationContext.getBean(
reference.consumer, ConsumerConfig.class));
                 }
                 try {
                     referenceConfig.afterPropertiesSet();
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/DynamicReferenceService.java
b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/DynamicReferenceService.java
new file mode 100644
index 0000000000..4ba6c93211
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/DynamicReferenceService.java
@@ -0,0 +1,29 @@
+package com.alibaba.dubbo.config.spring;
+
+import com.alibaba.dubbo.config.RefConf;
+
+/**
+ * 动态reference服务
+ * User: zhouzhipeng
+ * Date: 2018/3/21:22:34
+ */
+public class DynamicReferenceService {
+
+    private AnnotationBean annotationBean;
+
+    private DynamicReferenceService() {
+    }
+
+    DynamicReferenceService(AnnotationBean annotationBean) {
+        this.annotationBean = annotationBean;
+    }
+
+    public <T> T getDubboService(Class<T> interfaceClass) {
+        return (T) annotationBean.referNew(new RefConf(), interfaceClass);
+    }
+
+    public <T> T getDubboService(Class<T> interfaceClass, RefConf referenceConf)
{
+        return (T) annotationBean.referNew(referenceConf, interfaceClass);
+    }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ReferenceBean.java
b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ReferenceBean.java
index f3aa9b0249..662209c09d 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ReferenceBean.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ReferenceBean.java
@@ -16,12 +16,7 @@
  */
 package com.alibaba.dubbo.config.spring;
 
-import com.alibaba.dubbo.config.ApplicationConfig;
-import com.alibaba.dubbo.config.ConsumerConfig;
-import com.alibaba.dubbo.config.ModuleConfig;
-import com.alibaba.dubbo.config.MonitorConfig;
-import com.alibaba.dubbo.config.ReferenceConfig;
-import com.alibaba.dubbo.config.RegistryConfig;
+import com.alibaba.dubbo.config.*;
 import com.alibaba.dubbo.config.annotation.Reference;
 import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
 import com.alibaba.dubbo.config.support.Parameter;
@@ -56,6 +51,16 @@ public ReferenceBean(Reference reference) {
         super(reference);
     }
 
+    /**
+     * 增加构造函数,支持 RefConf 配置
+     * @param reference
+     */
+    public ReferenceBean(RefConf reference) {
+        super(reference);
+    }
+
+
+
     public void setApplicationContext(ApplicationContext applicationContext) {
         this.applicationContext = applicationContext;
         SpringExtensionFactory.addApplicationContext(applicationContext);


 

----------------------------------------------------------------
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:
users@infra.apache.org


With regards,
Apache Git Services

Mime
View raw message