Skip to content

Commit a277b38

Browse files
authored
Merge pull request apache#1837, spring spi support inject by type.
1 parent eca2c3d commit a277b38

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/extension/SpringExtensionFactory.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
package com.alibaba.dubbo.config.spring.extension;
1818

1919
import com.alibaba.dubbo.common.extension.ExtensionFactory;
20+
import com.alibaba.dubbo.common.logger.Logger;
21+
import com.alibaba.dubbo.common.logger.LoggerFactory;
2022
import com.alibaba.dubbo.common.utils.ConcurrentHashSet;
23+
24+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
25+
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
2126
import org.springframework.context.ApplicationContext;
2227

2328
import java.util.Set;
@@ -26,6 +31,7 @@
2631
* SpringExtensionFactory
2732
*/
2833
public class SpringExtensionFactory implements ExtensionFactory {
34+
private static final Logger logger = LoggerFactory.getLogger(SpringExtensionFactory.class);
2935

3036
private static final Set<ApplicationContext> contexts = new ConcurrentHashSet<ApplicationContext>();
3137

@@ -37,6 +43,11 @@ public static void removeApplicationContext(ApplicationContext context) {
3743
contexts.remove(context);
3844
}
3945

46+
// currently for test purpose
47+
public static void clearContexts() {
48+
contexts.clear();
49+
}
50+
4051
@Override
4152
@SuppressWarnings("unchecked")
4253
public <T> T getExtension(Class<T> type, String name) {
@@ -48,6 +59,23 @@ public <T> T getExtension(Class<T> type, String name) {
4859
}
4960
}
5061
}
62+
63+
logger.warn("No spring extension(bean) named:" + name + ", try to find an extension(bean) of type " + type.getName());
64+
65+
for (ApplicationContext context : contexts) {
66+
try {
67+
return context.getBean(type);
68+
} catch (NoUniqueBeanDefinitionException multiBeanExe) {
69+
throw multiBeanExe;
70+
} catch (NoSuchBeanDefinitionException noBeanExe) {
71+
if (logger.isDebugEnabled()) {
72+
logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe);
73+
}
74+
}
75+
}
76+
77+
logger.warn("No spring extension(bean) named:" + name + ", type:" + type.getName() + " found, stop get bean.");
78+
5179
return null;
5280
}
5381

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.alibaba.dubbo.config.spring.extension;
18+
19+
import com.alibaba.dubbo.config.spring.api.DemoService;
20+
import com.alibaba.dubbo.config.spring.impl.DemoServiceImpl;
21+
22+
import org.springframework.context.annotation.Bean;
23+
import org.springframework.context.annotation.Configuration;
24+
25+
@Configuration
26+
public class BeanForContext2 {
27+
@Bean("bean1")
28+
public DemoService context2Bean() {
29+
return new DemoServiceImpl();
30+
}
31+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.alibaba.dubbo.config.spring.extension;
18+
19+
import com.alibaba.dubbo.config.spring.api.DemoService;
20+
import com.alibaba.dubbo.config.spring.api.HelloService;
21+
import com.alibaba.dubbo.config.spring.impl.DemoServiceImpl;
22+
import com.alibaba.dubbo.config.spring.impl.HelloServiceImpl;
23+
24+
import org.junit.After;
25+
import org.junit.Assert;
26+
import org.junit.Before;
27+
import org.junit.Test;
28+
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
29+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
30+
import org.springframework.context.annotation.Bean;
31+
import org.springframework.context.annotation.Configuration;
32+
33+
@Configuration
34+
public class SpringExtensionFactoryTest {
35+
36+
private SpringExtensionFactory springExtensionFactory = new SpringExtensionFactory();
37+
private AnnotationConfigApplicationContext context1;
38+
private AnnotationConfigApplicationContext context2;
39+
40+
@Before
41+
public void init() {
42+
context1 = new AnnotationConfigApplicationContext();
43+
context1.register(getClass());
44+
context1.refresh();
45+
context2 = new AnnotationConfigApplicationContext();
46+
context2.register(BeanForContext2.class);
47+
context2.refresh();
48+
SpringExtensionFactory.addApplicationContext(context1);
49+
SpringExtensionFactory.addApplicationContext(context2);
50+
}
51+
52+
@Test
53+
public void testGetExtensionByName() {
54+
DemoService bean = springExtensionFactory.getExtension(DemoService.class, "bean1");
55+
Assert.assertNotNull(bean);
56+
}
57+
58+
@Test
59+
public void testGetExtensionByTypeMultiple() {
60+
try {
61+
springExtensionFactory.getExtension(DemoService.class, "beanname-not-exist");
62+
} catch (Exception e) {
63+
e.printStackTrace();
64+
Assert.assertTrue(e instanceof NoUniqueBeanDefinitionException);
65+
}
66+
}
67+
68+
@Test
69+
public void testGetExtensionByType() {
70+
HelloService bean = springExtensionFactory.getExtension(HelloService.class, "beanname-not-exist");
71+
Assert.assertNotNull(bean);
72+
}
73+
74+
@After
75+
public void destroy() {
76+
SpringExtensionFactory.clearContexts();
77+
context1.close();
78+
context2.close();
79+
}
80+
81+
@Bean("bean1")
82+
public DemoService bean1() {
83+
return new DemoServiceImpl();
84+
}
85+
86+
@Bean("bean2")
87+
public DemoService bean2() {
88+
return new DemoServiceImpl();
89+
}
90+
91+
@Bean("hello")
92+
public HelloService helloService() {
93+
return new HelloServiceImpl();
94+
}
95+
}

0 commit comments

Comments
 (0)