@Override public T get(final InternalContext context, final Dependency<?> dependency, boolean linked) throws InternalProvisionException { if (provisionCallback == null) { return doProvision(context, dependency); } else { return provisionCallback.provision( context, new ProvisionCallback<T>() { @Override public T call() throws InternalProvisionException { return doProvision(context, dependency); } }); } }
@Override public final T get( final InternalContext context, final Dependency<?> dependency, boolean linked) throws InternalProvisionException { final ConstructionContext<T> constructionContext = context.getConstructionContext(this); // We have a circular reference between bindings. Return a proxy. if (constructionContext.isConstructing()) { Class<?> expectedType = dependency.getKey().getTypeLiteral().getRawType(); @SuppressWarnings("unchecked") T proxyType = (T) constructionContext.createProxy(context.getInjectorOptions(), expectedType); return proxyType; } // Optimization: Don't go through the callback stack if no one's listening. constructionContext.startConstruction(); try { if (provisionCallback == null) { return provision(dependency, context, constructionContext); } else { return provisionCallback.provision( context, new ProvisionCallback<T>() { @Override public T call() throws InternalProvisionException { return provision(dependency, context, constructionContext); } }); } } finally { constructionContext.removeCurrentReference(); constructionContext.finishConstruction(); } }
protected T circularGet( final Provider<? extends T> provider, InternalContext context, final Dependency<?> dependency, /* @Nullable */ ProvisionListenerStackCallback<T> provisionCallback) throws InternalProvisionException { final ConstructionContext<T> constructionContext = context.getConstructionContext(this); // We have a circular reference between constructors. Return a proxy. if (constructionContext.isConstructing()) { Class<?> expectedType = dependency.getKey().getTypeLiteral().getRawType(); // TODO: if we can't proxy this object, can we proxy the other object? @SuppressWarnings("unchecked") T proxyType = (T) constructionContext.createProxy(context.getInjectorOptions(), expectedType); return proxyType; } // Optimization: Don't go through the callback stack if no one's listening. constructionContext.startConstruction(); try { if (provisionCallback == null) { return provision(provider, dependency, constructionContext); } else { return provisionCallback.provision( context, new ProvisionCallback<T>() { @Override public T call() throws InternalProvisionException { return provision(provider, dependency, constructionContext); } }); } } finally { constructionContext.removeCurrentReference(); 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(); } }
protected T circularGet(final Provider<? extends T> provider, final Errors errors, InternalContext context, final Dependency<?> dependency, boolean linked, ProvisionListenerStackCallback<T> provisionCallback) throws ErrorsException { Class<?> expectedType = dependency.getKey().getTypeLiteral().getRawType(); 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: if we can't proxy this object, can we proxy the other object? @SuppressWarnings("unchecked") T proxyType = (T) constructionContext.createProxy(errors, expectedType); return proxyType; } } // Optimization: Don't go through the callback stack if no one's listening. constructionContext.startConstruction(); try { if (!provisionCallback.hasListeners()) { return provision(provider, errors, dependency, constructionContext); } else { return provisionCallback.provision(errors, context, new ProvisionCallback<T>() { public T call() throws ErrorsException { return provision(provider, errors, dependency, constructionContext); } }); } } finally { constructionContext.removeCurrentReference(); constructionContext.finishConstruction(); } }
/** * Construct an instance. Returns {@code Object} instead of {@code T} because it may return a * proxy. */ Object construct( final InternalContext context, Dependency<?> dependency, /* @Nullable */ ProvisionListenerStackCallback<T> provisionCallback) throws InternalProvisionException { 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( 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 InternalProvisionException.circularDependenciesDisabled( dependency.getKey().getTypeLiteral().getRawType()); } else { return t; } } constructionContext.startConstruction(); try { // Optimization: Don't go through the callback stack if we have no listeners. if (provisionCallback == null) { return provision(context, constructionContext); } else { return provisionCallback.provision( context, new ProvisionCallback<T>() { @Override public T call() throws InternalProvisionException { return provision(context, constructionContext); } }); } } finally { constructionContext.finishConstruction(); } }
void injectAndNotify( final T instance, final Key<T> key, // possibly null! final ProvisionListenerStackCallback<T> provisionCallback, // possibly null! final Object source, final boolean toolableOnly) throws InternalProvisionException { if (instance == null) { return; } final InternalContext context = injector.enterContext(); context.pushState(key, source); try { if (provisionCallback != null && provisionCallback.hasListeners()) { provisionCallback.provision( context, new ProvisionCallback<T>() { @Override public T call() throws InternalProvisionException { injectMembers(instance, context, toolableOnly); return instance; } }); } else { injectMembers(instance, context, toolableOnly); } } finally { context.popState(); context.close(); } // TODO: We *could* notify listeners too here, // but it's not clear if we want to. There's no way to know // if a MembersInjector from the usersMemberInjector list wants // toolable injections, so do we really want to notify // about injection? (We could take a strategy of only notifying // if atleast one InjectionPoint was toolable, in which case // the above callInContext could return 'true' if it injected // anything.) if (!toolableOnly) { notifyListeners(instance); } }
void injectAndNotify(final T instance, final Errors errors, final Key<T> key, // possibly null! final ProvisionListenerStackCallback<T> provisionCallback, // possibly null! final Object source, final boolean toolableOnly) throws ErrorsException { if (instance == null) { return; } injector.callInContext(new ContextualCallable<Void>() { @Override public Void call(final InternalContext context) throws ErrorsException { context.pushState(key, source); try { if (provisionCallback != null && provisionCallback.hasListeners()) { provisionCallback.provision(errors, context, new ProvisionCallback<T>() { @Override public T call() { injectMembers(instance, errors, context, toolableOnly); return instance; } }); } else { injectMembers(instance, errors, context, toolableOnly); } } finally { context.popState(); } return null; } }); // TODO: We *could* notify listeners too here, // but it's not clear if we want to. There's no way to know // if a MembersInjector from the usersMemberInjector list wants // toolable injections, so do we really want to notify // about injection? (We could take a strategy of only notifying // if atleast one InjectionPoint was toolable, in which case // the above callInContext could return 'true' if it injected // anything.) if(!toolableOnly) { notifyListeners(instance, errors); } }