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 1805e49370b..90279dbf48e 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 @@ protected void appendAnnotation(Class annotationClass, Object annotation) { } 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 @@ protected void appendAnnotation(Class annotationClass, Object annotation) { } } + 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 e752726a0ca..e5f26d4e495 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 Boolean isCallback() { 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 28230fd9e49..7fa7140e3e2 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 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 argumentConfigs = new ArrayList(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 constructMethodConfig(Method[] methods) { + if (methods != null && methods.length != 0) { + List methodConfigs = new ArrayList(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 void setReturn(Boolean isReturn) { 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 c761d9c5d6c..adcff42a4c4 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 ReferenceConfig() { public ReferenceConfig(Reference reference) { appendAnnotation(Reference.class, reference); + setMethods(MethodConfig.constructMethodConfig(reference.methods())); } private static void checkAndConvertImplicitConfig(MethodConfig method, Map map, Map 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 c02a222afe4..3f971dfa218 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 ServiceConfig() { public ServiceConfig(Service service) { appendAnnotation(Service.class, service); + setMethods(MethodConfig.constructMethodConfig(service.methods())); } @Deprecated diff --git a/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Argument.java b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Argument.java new file mode 100644 index 00000000000..b5d51e5a0d7 --- /dev/null +++ b/dubbo-config/dubbo-config-api/src/main/java/com/alibaba/dubbo/config/annotation/Argument.java @@ -0,0 +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.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 00000000000..6759d0ee85f --- /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 b3a93d7b72d..b772ef0ea2a 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 @@ * @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 0f094f98076..e6d0b09819f 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 2dc595fc597..af29bb72b72 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 void setFlag(byte flag) { 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 @@ private static class AnnotationConfig extends AbstractConfig { private String filter; private String listener; private Map parameters; + private String[] configFields; public Class getInterface() { return interfaceClass; @@ -514,5 +525,13 @@ public Map getParameters() { public void setParameters(Map 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 4e1276f3a51..3a6bc09545b 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 d3ca1814657..3a8210487bd 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.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 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 e20ee390d6f..3f2ac9b07c3 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 void testInjvm() throws Exception { 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 e8be4c0decb..c7908cd7b66 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 Map> getInjectedMetho } @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 void destroy() throws Exception { 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 9b92d214169..67bdca1e533 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 @@ 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.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 @@ private void configureConsumerConfig(Reference reference, ReferenceBean refer } + void configureMethodConfig(Reference reference, ReferenceBean referenceBean){ + Method[] methods = reference.methods(); + List methodConfigs = MethodConfig.constructMethodConfig(methods); + if(!methodConfigs.isEmpty()){ + referenceBean.setMethods(methodConfigs); + } + } + @Override protected ReferenceBean doBuild() { return new ReferenceBean(); @@ -154,6 +165,8 @@ protected void postConfigureBean(Reference annotation, ReferenceBean bean) throw 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 0c2fc64406c..457f35567fe 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 @@ 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 @@ private AbstractBeanDefinition buildServiceBeanDefinition(Service service, Class builder.addPropertyValue("protocols", protocolRuntimeBeanReferences); } + Method[] methods = service.methods(); + List 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 703e649ad23..fc6bf38d79e 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 static String resolveInterfaceName(Reference reference, Class defaultI 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 static Map getAttributes(Annotation annotation, PropertyR 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 7b401923a1a..f55642eb66b 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 @@ @Component("annotationAction") public class AnnotationAction { - @Reference + @Reference(methods = {@Method(name = "sayHello", timeout = 5000)}) private AnnotationService annotationService; public String doSayHello(String name) {