Skip to content
Permalink
Browse files
Merge pull request #1837, spring spi support inject by type.
  • Loading branch information
chickenlj committed May 31, 2018
1 parent 1b553fd commit 5f5fecd68e209c79a7f9ac382b95296713c77bea
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 0 deletions.
@@ -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<ApplicationContext> contexts = new ConcurrentHashSet<ApplicationContext>();

@@ -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> T getExtension(Class<T> type, String name) {
@@ -48,6 +59,23 @@ public <T> T getExtension(Class<T> 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;
}

@@ -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();
}
}
@@ -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();
}
}

0 comments on commit 5f5fecd

Please sign in to comment.