Пример #1
0
  /**
   * Construct an instance. Returns {@code Object} instead of {@code T} because it may return a
   * proxy.
   */
  Object construct(
      final Errors errors,
      final InternalContext context,
      Class<?> expectedType,
      boolean allowProxy,
      ProvisionListenerStackCallback<T> provisionCallback)
      throws ErrorsException {
    final ConstructionContext<T> constructionContext = context.getConstructionContext(this);

    // We have a circular reference between constructors. Return a proxy.
    if (constructionContext.isConstructing()) {
      if (!allowProxy) {
        throw errors.circularProxiesDisabled(expectedType).toException();
      } else {
        // TODO (crazybob): if we can't proxy this object, can we proxy the other object?
        return constructionContext.createProxy(errors, 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;
    }

    constructionContext.startConstruction();
    try {
      // Optimization: Don't go through the callback stack if we have no listeners.
      if (!provisionCallback.hasListeners()) {
        return provision(errors, context, constructionContext);
      } else {
        return provisionCallback.provision(
            errors,
            context,
            new ProvisionCallback<T>() {
              public T call() throws ErrorsException {
                return provision(errors, context, constructionContext);
              }
            });
      }
    } finally {
      constructionContext.finishConstruction();
    }
  }
Пример #2
0
  /**
   * Construct an instance. Returns {@code Object} instead of {@code T} because it may return a
   * proxy.
   */
  Object construct(
      final Errors errors,
      final InternalContext context,
      Dependency<?> dependency,
      /* @Nullable */ ProvisionListenerStackCallback<T> provisionCallback)
      throws ErrorsException {
    final 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(
          errors, context.getInjectorOptions(), dependency.getKey().getTypeLiteral().getRawType());
    }

    // 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) {
      if (context.getInjectorOptions().disableCircularProxies) {
        throw errors
            .circularDependenciesDisabled(dependency.getKey().getTypeLiteral().getRawType())
            .toException();
      } else {
        return t;
      }
    }

    constructionContext.startConstruction();
    try {
      // Optimization: Don't go through the callback stack if we have no listeners.
      if (provisionCallback == null) {
        return provision(errors, context, constructionContext);
      } else {
        return provisionCallback.provision(
            errors,
            context,
            new ProvisionCallback<T>() {
              @Override
              public T call() throws ErrorsException {
                return provision(errors, context, constructionContext);
              }
            });
      }
    } finally {
      constructionContext.finishConstruction();
    }
  }