diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java index a4c05c3abc8..389515d1f1d 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java @@ -17,7 +17,12 @@ package com.alibaba.dubbo.config.spring.extension; import com.alibaba.dubbo.common.extension.ExtensionFactory; +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; import com.alibaba.dubbo.common.utils.ConcurrentHashSet; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.context.ApplicationContext; import java.util.Set; @@ -26,6 +31,7 @@ * SpringExtensionFactory */ public class SpringExtensionFactory implements ExtensionFactory { + private static final Logger logger = LoggerFactory.getLogger(SpringExtensionFactory.class); private static final Set contexts = new ConcurrentHashSet(); @@ -37,6 +43,11 @@ public static void removeApplicationContext(ApplicationContext context) { contexts.remove(context); } + // currently for test purpose + public static void clearContexts() { + contexts.clear(); + } + @Override @SuppressWarnings("unchecked") public T getExtension(Class type, String name) { @@ -48,6 +59,23 @@ public T getExtension(Class type, String name) { } } } + + logger.warn("No spring extension(bean) named:" + name + ", try to find an extension(bean) of type " + type.getName()); + + for (ApplicationContext context : contexts) { + try { + return context.getBean(type); + } catch (NoUniqueBeanDefinitionException multiBeanExe) { + throw multiBeanExe; + } catch (NoSuchBeanDefinitionException noBeanExe) { + if (logger.isDebugEnabled()) { + logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe); + } + } + } + + logger.warn("No spring extension(bean) named:" + name + ", type:" + type.getName() + " found, stop get bean."); + return null; } diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/extension/BeanForContext2.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/extension/BeanForContext2.java new file mode 100644 index 00000000000..cc272d84770 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/extension/BeanForContext2.java @@ -0,0 +1,31 @@ +/* + * 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.spring.extension; + +import com.alibaba.dubbo.config.spring.api.DemoService; +import com.alibaba.dubbo.config.spring.impl.DemoServiceImpl; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class BeanForContext2 { + @Bean("bean1") + public DemoService context2Bean() { + return new DemoServiceImpl(); + } +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactoryTest.java b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactoryTest.java new file mode 100644 index 00000000000..657d9212514 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/test/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactoryTest.java @@ -0,0 +1,95 @@ +/* + * 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.spring.extension; + +import com.alibaba.dubbo.config.spring.api.DemoService; +import com.alibaba.dubbo.config.spring.api.HelloService; +import com.alibaba.dubbo.config.spring.impl.DemoServiceImpl; +import com.alibaba.dubbo.config.spring.impl.HelloServiceImpl; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.NoUniqueBeanDefinitionException; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringExtensionFactoryTest { + + private SpringExtensionFactory springExtensionFactory = new SpringExtensionFactory(); + private AnnotationConfigApplicationContext context1; + private AnnotationConfigApplicationContext context2; + + @Before + public void init() { + context1 = new AnnotationConfigApplicationContext(); + context1.register(getClass()); + context1.refresh(); + context2 = new AnnotationConfigApplicationContext(); + context2.register(BeanForContext2.class); + context2.refresh(); + SpringExtensionFactory.addApplicationContext(context1); + SpringExtensionFactory.addApplicationContext(context2); + } + + @Test + public void testGetExtensionByName() { + DemoService bean = springExtensionFactory.getExtension(DemoService.class, "bean1"); + Assert.assertNotNull(bean); + } + + @Test + public void testGetExtensionByTypeMultiple() { + try { + springExtensionFactory.getExtension(DemoService.class, "beanname-not-exist"); + } catch (Exception e) { + e.printStackTrace(); + Assert.assertTrue(e instanceof NoUniqueBeanDefinitionException); + } + } + + @Test + public void testGetExtensionByType() { + HelloService bean = springExtensionFactory.getExtension(HelloService.class, "beanname-not-exist"); + Assert.assertNotNull(bean); + } + + @After + public void destroy() { + SpringExtensionFactory.clearContexts(); + context1.close(); + context2.close(); + } + + @Bean("bean1") + public DemoService bean1() { + return new DemoServiceImpl(); + } + + @Bean("bean2") + public DemoService bean2() { + return new DemoServiceImpl(); + } + + @Bean("hello") + public HelloService helloService() { + return new HelloServiceImpl(); + } +}