public static <F> Provider<F> newFactory( TypeLiteral<F> factoryType, TypeLiteral<?> implementationType) { Map<Method, AssistedConstructor<?>> factoryMethodToConstructor = createMethodMapping(factoryType, implementationType); if (!factoryMethodToConstructor.isEmpty()) { return new FactoryProvider<>(factoryType, factoryMethodToConstructor); } else { return new FactoryProvider2<>(factoryType, Key.get(implementationType)); } }
/** * When a factory method is invoked, we create a child injector that binds all parameters, then * use that to get an instance of the return type. */ @Override public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable { if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } Provider<?> provider = getBindingFromNewInjector(method, args).getProvider(); try { return provider.get(); } catch (ProvisionException e) { // if this is an exception declared by the factory method, throw it as-is if (e.getErrorMessages().size() == 1) { Message onlyError = Iterables.getOnlyElement(e.getErrorMessages()); Throwable cause = onlyError.getCause(); if (cause != null && canRethrow(method, cause)) { throw cause; } } throw e; } }
/** * At injector-creation time, we initialize the invocation handler. At this time we make sure * all factory methods will be able to build the target types. */ @Inject public void initialize(Injector injector) { if (this.injector != null) { throw new ConfigurationException(Collections.singletonList(new Message(FactoryProvider2.class, "Factories.create() factories may only be used in one Injector!"))); } this.injector = injector; for (Method method : returnTypesByMethod.keySet()) { Object[] args = new Object[method.getParameterTypes().length]; Arrays.fill(args, "dummy object for validating Factories"); getBindingFromNewInjector(method, args); // throws if the binding isn't properly configured } }
for (TypeLiteral<?> param : params) { Key<?> paramKey = getKey(param, method, paramAnnotations[p++], errors); keys.add(assistKey(method, paramKey, errors));