Struts2依赖注入关联的类

 // ContainerImpl  中定义的静态内部类

  

  /**
   * Injects a field or method in a given object.
   */
  interface Injector extends Serializable {
    void inject(InternalContext context, Object o);
  }

  static class MissingDependencyException extends Exception {

     MissingDependencyException(String message) {
       super(message);
     }
  }

   // 一些Injector 的实现类

static class FieldInjector implements Injector {

    final Field field;
    final InternalFactory<?> factory;
    final ExternalContext<?> externalContext;

    public FieldInjector(ContainerImpl container, Field field, String name)
        throws MissingDependencyException {
      this.field = field;
      field.setAccessible(true);// 此处貌似都是有必要的

                           //不使用构造函数是因为 Key类中构造函数定义为private
      Key<?> key = Key.newInstance(field.getType(), name);
      factory = container.getFactory(key);//注意传入ContainerImpl呀!
      if (factory == null) {
        throw new MissingDependencyException(
            "No mapping found for dependency " + key + " in " + field + ".");
      }
                           //不使用构造函数不知道为何了?????
      this.externalContext = ExternalContext.newInstance(field, key, container);
    }

   // 此处是核心关键调用的方法
    public void inject(InternalContext context, Object o) {
      ExternalContext<?> previous = context.getExternalContext();
      context.setExternalContext(externalContext);
      try {
         // 将指定对象变量上(o)此 Field 对象表示的字段设置为指定的新值(param2)。
        field.set(o, factory.create(context));

      } catch (IllegalAccessException e) {
        throw new AssertionError(e);
      } finally {
        // 此处谁能告诉我是干什么的?
        context.setExternalContext(previous);
      }
    }
  }

  //

static class ParameterInjector<T> {

    final ExternalContext<T> externalContext;
    final InternalFactory<? extends T> factory;

    public ParameterInjector(ExternalContext<T> externalContext,
        InternalFactory<? extends T> factory) {
             this.externalContext = externalContext;
             this.factory = factory;
    }

     //member 反映有关单个成员(字段或方法)或构造方法的标识信息。 
    T inject(Member member, InternalContext context) {
      ExternalContext<?> previous = context.getExternalContext();
      context.setExternalContext(externalContext);
      try {
        return factory.create(context);
      } finally { // 此处又来了 
        context.setExternalContext(previous);
      }
    }
  }

   

static class ConstructorInjector<T> {

    final Class<T> implementation;
    final List<Injector> injectors;
    final Constructor<T> constructor;
    final ParameterInjector<?>[] parameterInjectors;

    ConstructorInjector(ContainerImpl container, Class<T> implementation) {
      this.implementation = implementation;
                          //内部类提供的内部方法
      constructor = findConstructorIn(implementation);
      constructor.setAccessible(true); //也来了

      try {
        Inject inject = constructor.getAnnotation(Inject.class);
        parameterInjectors = inject == null
            ? null // default constructor.
            : container.getParametersInjectors(
                constructor,
                constructor.getParameterAnnotations(),
                constructor.getParameterTypes(),
                inject.value()
              );
      } catch (MissingDependencyException e) {
        throw new DependencyException(e);
      }
      injectors = container.injectors.get(implementation);
    }

    //内部类中提供的方法
    @SuppressWarnings("unchecked")
    private Constructor<T> findConstructorIn(Class<T> implementation) {
      Constructor<T> found = null;
      Constructor<T>[] declaredConstructors = (Constructor<T>[]) implementation.getDeclaredConstructors();
      for(Constructor<T> constructor :  declaredConstructors) {
        if (constructor.getAnnotation(Inject.class) != null) {
          if (found != null) {
            throw new DependencyException("More than one constructor annotated"
              + " with @Inject found in " + implementation + ".");
          }
          found = constructor;
        }
      }
      if (found != null) {
        return found;
      }

      // If no annotated constructor is found, look for a no-arg constructor
      // instead.
      try {
                return implementation.getDeclaredConstructor();
      } catch (NoSuchMethodException e) {
        throw new DependencyException("Could not find a suitable constructor"
            + " in " + implementation.getName() + ".");
      }
    }

    /**
     * Construct an instance. Returns {@code Object} instead of {@code T}
     * because it may return a proxy.
     */
    Object construct(InternalContext context, Class<? super T> expectedType) {
      ConstructionContext<T> constructionContext =
          context.getConstructionContext(this);

      // We have a circular reference between constructors. Return a proxy.
      if (constructionContext.isConstructing()) {
        // TODO (crazybob): if we can't proxy this object, can we proxy the
        // other object?
        return constructionContext.createProxy(expectedType);
      }

      // If we're re-entering this factory while injecting fields or methods,
      // return the same instance. This prevents infinite loops.
      T t = constructionContext.getCurrentReference();
      if (t != null) {
        return t;
      }

      try {
        // First time through...
        constructionContext.startConstruction();
        try {
          Object[] parameters =
              getParameters(constructor, context, parameterInjectors);
          t = constructor.newInstance(parameters);
          constructionContext.setProxyDelegates(t);
        } finally {
          constructionContext.finishConstruction();
        }

        // Store reference. If an injector re-enters this factory, they'll
        // get the same reference.
        constructionContext.setCurrentReference(t);

        // Inject fields and methods.
        for (Injector injector : injectors) {
          injector.inject(context, t);
        }

        return t;
      } catch (InstantiationException e) {
        throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
        throw new RuntimeException(e);
      } finally {
             constructionContext.removeCurrentReference();
      }
    }
  }

 // Container接口实现类中需要 重要的变量定义和方法定义

 ThreadLocal<Object[]> localContext = new ThreadLocal<Object[]>() {
          protected InternalContext[] initialValue() {
                return new InternalContext[1];
          }
      };

  /**
   * Looks up thread local context. Creates (and removes) a new context if
   * necessary.
   */
  <T> T callInContext(ContextualCallable<T> callable) {
    InternalContext[] reference = (InternalContext[]) localContext.get();
    if (reference[0] == null) {
      reference[0] = new InternalContext(this);
      try {
         return callable.call(reference[0]);
      } finally {
        // Only remove the context if this call created it.
         reference[0] = null;
      }
    } else {
      // Someone else will clean up this context.
       return callable.call(reference[0]);
    }
  }
  // 注意此处的接口定义
  interface ContextualCallable<T> {
         T call(InternalContext context);
   }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值