下面列出了怎么用com.google.inject.MembersInjector的API类实例代码及写法,或者点击链接到github查看源代码。
@Inject public MemberInjectingFactory(TypeLiteral<T> type, MembersInjector<T> injector) {
this.type = type;
this.injector = injector;
this.injectionPoint = InjectionPoint.forConstructorOf(type);
this.constructor = (Constructor<T>) injectionPoint.getMember();
this.constructor.setAccessible(true);
dependencies.addAll(Dependency.forInjectionPoints(InjectionPoint.forInstanceMethodsAndFields(type)));
}
@Override
protected void configure() {
final InjectionPoint point = InjectionPoint.forConstructorOf(innerType);
final Constructor<I> constructor = (Constructor<I>) point.getMember();
constructor.setAccessible(true);
if(point.getDependencies().isEmpty() || !Types.isAssignable(point.getDependencies().get(0).getKey().getTypeLiteral(), outerType)) {
addError("Expected %s to take %s as the first parameter of its injectable constructor", innerType, outerType);
return;
}
final Set<Dependency<?>> dependencies = point.getDependencies()
.stream()
.skip(1)
.collect(Collectors.toImmutableSet());
final List<Provider<?>> providers = dependencies.stream()
.map(dep -> getProvider(dep.getKey()))
.collect(Collectors.toImmutableList());
final MembersInjector<I> membersInjector = getMembersInjector(innerType);
class FactoryImpl implements InnerFactory<O, I>, HasDependencies {
@Override
public Set<Dependency<?>> getDependencies() {
return dependencies;
}
public I create(O outer) {
final Object[] args = new Object[providers.size() + 1];
args[0] = outer;
for(int i = 0; i < providers.size(); i++) {
args[i + 1] = providers.get(i).get();
}
return Injection.wrappingExceptions(() -> {
final I instance = constructor.newInstance(args);
membersInjector.injectMembers(instance);
return instance;
});
}
}
bind(factoryKey).toInstance(new FactoryImpl());
}
@SuppressWarnings("unchecked")
@Override
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
if (IAdaptable.class.isAssignableFrom(type.getRawType())) {
// TODO: method check should be moved into members injector,
// here, only the type + an additional operation should be checked.
for (final Method method : type.getRawType().getMethods()) {
// check that AdapterMap annotation is not used to mark
// injection points (but only in bindings).
for (int i = 0; i < method
.getParameterAnnotations().length; i++) {
AdapterMap adapterMapAnnotation = getAnnotation(
method.getParameterAnnotations()[i],
AdapterMap.class);
if (adapterMapAnnotation != null) {
encounter.addError(
"@AdapterMap annotation may only be used in adapter map bindings, not to mark an injection point. Annotate method with @InjectAdapters instead.",
method);
}
}
// we have a method annotated with AdapterBinding
if (eligibleForAdapterInjection(method)) {
// check that no Guice @Inject annotation is present on the
// method (so no interference occurs).
Inject injectAnnotation = method
.getAnnotation(Inject.class);
if (injectAnnotation != null) {
encounter.addError(
"To prevent that Guice member injection interferes with adapter injection, no @Inject annotation may be used on a method that provides an @InjectAdapters annotation.");
}
// register member injector on the IAdaptable (and provide
// the method to it, so it does not have to look it up
// again).
AdapterInjector membersInjector = new AdapterInjector(
method, loggingMode);
if (injector != null) {
injector.injectMembers(membersInjector);
} else {
nonInjectedMemberInjectors.add(membersInjector);
}
// System.out.println("Registering member injector to "
// + type);
encounter.register((MembersInjector<I>) membersInjector);
}
}
}
}