下面列出了com.google.inject.MembersInjector#com.google.inject.spi.InjectionPoint 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void injectValues(final Object target, final boolean sharedFields) throws IllegalAccessException {
for (InjectionPoint point : injectionPoints) {
if (!(point.getMember() instanceof Field)) {
throw new GuiceyExtensionException("Method injection is not supported; use field injection instead");
}
final Field field = (Field) point.getMember();
if (field.isAnnotationPresent(Shared.class) != sharedFields) {
continue;
}
final Object value = injector.getInstance(point.getDependencies().get(0).getKey());
field.setAccessible(true);
field.set(target, value);
}
// ClientSupport fields
SpecialFieldsSupport.initClients(target, clientFields, support.getClient(), sharedFields);
}
/**
* Return all direct dependencies injected into the given type
*/
public static Stream<Dependency<?>> dependencies(Class<?> type) {
return Stream.concat(
Stream.of(InjectionPoint.forConstructorOf(type)),
InjectionPoint.forInstanceMethodsAndFields(type).stream()
).flatMap(ip -> ip.getDependencies().stream());
}
private <D> InjectableMethod(@Nullable TypeLiteral<D> targetType, @Nullable D target, Method method, @Nullable T result) {
final Errors errors = new Errors(method);
if(Members.isStatic(method)) {
checkArgument(target == null);
} else {
checkArgument(target != null);
}
targetType = targetType(targetType, target, method);
checkArgument(method.getDeclaringClass().isAssignableFrom(targetType.getRawType()));
this.method = method;
this.dependencies = ImmutableSet.copyOf(InjectionPoint.forMethod(method, targetType).getDependencies());
if(result != null) {
this.result = result;
this.providedKey = Keys.forInstance(result);
} else {
final TypeLiteral<T> returnType = (TypeLiteral<T>) targetType.getReturnType(method);
if(!Void.class.equals(returnType.getRawType())) {
final Annotation qualifier = Annotations.findBindingAnnotation(errors, method, method.getAnnotations());
this.result = null;
this.providedKey = Keys.get(returnType, qualifier);
} else {
this.result = (T) this;
this.providedKey = Keys.forInstance(this.result);
}
}
this.scope = Annotations.findScopeAnnotation(errors, method.getAnnotations());
MethodHandle handle = MethodHandleUtils.privateUnreflect(method);
if(target != null) {
handle = handle.bindTo(target);
}
this.handle = handle;
}
public DependencyCollector log(Logger logger, Level level) {
logger.log(level, "Dumping all dependencies:");
for(Map.Entry<TypeLiteral<?>, Collection<InjectionPoint>> entry : injectionPointsByType().asMap().entrySet()) {
logger.log(level, entry.getKey().toString());
for(InjectionPoint ip : entry.getValue()) {
logger.log(level, " " + ip.getMember());
for(Dependency<?> dep : dependenciesByInjectionPoint().get(ip)) {
logger.log(level, " " + dep);
}
}
}
return this;
}
@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)));
}
public static void checkInjectableCGLibProxyBase(Class<?> cls) {
InjectionPoint.forInstanceMethodsAndFields(cls).forEach(ip -> {
if(ip.getMember() instanceof Method && !Modifier.isPrivate(ip.getMember().getModifiers())) {
// CGLib proxies override all non-private methods on the base class,
// and do not copy method annotations, so Guice will not find the
// @Inject annotation on the base method. Declaring the method
// private works around this. The proxy will not try to override
// private methods, and Guice can find them just fine.
throw new MethodFormException(
(Method) ip.getMember(),
"Injected method on CGLib proxied class must be private (see exception site for details)"
);
}
});
}
public GuiceyInterceptor(final SpecInfo spec, final EnvironmentSupport support,
final List<GuiceyConfigurationHook> hooks) {
this.support = support;
this.hooks = hooks;
injectionPoints = InjectionPoint.forInstanceMethodsAndFields(spec.getReflection());
clientFields = SpecialFieldsSupport.findClientFields(spec.getReflection());
}
public static <T> Constructor<T> injectableConstructor(TypeLiteral<T> type) {
return (Constructor<T>) InjectionPoint.forConstructorOf(type).getMember();
}
private void processInjectionPoint(InjectionPoint injectionPoint) {
injectionPointsByType.put(injectionPoint.getDeclaringType(), injectionPoint);
injectionPoint.getDependencies().forEach(this::processDependency);
}
private void processInjectionPoints(Iterable<InjectionPoint> injectionPoint) {
injectionPoint.forEach(this::processInjectionPoint);
}
private void processInstanceInjections(TypeLiteral<?> type) {
InjectionPoint.forInstanceMethodsAndFields(type).forEach(this::processInjectionPoint);
}
private void processInjections(TypeLiteral<?> type) {
processInjectionPoint(InjectionPoint.forConstructorOf(type));
processInstanceInjections(type);
}
public static Stream<Dependency<?>> forInstanceMethodsAndFields(TypeLiteral<?> type) {
return InjectionPoint.forInstanceMethodsAndFields(type)
.stream()
.flatMap(point -> point.getDependencies().stream());
}
@Override
public Void visit(ConstructorBinding<? extends T> binding) {
final InjectionPoint point = binding.getConstructor();
scope(binding, rebind(binding).toConstructor((Constructor) point.getMember(), point.getDeclaringType()));
return null;
}
@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());
}
@Override public <T> Key<T> prepareMethod(Binder binder, Annotation annotation, Key<T> key, InjectionPoint injectionPoint) { return key; }
public SetMultimap<InjectionPoint, Dependency<?>> dependenciesByInjectionPoint() { return dependenciesByInjectionPoint; }
public SetMultimap<TypeLiteral<?>, InjectionPoint> injectionPointsByType() { return injectionPointsByType; }