3.2 Dubbo IOC

Dubbo IOC 是通过 setter 方法注入依赖。Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征。若有,则通过 ObjectFactory 获取依赖对象,最后通过反射调用 setter 方法将依赖设置到目标对象中。整个过程对应的代码如下:

  1. private T injectExtension(T instance) {
  2. try {
  3. if (objectFactory != null) {
  4. // 遍历目标类的所有方法
  5. for (Method method : instance.getClass().getMethods()) {
  6. // 检测方法是否以 set 开头,且方法仅有一个参数,且方法访问级别为 public
  7. if (method.getName().startsWith("set")
  8. && method.getParameterTypes().length == 1
  9. && Modifier.isPublic(method.getModifiers())) {
  10. // 获取 setter 方法参数类型
  11. Class<?> pt = method.getParameterTypes()[0];
  12. try {
  13. // 获取属性名,比如 setName 方法对应属性名 name
  14. String property = method.getName().length() > 3 ?
  15. method.getName().substring(3, 4).toLowerCase() +
  16. method.getName().substring(4) : "";
  17. // 从 ObjectFactory 中获取依赖对象
  18. Object object = objectFactory.getExtension(pt, property);
  19. if (object != null) {
  20. // 通过反射调用 setter 方法设置依赖
  21. method.invoke(instance, object);
  22. }
  23. } catch (Exception e) {
  24. logger.error("fail to inject via method...");
  25. }
  26. }
  27. }
  28. }
  29. } catch (Exception e) {
  30. logger.error(e.getMessage(), e);
  31. }
  32. return instance;
  33. }

在上面代码中,objectFactory 变量的类型为 AdaptiveExtensionFactory,AdaptiveExtensionFactory 内部维护了一个 ExtensionFactory 列表,用于存储其他类型的 ExtensionFactory。Dubbo 目前提供了两种 ExtensionFactory,分别是 SpiExtensionFactory 和 SpringExtensionFactory。前者用于创建自适应的拓展,后者是用于从 Spring 的 IOC 容器中获取所需的拓展。这两个类的类的代码不是很复杂,这里就不一一分析了。

Dubbo IOC 目前仅支持 setter 方式注入,总的来说,逻辑比较简单易懂。