dubbo怎么做自动注入的?

通过spi扩展加载的时候,都是通过extensionloader来得到extension的,比如获得一个exchanger:

public static Exchanger getExchanger(String type) {    return ExtensionLoader.getExtensionLoader(Exchanger.class).getExtension(type);}

那么就是先拿到自己的extensionloader,然后利用这个loder去拿到extent-name对应的具体的扩展实例。

对于每一个extensionloader来说,除非自己是ExtensionFactory否则都有一个objectFactory,这个objectFactory本身通过扩展也是一个单例的adaptiveextension。

private ExtensionLoader(Class<?> type) {    this.type = type;    objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());}

通过这个ExtensionLoader去拿到具体的extension的时候:

injectExtension(instance);Set<Class<?>> wrapperClasses = cachedWrapperClasses;if (wrapperClasses != null && !wrapperClasses.isEmpty()) {    for (Class<?> wrapperClass : wrapperClasses) {        instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));    }}

有两种注入,一个是给自己的内部成员注入,另外就是自己被外层wrapper注入,反正都通过injectExtension来做的,具体看这个方法:

private T injectExtension(T instance) {    try {        if (objectFactory != null) {            for (Method method : instance.getClass().getMethods()) {                if (method.getName().startsWith("set")                        && method.getParameterTypes().length == 1                        && Modifier.isPublic(method.getModifiers())) {                    Class<?> pt = method.getParameterTypes()[0];                    try {                        String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";                        Object object = objectFactory.getExtension(pt, property);                        if (object != null) {                            method.invoke(instance, object);                        }                    } catch (Exception e) {                        logger.error("fail to inject via method " + method.getName()                                + " of interface " + type.getName() + ": " + e.getMessage(), e);                    }                }            }        }    } 

就是对所有的set方法对应的属性进行注入,通过objectFactory来完成的,这个factory是一个单例adaptive的,它的具体实现不是通过字节码自动生成的,而是提前写好的:

public <T> T getExtension(Class<T> type, String name) {    for (ExtensionFactory factory : factories) {        T extension = factory.getExtension(type, name);        if (extension != null) {            return extension;        }    }    return null;}

对于adaptive来说,它里面含有有两种facotry,spi和spring的,也就是只要有一个能够通过他们两个其中一个找到extension,那么就认为找到。

对于spi的facotry来说:

public <T> T getExtension(Class<T> type, String name) {    if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {        ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);        if (!loader.getSupportedExtensions().isEmpty()) {            return loader.getAdaptiveExtension();        }    }    return null;}

找到对应的extensionloader(所有的loader都放在全局、静态变量里面),然后直接返回适应性扩展。

也就是说dubbo帮你注入的不是一个具体extension,实际上也无法拿出来,因为只有在url给定具体的type以后才能给你真正对应的extension。

而在这里还没有到url解析,所以只返回一个适应性扩展帮你注入。后面如果需要拿到具体的extension,需要结合url才可以做到。这也方便了每个实现者通过url进行自我定义,dubbo只是帮你注入了一个adaptive扩展,具体哪个扩展,你自己结合url去拿。

对于spring扩展来说:

public <T> T getExtension(Class<T> type, String name) {    for (ApplicationContext context : contexts) {        if (context.containsBean(name)) {            Object bean = context.getBean(name);            if (type.isInstance(bean)) {                return (T) bean;            }        }    }    return null;}

这个就是依赖spring自己的context,比如定义了一个bean实现,想把它作为prover的imp-ref,那么就用这种方式。

原文地址:https://www.cnblogs.com/notlate/p/10229133.html

时间: 2024-10-16 02:17:12

dubbo怎么做自动注入的?的相关文章

关于springboot项目中自动注入,但是用的时候值为空的BUG

最近想做一些web项目来填充下业余时间,首先想到了使用springboot框架,毕竟方便 快捷 首先:去这里 http://start.spring.io/ 直接构建了一个springboot初始化的项目框架 然后:在页面上选择相应的依赖包,然后点击构建按钮,然后下载并且导入IDE中,目前喜欢使用IDEA 于是一个简答的springboot项目就搭建好了 废话说完,然后想体验下spring中redis的使用: 那就直接新建了一个类,然后 @Autowired 自动注入 RedisTemplate

spring自动注入是单例还是多例?单例如何注入多例?

单例多例需要搞明白这些问题:      1. 什么是单例多例:      2. 如何产生单例多例:      3. 为什么要用单例多例      4. 什么时候用单例,什么时候用多例:   1. 什么是单例.多例: 所谓单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的,而多例则指每个请求用一个新的对象来处理,比如action; 单例模式和多例模式说明: 1. 单例模式和多例模式属于对象模式. 2. 单例模式的对象在整个系统中只有一份,多例模式可以有

带你开发一款给Apk中自动注入代码工具icodetools(开凿篇)

一.前言 从这篇开始咋们开始一个全新的静态方式逆向工具icodetools的实现过程,这个也是我自己第一次写的个人觉得比较有用的小工具,特别是在静态方式逆向apk找关键点的时候,后续会分为三篇来详细介绍这个工具实现: 第一篇:开凿篇,简单介绍实现原理以及简单的初次方案实现简单的apk注入代码功能 第二篇:填坑篇,这一篇是在前一篇的基础上对工具的优化,可以应对市面上大部分的apk代码注入功能实现 第三篇:生产篇,这一篇是在前两篇的基础上利用这个工具来实际操刀如何进行快速定位应用的关键方法功能 还记

运用smali自动注入技术分析apk行为

现在android开发者社区里,除了app开发外,还有很多周边的工具类产品,比如安全.性能等,app产品已经出现了 巨无霸,但是工具类的产品,目前还没有出现规模比较大的公司,大部分还处于创业阶段,这可能是创业者的下一个机会. 工具类的产品相对app开发有比较高的技术门槛,从事这方面开发的技术人员需要掌握的基本功如下: 1.熟悉android app的编译过程,了解jvm的bytecode与dalvik bytecode的区别: 2.熟悉android framework,读过部分代码,比如系统启

web 工程中利用Spring的 ApplicationContextAware接口自动注入bean

最常用的办法就是用 ClassPathXmlApplicationContext, FileSystemClassPathXmlApplicationContext, FileSystemXmlApplicationContext 等对象去加载Spring配置文件,这样做也是可以, 但是在加载Spring配置文件的时候,就会生成一个新的ApplicaitonContext对象而不是Spring容器帮我们生成的哪一个, 这样就产生了冗余, 所以不采用应用程序手动加载文件的方式,而是使用Applic

【安全牛学习笔记】SQLMAP自动注入-ENUMERATION、BRUTE FORCE、UDF IN

伪静态页面不能注入,这是错误的! SQLMAP自动注入08-----ENUMERATION --current-user --current-db --hostname --users --privileges -U username (CU当前账号) --roles --dbs --tables,--exclude-sysdbs -D dvwa -T user -D dvwa -C user --columns [email protected]:~# sqlmap -u "http://19

【安全牛学习笔记】SQLMAP自动注入-INHECTION、DETECTION、TECHNIQUES

SQLMAP自动注入04-----INJECTION -p 指定扫描的参数,使--level失效 -p "user-agent,referer" --skip 排除指定的扫描参数 --level=5 --skip="id,user-agent" URI注入点 sqlmap -u "http://targeturl/param1/value1*/param2/value2/" [email protected]:~# sqlmap -u "

【安全牛学习笔记】SQLMAP自动注入(二)

SQLMAP自动注入(二)-REQUEST和SQLMAP自动注入(三)-OPTIMIZATION SQLMAP自动注入02-----REQUEST --delay 每次http(s)请求之间延迟时间,浮点数,单位为秒,默认无延迟 --timeout 请求超时时间,浮点数,默认为30秒 --retries http(s)连接超时重试次数,默认3次 --randomize 长度.类型与原始值保持一致的前提下,指定每次请求随机取值的参数名 SQLMAP自动注入02-----REQUEST --scop

Injection of autowired dependencies failed; autowire 自动注入失败,测试类已初始化过了Spring容器。

1 严重: StandardWrapper.Throwable 2 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreatio