1、基本流程
2、AOP
3、IOC
4、AdaptiveExtension
5、ActivateExtension
getExtension(name)
getAdaptiveExtension(URL)
getAdaptiveExtension(URL,扩展点名称,group名称)
dubbo spi的使用:
需要设置的地方:
1)resource文件夹增加接口全路径名称的文件
2)接口类增加@SPI注解。
3)被代理的对象增加@Adaptive注解
配置好spi后执行的时候,是根据配置文件的key找到一个代理对象(此代理对象是根据配置的实现类的实例实现的,被代理的方法实现逻辑是,根据com.alibaba.dubbo.common.URL参数,拿到文件key,根据key找)
ExtensionLoader -- 扩展点加载器
1、type ---- 接口
2、objectFactory ----> 实现类的对象 ---- Spring容器(type)
方法
1、getExtension(name)----
2、createExtension(name) ----> 创建对象
1、name--->实现类的全路径名字
加载文件,遍历扫描文件内容,找到实现类的名字,放到map中。
扫描到的wrapper类名字都放到一个set中,供依赖注入后使用生成wrapper类实例
2、实例化(newInstance)-------carFilter
3、依赖注入
是通过set方法来设置属性的。
找到类的方法和参数,根据属性和方法找到对象,然后通过反射设置属性值(method.invoke(instance,object))
依赖注入后,会根据上一步的接口实例生成wrapper类的实例(传入了instance)。如果有多个wrapper的话,会把上一次生成的wrapper类实例当成一个实例传入,然后生成一个新的wrapper类实例,就像套娃一样。
4、AOP
5、return instance
3、loadExtensionClasses() -- return Map
1 三者的关系
SpiExtensionFactory
要使用这个来获取对象,必须在接口上使用@SPI注解。
获取的过程:先找到加载器,loader.getAdaptiveExtension()获取接口的Adaptive类(是一个代理对象)。
解决方法上必须使用@Adaptive注解,才能默认生成代理类。而且需要被代理的方法也必须有个com.alibaba.dubbo.common.URL(dubbo服务提供者的url)参数
如果接口方法没有指定Adaptive类,dubbo会默认生成一个
ExtensionLoader的代码:
//生成java类的代码
String code = this.createAdaptiveExtensionClassCode();
ClassLoader classLoader = findClassLoader();
Compiler compiler = (Compiler)getExtensionLoader(Compiler.class).getAdaptiveExtension();
//编译成class类
return compiler.compile(code, classLoader);
SpinrgExtensionFactory
是从ApplicationContext(Spring容器)中先根据名称去拿对象实例,如果没有找到再根据type去拿。
AdaptiveExtensionFactory:用来判断是适用spi的factory还是spring的factory。
具体再适用的时候,如果接口上制定了@SPI的注解,那就只能适用SpiExtensionFactory,否则,只要从一个factory中生成了对象实例就返回。
group 只是一个表示,不仅仅有PROVIDER和CONSUMER,可以随便定义
@Activate(group={PROVIDER,CONSUMER})
服务端和消费端都可以使用
@Activate(group=CommonConstants.PROVIDER)
只能服务端使用
@Activate(group=CommonConstants.PROVIDER,value="condition_param")
服务端使用,而且必须满足value配合的条件时才可使用