您好,登錄后才能下訂單哦!
dubbo中SpringExtensionFactory有什么用,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
dubbo-2.7.3/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionFactory.java
@SPI public interface ExtensionFactory { /** * Get extension. * * @param type object type. * @param name object name. * @return object instance. */ <T> T getExtension(Class<T> type, String name); }
ExtensionFactory接口定義了getExtension方法
dubbo-2.7.3/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionFactory.java
public class SpringExtensionFactory implements ExtensionFactory { private static final Logger logger = LoggerFactory.getLogger(SpringExtensionFactory.class); private static final Set<ApplicationContext> CONTEXTS = new ConcurrentHashSet<ApplicationContext>(); private static final ApplicationListener SHUTDOWN_HOOK_LISTENER = new ShutdownHookListener(); public static void addApplicationContext(ApplicationContext context) { CONTEXTS.add(context); if (context instanceof ConfigurableApplicationContext) { ((ConfigurableApplicationContext) context).registerShutdownHook(); DubboShutdownHook.getDubboShutdownHook().unregister(); } BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER); } public static void removeApplicationContext(ApplicationContext context) { CONTEXTS.remove(context); } public static Set<ApplicationContext> getContexts() { return CONTEXTS; } // currently for test purpose public static void clearContexts() { CONTEXTS.clear(); } @Override @SuppressWarnings("unchecked") public <T> T getExtension(Class<T> type, String name) { //SPI should be get from SpiExtensionFactory if (type.isInterface() && type.isAnnotationPresent(SPI.class)) { return null; } for (ApplicationContext context : CONTEXTS) { if (context.containsBean(name)) { Object bean = context.getBean(name); if (type.isInstance(bean)) { return (T) bean; } } } logger.warn("No spring extension (bean) named:" + name + ", try to find an extension (bean) of type " + type.getName()); if (Object.class == type) { return null; } for (ApplicationContext context : CONTEXTS) { try { return context.getBean(type); } catch (NoUniqueBeanDefinitionException multiBeanExe) { logger.warn("Find more than 1 spring extensions (beans) of type " + type.getName() + ", will stop auto injection. Please make sure you have specified the concrete parameter type and there's only one extension of that type."); } 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; } private static class ShutdownHookListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof ContextClosedEvent) { DubboShutdownHook shutdownHook = DubboShutdownHook.getDubboShutdownHook(); shutdownHook.doDestroy(); } } } }
SpringExtensionFactory實現(xiàn)了ExtensionFactory方法,它提供了addApplicationContext靜態(tài)方法來添加ApplicationContext,同時注冊了SHUTDOWN_HOOK_LISTENER;其getExtension方法首先根據(jù)name從ApplicationContext中獲取bean,獲取不到則在根據(jù)type再去ApplicationContext中獲取bean,獲取不到則返回null
dubbo-2.7.3/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/extension/SpringExtensionFactoryTest.java
@Configuration public class SpringExtensionFactoryTest { private SpringExtensionFactory springExtensionFactory = new SpringExtensionFactory(); private AnnotationConfigApplicationContext context1; private AnnotationConfigApplicationContext context2; @BeforeEach 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 testGetExtensionBySPI() { Protocol protocol = springExtensionFactory.getExtension(Protocol.class, "protocol"); Assertions.assertNull(protocol); } @Test public void testGetExtensionByName() { DemoService bean = springExtensionFactory.getExtension(DemoService.class, "bean1"); Assertions.assertNotNull(bean); } @Test public void testGetExtensionByTypeMultiple() { try { springExtensionFactory.getExtension(DemoService.class, "beanname-not-exist"); } catch (Exception e) { e.printStackTrace(); Assertions.assertTrue(e instanceof NoUniqueBeanDefinitionException); } } @Test public void testGetExtensionByType() { HelloService bean = springExtensionFactory.getExtension(HelloService.class, "beanname-not-exist"); Assertions.assertNotNull(bean); } @AfterEach 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(); } }
SpringExtensionFactoryTest的init方法給springExtensionFactory添加了context1和context2;之后驗證了根據(jù)SPI、根據(jù)name、根據(jù)type來獲取extension
SpringExtensionFactory實現(xiàn)了ExtensionFactory方法,它提供了addApplicationContext靜態(tài)方法來添加ApplicationContext,同時注冊了SHUTDOWN_HOOK_LISTENER;其getExtension方法首先根據(jù)name從ApplicationContext中獲取bean,獲取不到則在根據(jù)type再去ApplicationContext中獲取bean,獲取不到則返回null
看完上述內(nèi)容,你們掌握dubbo中SpringExtensionFactory有什么用的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。