/** * 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(); } }
/** * 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(); } }