return loadVariable(creationalCallbackVarName).invoke("getInstance", Refs.get("context"));
}
}
final InjectionContext injectContext = injectableInstance.getInjectionContext();
final IOCProcessingContext ctx = injectContext.getProcessingContext();
/*
get a parameterized version of the CreationalCallback class, parameterized with the type of
bean it produces.
*/
final MetaClass creationCallbackRef = parameterizedAs(CreationalCallback.class, typeParametersOf(type));
/*
begin building the creational callback, implement the "getInstance" method from the interface
and assign its BlockBuilder to a callbackBuilder so we can work with it.
*/
final BlockBuilder<AnonymousClassStructureBuilder> callbackBuilder
= newInstanceOf(creationCallbackRef).extend()
.publicOverridesMethod("getInstance", Parameter.of(CreationalContext.class, "context", true));
/*
render local variables Class::beanType and Annotation[]::qualifiers at the beginning of the getInstance()
method so we can easily refer to them later on.
*/
callbackBuilder
._(declareVariable(Class.class).named("beanType").initializeWith(load(type)))
._(declareVariable(Annotation[].class).named("qualifiers")
.initializeWith(load(qualifyingMetadata.getQualifiers())));
/* push the method block builder onto the stack, so injection tasks are rendered appropriately. */
ctx.pushBlockBuilder(callbackBuilder);
/* get a new unique variable for the creational callback */
creationalCallbackVarName = InjectUtil.getNewInjectorName() + "_" + type.getName() + "_creationalCallback";
/* get the construction strategy and execute it to wire the bean */
InjectUtil.getConstructionStrategy(this, injectContext).generateConstructor(new ConstructionStatusCallback() {
@Override
public void beanConstructed() {
/* the bean has been constructed, so get a reference to the BeanRef and set it to the 'beanRef' variable. */
callbackBuilder.append(declareVariable(BeanRef.class).named("beanRef")
.initializeWith(loadVariable("context").invoke("getBeanReference", Refs.get("beanType"),
Refs.get("qualifiers"))));
/* add the bean to CreationalContext */
callbackBuilder.append(loadVariable("context").invoke("addBean", Refs.get("beanRef"), Refs.get(varName)));
/* mark this injector as injected so we don't go into a loop if there is a cycle. */
setCreated(true);
}
});
/*
return the instance of the bean from the creational callback.
*/
callbackBuilder.append(loadVariable(varName).returnValue());
/* pop the block builder of the stack now that we're done wiring. */
ctx.popBlockBuilder();
/*
declare a final variable for the CreationalCallback and initialize it with the anonymous class we just
built.
*/
// ctx.globalAppend(declareVariable(creationCallbackRef).asFinal().named(creationalCallbackVarName)
// .initializeWith(callbackBuilder.finish().finish()));
ctx.getBootstrapBuilder().privateField(creationalCallbackVarName, creationCallbackRef).modifiers(Modifier.Final)
.initializesWith(callbackBuilder.finish().finish()).finish();
Statement retVal;
if (isSingleton()) {
/*
if the injector is for a singleton, we create a variable to hold the singleton reference in the bootstrapper
method and assign it with CreationalContext.getInstance().
*/
// ctx.globalAppend(declareVariable(type).asFinal().named(varName)
// .initializeWith(loadVariable(creationalCallbackVarName).invoke("getInstance",
// Refs.get("context"))));
ctx.getBootstrapBuilder().privateField(varName, type).modifiers(Modifier.Final)
.initializesWith(loadVariable(creationalCallbackVarName).invoke("getInstance", Refs.get("context"))).finish();
/*
use the variable we just assigned as the return value for this injector.
*/