dubbo源码(章节二) -- dubbo的Ioc

 上一篇主要分析了extensionLoader的获取,以及获取extension的第一种方式,即通过装饰类或者动态代理的方式,今天我们首先从获取extension的第二种方式说起。

复制代码
/**  * Find the extension with the given name.  */ getExtension(String name)
复制代码

 

下面讨论getExtension(String name)

先从这个方法的代码跟踪开始,

复制代码
1 public T getExtension(String name) {
2   Holder<Object> holder = cachedInstances.get(name); 3   ......
4   Object instance = holder.get(); 5   ......
6   instance = createExtension(name);
7   return (T) instance; 8 }
复制代码

这里省略了比较多的内容,有了前面一篇跟踪代码的经验,缓存的具体使用就不再贴出来了,我们只看主要逻辑即可,跟进去看createExtension(name),

复制代码
 1 private T createExtension(String name) {  2   Class<?> clazz = getExtensionClasses().get(name); 
3
  T instance = clazz.newInstance(); 4
5   injectExtension(instance); 6   Set<Class<?>> wrapperClasses = cachedWrapperClasses;
7   for (Class<?> wrapperClass : wrapperClasses) { 8     instance =
9     injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
10   }
11   return instance;
12 }
复制代码

这里先是通过getExtensionClasses().get(name)拿到一个class对象,getExtensionClasses()方法上一篇说过了,它最终所赋值的是type扩展的所有实现中,既没有@Adaptive注解,也不包含type类型的构造器(这一类扩展实现我们称之为包装类)的那些实现类,并且被缓存在cachedClasses map中,map的key即为实现类在dubbo spi配置文件中的类名,这里提一个细节,如果在cachedClasses中没有拿到key为name对应的value,这里就会抛出异常,那也就是说,getExtension(name)这种方式,只能用来获取既非@Adaptive注解,又非包装类的那些类的实现,因为只有这样的类才会被缓存在cachedClasses中。这里拿到这个类并实例化一个Instance,然后调用了方法injectExtension(instance),这个方法看名字就知道了,inject既就是注射的意思,这里就将实现dubbo的依赖注入,现在来看这个方法的实现,

复制代码
 1 private T injectExtension(T instance) { 
2
  for (Method method : instance.getClass().getMethods()) { 3     if (method.getName().startsWith("set") 4         && method.getParameterTypes().length == 1 5         && Modifier.isPublic(method.getModifiers())) { 6       Class<?> pt = method.getParameterTypes()[0]; 7
8       String property = method.getName().length() > 3 ?
9         method.getName().substring(3, 4).toLowerCase() +
10         method.getName().substring(4) : ""
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信