You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by mi...@apache.org on 2019/02/25 13:32:32 UTC

[incubator-dubbo] branch 2.6.x updated: [Dubbo-2298] Add Annotation-Driven for MethodConfig and ArgumentConfig (#2603)

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

min pushed a commit to branch 2.6.x
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/2.6.x by this push:
     new c528d56  [Dubbo-2298] Add Annotation-Driven for MethodConfig and ArgumentConfig (#2603)
c528d56 is described below

commit c528d56b6e947fab85a6ec772ae50d0db2491cb2
Author: cvictory <sh...@gmail.com>
AuthorDate: Mon Feb 25 21:32:17 2019 +0800

    [Dubbo-2298] Add Annotation-Driven for MethodConfig and ArgumentConfig (#2603)
    
    * support methodConfig and argementConfig. fix #2298
    
    * unit test
    
    * unit test
    
    * remove unused
    
    * remove author
    
    * add licence
    
    * format the code
---
 .../com/alibaba/dubbo/config/AbstractConfig.java   |   9 +-
 .../com/alibaba/dubbo/config/ArgumentConfig.java   |  12 +-
 .../com/alibaba/dubbo/config/MethodConfig.java     |  36 ++-
 .../com/alibaba/dubbo/config/ReferenceConfig.java  |   1 +
 .../com/alibaba/dubbo/config/ServiceConfig.java    |   1 +
 .../alibaba/dubbo/config/annotation/Argument.java  |  81 ++++---
 .../alibaba/dubbo/config/annotation/Method.java    |  70 ++++++
 .../alibaba/dubbo/config/annotation/Reference.java |   6 +-
 .../alibaba/dubbo/config/annotation/Service.java   | 252 +++++++++++----------
 .../alibaba/dubbo/config/AbstractConfigTest.java   |  19 ++
 .../alibaba/dubbo/config/ArgumentConfigTest.java   |   1 +
 .../com/alibaba/dubbo/config/MethodConfigTest.java |  53 +++++
 .../alibaba/dubbo/config/ReferenceConfigTest.java  |  32 +++
 .../ReferenceAnnotationBeanPostProcessor.java      |   4 +-
 .../factory/annotation/ReferenceBeanBuilder.java   |  13 ++
 .../ServiceAnnotationBeanPostProcessor.java        |   8 +
 .../dubbo/config/spring/util/AnnotationUtils.java  |  16 +-
 .../annotation/action/AnnotationAction.java        |   3 +-
 18 files changed, 445 insertions(+), 172 deletions(-)

diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/AbstractConfig.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/AbstractConfig.java
index 1805e49..90279db 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/AbstractConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/AbstractConfig.java
@@ -423,7 +423,7 @@ public abstract class AbstractConfig implements Serializable {
                     }
                     String setter = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
                     Object value = method.invoke(annotation);
-                    if (value != null && !value.equals(method.getDefaultValue())) {
+                    if (!isAnnotationArray(method.getReturnType()) &&  value != null && !value.equals(method.getDefaultValue())) {
                         Class<?> parameterType = ReflectUtils.getBoxedClass(method.getReturnType());
                         if ("filter".equals(property) || "listener".equals(property)) {
                             parameterType = String.class;
@@ -446,6 +446,13 @@ public abstract class AbstractConfig implements Serializable {
         }
     }
 
+    boolean isAnnotationArray(Class target) {
+        if (target.isArray() && target.getComponentType().isAnnotation()) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public String toString() {
         try {
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ArgumentConfig.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ArgumentConfig.java
index e752726..e5f26d4 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ArgumentConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ArgumentConfig.java
@@ -16,6 +16,7 @@
  */
 package com.alibaba.dubbo.config;
 
+import com.alibaba.dubbo.config.annotation.Argument;
 import com.alibaba.dubbo.config.support.Parameter;
 
 import java.io.Serializable;
@@ -36,6 +37,15 @@ public class ArgumentConfig implements Serializable {
     //callback interface
     private Boolean callback;
 
+    public ArgumentConfig() {
+    }
+
+    public ArgumentConfig(Argument argument) {
+        this.index = argument.index();
+        this.type = argument.type();
+        this.callback = argument.callback();
+    }
+
     @Parameter(excluded = true)
     public Integer getIndex() {
         return index;
@@ -62,4 +72,4 @@ public class ArgumentConfig implements Serializable {
         return callback;
     }
 
-}
\ No newline at end of file
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/MethodConfig.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/MethodConfig.java
index 28230fd..7fa7140 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/MethodConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/MethodConfig.java
@@ -17,8 +17,11 @@
 package com.alibaba.dubbo.config;
 
 import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.config.annotation.Method;
 import com.alibaba.dubbo.config.support.Parameter;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -74,6 +77,37 @@ public class MethodConfig extends AbstractMethodConfig {
 
     private List<ArgumentConfig> arguments;
 
+    public MethodConfig() {
+    }
+
+    public MethodConfig(Method method) {
+        appendAnnotation(Method.class, method);
+        this.setReturn(method.isReturn());
+        this.setOninvoke(method.oninvoke());
+        this.setOnreturn(method.onreturn());
+        this.setOnthrow(method.onthrow());
+        if (method.arguments() != null && method.arguments().length != 0) {
+            List<ArgumentConfig> argumentConfigs = new ArrayList<ArgumentConfig>(method.arguments().length);
+            this.setArguments(argumentConfigs);
+            for (int i = 0; i < method.arguments().length; i++) {
+                ArgumentConfig argumentConfig = new ArgumentConfig(method.arguments()[i]);
+                argumentConfigs.add(argumentConfig);
+            }
+        }
+    }
+
+    public static List<MethodConfig> constructMethodConfig(Method[] methods) {
+        if (methods != null && methods.length != 0) {
+            List<MethodConfig> methodConfigs = new ArrayList<MethodConfig>(methods.length);
+            for (int i = 0; i < methods.length; i++) {
+                MethodConfig methodConfig = new MethodConfig(methods[i]);
+                methodConfigs.add(methodConfig);
+            }
+            return methodConfigs;
+        }
+        return Collections.emptyList();
+    }
+
     @Parameter(excluded = true)
     public String getName() {
         return name;
@@ -211,4 +245,4 @@ public class MethodConfig extends AbstractMethodConfig {
         this.isReturn = isReturn;
     }
 
-}
\ No newline at end of file
+}
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 c761d9c..adcff42 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
@@ -112,6 +112,7 @@ public class ReferenceConfig<T> extends AbstractReferenceConfig {
 
     public ReferenceConfig(Reference reference) {
         appendAnnotation(Reference.class, reference);
+        setMethods(MethodConfig.constructMethodConfig(reference.methods()));
     }
 
     private static void checkAndConvertImplicitConfig(MethodConfig method, Map<String, String> map, Map<Object, Object> attributes) {
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java
index c02a222..3f971df 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/ServiceConfig.java
@@ -101,6 +101,7 @@ public class ServiceConfig<T> extends AbstractServiceConfig {
 
     public ServiceConfig(Service service) {
         appendAnnotation(Service.class, service);
+        setMethods(MethodConfig.constructMethodConfig(service.methods()));
     }
 
     @Deprecated
diff --git a/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/annotation/action/AnnotationAction.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Argument.java
similarity index 56%
copy from dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/annotation/action/AnnotationAction.java
copy to dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Argument.java
index 7b40192..b5d51e5 100644
--- a/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/annotation/action/AnnotationAction.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Argument.java
@@ -1,37 +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 com.alibaba.dubbo.examples.annotation.action;
-
-import com.alibaba.dubbo.config.annotation.Reference;
-import com.alibaba.dubbo.examples.annotation.api.AnnotationService;
-
-import org.springframework.stereotype.Component;
-
-/**
- * AnnotationAction
- */
-@Component("annotationAction")
-public class AnnotationAction {
-
-    @Reference
-    private AnnotationService annotationService;
-
-    public String doSayHello(String name) {
-        return annotationService.sayHello(name);
-    }
-
-}
+/*
+ * 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 com.alibaba.dubbo.config.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @since 2.6.5
+ *
+ * 2018/9/29
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.ANNOTATION_TYPE})
+@Inherited
+public @interface Argument {
+    //argument: index -1 represents not set
+    int index() default -1;
+
+    //argument type
+    String type() default "";
+
+    //callback interface
+    boolean callback() default false;
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Method.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Method.java
new file mode 100644
index 0000000..6759d0e
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Method.java
@@ -0,0 +1,70 @@
+/*
+ * 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 com.alibaba.dubbo.config.annotation;
+
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @since 2.6.5
+ *  *
+ *  * 2018/9/29
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.ANNOTATION_TYPE})
+@Inherited
+public @interface Method {
+    String name();
+
+    int timeout() default -1;
+
+    int retries() default -1;
+
+    String loadbalance() default "";
+
+    boolean async() default false;
+
+    boolean sent() default true;
+
+    int actives() default 0;
+
+    int executes() default 0;
+
+    boolean deprecated() default false;
+
+    boolean sticky() default false;
+
+    boolean isReturn() default true;
+
+    String oninvoke() default "";
+
+    String onreturn() default "";
+
+    String onthrow() default "";
+
+    String cache() default "";
+
+    String validation() default "";
+
+    Argument[] arguments() default {};
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Reference.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Reference.java
index b3a93d7..b772ef0 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Reference.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Reference.java
@@ -118,6 +118,8 @@ public @interface Reference {
      * @return the default value is ""
      * @since 2.6.6
      */
-    String protocol() default "";
+    String protocol() default "";  
+  
+    Method[] methods() default {};
 
-}
+}
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Service.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Service.java
index 0f094f9..e6d0b09 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Service.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Service.java
@@ -1,125 +1,127 @@
-/*
- * 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 com.alibaba.dubbo.config.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Service
- *
- * @export
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE})
-@Inherited
-public @interface Service {
-
-    Class<?> interfaceClass() default void.class;
-
-    String interfaceName() default "";
-
-    String version() default "";
-
-    String group() default "";
-
-    String path() default "";
-
-    boolean export() default false;
-
-    String token() default "";
-
-    boolean deprecated() default false;
-
-    boolean dynamic() default false;
-
-    String accesslog() default "";
-
-    int executes() default 0;
-
-    boolean register() default true;
-
-    int weight() default 0;
-
-    String document() default "";
-
-    int delay() default 0;
-
-    String local() default "";
-
-    String stub() default "";
-
-    String cluster() default "";
-
-    String proxy() default "";
-
-    int connections() default 0;
-
-    int callbacks() default 0;
-
-    String onconnect() default "";
-
-    String ondisconnect() default "";
-
-    String owner() default "";
-
-    String layer() default "";
-
-    int retries() default 0;
-
-    String loadbalance() default "";
-
-    boolean async() default false;
-
-    int actives() default 0;
-
-    boolean sent() default false;
-
-    String mock() default "";
-
-    String validation() default "";
-
-    int timeout() default 0;
-
-    String cache() default "";
-
-    String[] filter() default {};
-
-    String[] listener() default {};
-
-    String[] parameters() default {};
-
-    String application() default "";
-
-    String module() default "";
-
-    String provider() default "";
-
-    String[] protocol() default {};
-
-    String monitor() default "";
-
-    String[] registry() default {};
-
-    String tag() default "";
-
-}
+/*
+ * 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 com.alibaba.dubbo.config.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Service
+ *
+ * @export
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Inherited
+public @interface Service {
+
+    Class<?> interfaceClass() default void.class;
+
+    String interfaceName() default "";
+
+    String version() default "";
+
+    String group() default "";
+
+    String path() default "";
+
+    boolean export() default false;
+
+    String token() default "";
+
+    boolean deprecated() default false;
+
+    boolean dynamic() default false;
+
+    String accesslog() default "";
+
+    int executes() default 0;
+
+    boolean register() default true;
+
+    int weight() default 0;
+
+    String document() default "";
+
+    int delay() default 0;
+
+    String local() default "";
+
+    String stub() default "";
+
+    String cluster() default "";
+
+    String proxy() default "";
+
+    int connections() default 0;
+
+    int callbacks() default 0;
+
+    String onconnect() default "";
+
+    String ondisconnect() default "";
+
+    String owner() default "";
+
+    String layer() default "";
+
+    int retries() default 0;
+
+    String loadbalance() default "";
+
+    boolean async() default false;
+
+    int actives() default 0;
+
+    boolean sent() default false;
+
+    String mock() default "";
+
+    String validation() default "";
+
+    int timeout() default 0;
+
+    String cache() default "";
+
+    String[] filter() default {};
+
+    String[] listener() default {};
+
+    String[] parameters() default {};
+
+    String application() default "";
+
+    String module() default "";
+
+    String provider() default "";
+
+    String[] protocol() default {};
+
+    String monitor() default "";
+
+    String[] registry() default {};
+
+    String tag() default "";
+
+    Method[] methods() default {};
+
+}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/AbstractConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/AbstractConfigTest.java
index 2dc595f..af29bb7 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/AbstractConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/AbstractConfigTest.java
@@ -475,6 +475,16 @@ public class AbstractConfigTest {
         String[] listener() default {};
 
         String[] parameters() default {};
+
+        ConfigField[] configFields() default {};
+
+        ConfigField configField() default @ConfigField;
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.ANNOTATION_TYPE})
+    public @interface ConfigField {
+        String value() default "";
     }
 
     private static class AnnotationConfig extends AbstractConfig {
@@ -482,6 +492,7 @@ public class AbstractConfigTest {
         private String filter;
         private String listener;
         private Map<String, String> parameters;
+        private String[] configFields;
 
         public Class getInterface() {
             return interfaceClass;
@@ -514,5 +525,13 @@ public class AbstractConfigTest {
         public void setParameters(Map<String, String> parameters) {
             this.parameters = parameters;
         }
+
+        public String[] getConfigFields() {
+            return configFields;
+        }
+
+        public void setConfigFields(String[] configFields) {
+            this.configFields = configFields;
+        }
     }
 }
diff --git a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/ArgumentConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/ArgumentConfigTest.java
index 4e1276f..3a6bc09 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/ArgumentConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/ArgumentConfigTest.java
@@ -17,6 +17,7 @@
 
 package com.alibaba.dubbo.config;
 
+import com.alibaba.dubbo.config.annotation.Argument;
 import org.junit.Test;
 
 import java.util.HashMap;
diff --git a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/MethodConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/MethodConfigTest.java
index d3ca181..3a82104 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/MethodConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/MethodConfigTest.java
@@ -18,11 +18,16 @@
 package com.alibaba.dubbo.config;
 
 import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.config.annotation.Argument;
+import com.alibaba.dubbo.config.annotation.Method;
+import com.alibaba.dubbo.config.annotation.Reference;
 import org.hamcrest.Matchers;
+import org.junit.Assert;
 import org.junit.Test;
 
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import static org.hamcrest.Matchers.contains;
@@ -34,6 +39,54 @@ import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertThat;
 
 public class MethodConfigTest {
+    private static final String METHOD_NAME = "sayHello";
+    private static final int TIMEOUT = 1300;
+    private static final int RETRIES = 4;
+    private static final String LOADBALANCE = "random";
+    private static final boolean ASYNC = true;
+    private static final int ACTIVES = 3;
+    private static final int EXECUTES = 5;
+    private static final boolean DEPERECATED = true;
+    private static final boolean STICKY = true;
+    private static final String ONINVOKE = "i";
+    private static final String ONTHROW = "t";
+    private static final String ONRETURN = "r";
+    private static final String CACHE = "c";
+    private static final String VALIDATION = "v";
+    private static final int ARGUMENTS_INDEX = 24;
+    private static final boolean ARGUMENTS_CALLBACK = true;
+    private static final String ARGUMENTS_TYPE = "sss";
+
+    @Reference(methods = {@Method(name = METHOD_NAME, timeout = TIMEOUT, retries = RETRIES, loadbalance = LOADBALANCE, async = ASYNC,
+            actives = ACTIVES, executes = EXECUTES, deprecated = DEPERECATED, sticky = STICKY, oninvoke = ONINVOKE, onthrow = ONTHROW, onreturn = ONRETURN, cache = CACHE, validation = VALIDATION,
+            arguments = {@Argument(index = ARGUMENTS_INDEX, callback = ARGUMENTS_CALLBACK, type = ARGUMENTS_TYPE)})})
+    private String testField;
+
+    @Test
+    public void testStaticConstructor() throws NoSuchFieldException {
+        Method[] methods = this.getClass().getDeclaredField("testField").getAnnotation(Reference.class).methods();
+        List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(methods);
+        MethodConfig methodConfig = methodConfigs.get(0);
+
+        Assert.assertEquals(METHOD_NAME, methodConfig.getName());
+        Assert.assertEquals(methodConfig.getTimeout().intValue(), TIMEOUT);
+        Assert.assertEquals(RETRIES, methodConfig.getRetries().intValue());
+        Assert.assertEquals(LOADBALANCE, methodConfig.getLoadbalance());
+        Assert.assertEquals(ASYNC, methodConfig.isAsync());
+        Assert.assertEquals(ACTIVES, methodConfig.getActives().intValue());
+        Assert.assertEquals(EXECUTES, methodConfig.getExecutes().intValue());
+        Assert.assertEquals(DEPERECATED, methodConfig.getDeprecated());
+        Assert.assertEquals(STICKY, methodConfig.getSticky());
+        Assert.assertEquals(ONINVOKE, methodConfig.getOninvoke());
+        Assert.assertEquals(ONTHROW, methodConfig.getOnthrow());
+        Assert.assertEquals(ONRETURN, methodConfig.getOnreturn());
+        Assert.assertEquals(CACHE, methodConfig.getCache());
+        Assert.assertEquals(VALIDATION, methodConfig.getValidation());
+        Assert.assertEquals(ARGUMENTS_INDEX, methodConfig.getArguments().get(0).getIndex().intValue());
+        Assert.assertEquals(ARGUMENTS_CALLBACK, methodConfig.getArguments().get(0).isCallback());
+        Assert.assertEquals(ARGUMENTS_TYPE, methodConfig.getArguments().get(0).getType());
+    }
+
     @Test
     public void testName() throws Exception {
         MethodConfig method = new MethodConfig();
diff --git a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/ReferenceConfigTest.java
index e20ee39..3f2ac9b 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/ReferenceConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/com/alibaba/dubbo/config/ReferenceConfigTest.java
@@ -17,6 +17,9 @@
 package com.alibaba.dubbo.config;
 
 import com.alibaba.dubbo.common.Constants;
+import com.alibaba.dubbo.config.annotation.Argument;
+import com.alibaba.dubbo.config.annotation.Method;
+import com.alibaba.dubbo.config.annotation.Reference;
 import com.alibaba.dubbo.config.api.DemoService;
 import com.alibaba.dubbo.config.provider.impl.DemoServiceImpl;
 
@@ -59,6 +62,35 @@ public class ReferenceConfigTest {
             demoService.unexport();
         }
     }
+
+    @Test
+    public void testConstructWithReferenceAnnotation() throws NoSuchFieldException {
+        Reference reference = getClass().getDeclaredField("innerTest").getAnnotation(Reference.class);
+        ReferenceConfig referenceConfig = new ReferenceConfig(reference);
+        Assert.assertTrue(referenceConfig.getMethods().size() == 1);
+        Assert.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getName(), "sayHello");
+        Assert.assertTrue(((MethodConfig) referenceConfig.getMethods().get(0)).getTimeout() == 1300);
+        Assert.assertTrue(((MethodConfig) referenceConfig.getMethods().get(0)).getRetries() == 4);
+        Assert.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getLoadbalance(), "random");
+        Assert.assertTrue(((MethodConfig) referenceConfig.getMethods().get(0)).getActives() == 3);
+        Assert.assertTrue(((MethodConfig) referenceConfig.getMethods().get(0)).getExecutes() == 5);
+        Assert.assertTrue(((MethodConfig) referenceConfig.getMethods().get(0)).isAsync());
+        Assert.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getOninvoke(), "i");
+        Assert.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getOnreturn(), "r");
+        Assert.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getOnthrow(), "t");
+        Assert.assertEquals(((MethodConfig) referenceConfig.getMethods().get(0)).getCache(), "c");
+    }
+
+
+    @Reference(methods = {@Method(name = "sayHello", timeout = 1300, retries = 4, loadbalance = "random", async = true,
+            actives = 3, executes = 5, deprecated = true, sticky = true, oninvoke = "i", onthrow = "t", onreturn = "r", cache = "c", validation = "v",
+            arguments = {@Argument(index = 24, callback = true, type = "sss")})})
+    private InnerTest innerTest;
+
+    private class InnerTest {
+
+    }
+
     /**
      * unit test for dubbo-1765
      */
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index e8be4c0..c7908cd 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -105,7 +105,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
     }
 
     @Override
-    protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType,
+                            protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType,
                                        InjectionMetadata.InjectedElement injectedElement) throws Exception {
 
         String referencedBeanName = buildReferencedBeanName(reference, injectedType);
@@ -263,4 +263,4 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
         this.injectedFieldReferenceBeanCache.clear();
         this.injectedMethodReferenceBeanCache.clear();
     }
-}
\ No newline at end of file
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
index 9b92d21..67bdca1 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
@@ -18,6 +18,8 @@ package com.alibaba.dubbo.config.spring.beans.factory.annotation;
 
 import com.alibaba.dubbo.common.utils.CollectionUtils;
 import com.alibaba.dubbo.config.ConsumerConfig;
+import com.alibaba.dubbo.config.MethodConfig;
+import com.alibaba.dubbo.config.annotation.Method;
 import com.alibaba.dubbo.config.annotation.Reference;
 import com.alibaba.dubbo.config.spring.ReferenceBean;
 
@@ -29,6 +31,7 @@ import org.springframework.util.StringUtils;
 import org.springframework.validation.DataBinder;
 
 import java.beans.PropertyEditorSupport;
+import java.util.List;
 import java.util.Map;
 
 import static com.alibaba.dubbo.config.spring.util.BeanFactoryUtils.getOptionalBean;
@@ -89,6 +92,14 @@ class ReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference
 
     }
 
+    void configureMethodConfig(Reference reference, ReferenceBean<?> referenceBean){
+        Method[] methods = reference.methods();
+        List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(methods);
+        if(!methodConfigs.isEmpty()){
+            referenceBean.setMethods(methodConfigs);
+        }
+    }
+
     @Override
     protected ReferenceBean doBuild() {
         return new ReferenceBean<Object>();
@@ -154,6 +165,8 @@ class ReferenceBeanBuilder extends AbstractAnnotationConfigBeanBuilder<Reference
 
         configureConsumerConfig(annotation, bean);
 
+        configureMethodConfig(annotation, bean);
+
         bean.afterPropertiesSet();
 
     }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
index 0c2fc64..457f355 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
@@ -18,6 +18,8 @@ package com.alibaba.dubbo.config.spring.beans.factory.annotation;
 
 import com.alibaba.dubbo.common.logger.Logger;
 import com.alibaba.dubbo.common.logger.LoggerFactory;
+import com.alibaba.dubbo.config.MethodConfig;
+import com.alibaba.dubbo.config.annotation.Method;
 import com.alibaba.dubbo.config.annotation.Service;
 import com.alibaba.dubbo.config.spring.ServiceBean;
 import com.alibaba.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
@@ -435,6 +437,12 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
             builder.addPropertyValue("protocols", protocolRuntimeBeanReferences);
         }
 
+        Method[] methods = service.methods();
+        List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(methods);
+        if(!methodConfigs.isEmpty()){
+            builder.addPropertyValue("methods", methodConfigs);
+        }
+
         return builder.getBeanDefinition();
 
     }
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java
index 703e649..fc6bf38 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/util/AnnotationUtils.java
@@ -92,8 +92,8 @@ public abstract class AnnotationUtils {
         return interfaceName;
 
     }
-
-
+  
+  
     // Cloned from https://github.com/alibaba/spring-context-support/blob/1.0.2/src/main/java/com/alibaba/spring/util/AnnotationUtils.java
 
     /**
@@ -258,6 +258,18 @@ public abstract class AnnotationUtils {
                 continue;
             }
 
+            /**
+             * @since 2.6.6
+             * ignore annotation member
+             */
+            if (attributeValue.getClass().isAnnotation()){
+                continue;
+            }
+            if (attributeValue.getClass().isArray() && attributeValue.getClass().getComponentType().isAnnotation()){
+                continue;
+            }
+          
+          
             if (attributeValue instanceof String) {
                 attributeValue = resolvePlaceholders(valueOf(attributeValue), propertyResolver);
             } else if (attributeValue instanceof String[]) {
diff --git a/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/annotation/action/AnnotationAction.java b/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/annotation/action/AnnotationAction.java
index 7b40192..f55642e 100644
--- a/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/annotation/action/AnnotationAction.java
+++ b/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/annotation/action/AnnotationAction.java
@@ -16,6 +16,7 @@
  */
 package com.alibaba.dubbo.examples.annotation.action;
 
+import com.alibaba.dubbo.config.annotation.Method;
 import com.alibaba.dubbo.config.annotation.Reference;
 import com.alibaba.dubbo.examples.annotation.api.AnnotationService;
 
@@ -27,7 +28,7 @@ import org.springframework.stereotype.Component;
 @Component("annotationAction")
 public class AnnotationAction {
 
-    @Reference
+    @Reference(methods = {@Method(name = "sayHello", timeout = 5000)})
     private AnnotationService annotationService;
 
     public String doSayHello(String name) {