final MutablePicoContainer child = parent.makeChildContainer(); ComponentAdapter hashMapAdapter = parent.as(getProperties()).addAdapter(new ConstructorInjection.ConstructorInjector<HashMap>(HashMap.class, HashMap.class)) .getComponentAdapter(HashMap.class, (NameBinding) null); ComponentAdapter hashSetAdapter = parent.as(getProperties()).addAdapter(new ConstructorInjection.ConstructorInjector<HashSet>(HashSet.class, HashSet.class)) .getComponentAdapter(HashSet.class, (NameBinding) null); InstanceAdapter instanceAdapter = new InstanceAdapter<String>(String.class, "foo", ComponentAdapter stringAdapter = parent.as(getProperties()).addAdapter(instanceAdapter).getComponentAdapter(instanceAdapter.getComponentKey()); ComponentAdapter arrayListAdapter = child.as(getProperties()).addAdapter(new ConstructorInjection.ConstructorInjector<ArrayList>(ArrayList.class, ArrayList.class)) .getComponentAdapter(ArrayList.class, (NameBinding) null); Parameter componentParameter = BasicComponentParameter.BASIC_DEFAULT; Parameter throwableParameter = new ConstantParameter(new Throwable("bar")); ConstructorInjection.ConstructorInjector<Exception> ci = new ConstructorInjection.ConstructorInjector<Exception>(Exception.class, Exception.class, componentParameter, throwableParameter); ComponentAdapter exceptionAdapter = child.as(getProperties()).addAdapter(ci).getComponentAdapter(Exception.class, (NameBinding) null);
final Map<ResolverKey, Parameter.Resolver> resolvers = new HashMap<ResolverKey, Parameter.Resolver>(); if (sortedMatchingConstructors == null) { sortedMatchingConstructors = getSortedMatchingConstructors(); boolean failedDependency = false; Type[] parameterTypes = sortedMatchingConstructor.getGenericParameterTypes(); fixGenericParameterTypes(sortedMatchingConstructor, parameterTypes); Annotation[] bindings = getBindings(sortedMatchingConstructor.getParameterAnnotations()); final Parameter[] currentParameters = constructorParameters.getParams() != null ? constructorParameters.getParams() : createDefaultParameters(parameterTypes.length); Type expectedType = box(parameterTypes[j]); NameBinding expectedNameBinding = new ParameterNameBinding(getParanamer(), sortedMatchingConstructor, j); Parameter parameterToUse = getParameterToUse(sortedMatchingConstructor,j, currentParameters[j]); parametersUsed.set(j, parameterToUse); ResolverKey resolverKey = new ResolverKey(expectedType, useNames() ? expectedNameBinding.getName() : null, useNames(), bindings[j], parameterToUse); Parameter.Resolver resolver = resolvers.get(resolverKey); if (resolver == null) { Parameter currentParameter = parameterToUse; Annotation annotation = bindings[j]; boolean b = useNames(); resolver = currentParameter.resolve(container, this, null, expectedType, expectedNameBinding, b, annotation); resolvers.put(resolverKey, resolver); unsatisfiedDependency = box(parameterTypes[j]); unsatisfiedConstructor = sortedMatchingConstructor; failedDependency = true; throw new PicoCompositionException(conflicts.size() + " satisfiable constructors is too many for '"+getComponentImplementation()+"'. Constructor List:" + conflicts.toString().replace(getComponentImplementation().getName(),"<init>").replace("public <i","<i"));
@Override @SuppressWarnings("synthetic-access") public T run(final Object instance) { CtorAndAdapters<T> ctorAndAdapters = getGreediestSatisfiableConstructor(guardedContainer, getComponentImplementation()); ComponentMonitor monitor = currentMonitor(); Constructor<T> ctor = ctorAndAdapters.getConstructor(); try { changeAccessToModifierifNeeded(ctor); T inst = newInstance(ctor, ctorParameters); monitor.instantiated(container, ConstructorInjector.this, ctor, inst, ctorParameters, System.currentTimeMillis() - startTime); return caughtInstantiationException(monitor, ctor, e, container); } catch (IllegalAccessException e) { return caughtIllegalAccessException(monitor, ctor, e, container);
final Map<ResolverKey, Parameter.Resolver> resolvers = new HashMap<ResolverKey, Parameter.Resolver>(); if (sortedMatchingConstructors == null) { sortedMatchingConstructors = getSortedMatchingConstructors(); boolean failedDependency = false; Type[] parameterTypes = sortedMatchingConstructor.getGenericParameterTypes(); fixGenericParameterTypes(sortedMatchingConstructor, parameterTypes); Annotation[] bindings = getBindings(sortedMatchingConstructor.getParameterAnnotations()); final Parameter[] currentParameters = constructorParameters.getParams() != null ? constructorParameters.getParams() : createDefaultParameters(parameterTypes.length); Type expectedType = box(parameterTypes[j]); NameBinding expectedNameBinding = new ParameterNameBinding(getParanamer(), sortedMatchingConstructor, j); Parameter parameterToUse = getParameterToUse(sortedMatchingConstructor,j, currentParameters[j]); parametersUsed.set(j, parameterToUse); ResolverKey resolverKey = new ResolverKey(expectedType, useNames() ? expectedNameBinding.getName() : null, useNames(), bindings[j], parameterToUse); Parameter.Resolver resolver = resolvers.get(resolverKey); if (resolver == null) { Parameter currentParameter = parameterToUse; Annotation annotation = bindings[j]; boolean b = useNames(); resolver = currentParameter.resolve(container, this, null, expectedType, expectedNameBinding, b, annotation); resolvers.put(resolverKey, resolver); unsatisfiedDependency = box(parameterTypes[j]); unsatisfiedConstructor = sortedMatchingConstructor; failedDependency = true; throw new PicoCompositionException(conflicts.size() + " satisfiable constructors is too many for '"+getComponentImplementation()+"'. Constructor List:" + conflicts.toString().replace(getComponentImplementation().getName(),"<init>").replace("public <i","<i"));
inst = instantiationGuard.observe(getComponentImplementation(), null); decorate(inst, container); } finally { if (i_Instantiated) {
inst = instantiationGuard.observe(getComponentImplementation(), null); decorate(inst, container); } finally { if (i_Instantiated) {
@Override @SuppressWarnings("synthetic-access") public T run(final Object instance) { CtorAndAdapters<T> ctorAndAdapters = getGreediestSatisfiableConstructor(guardedContainer, getComponentImplementation()); ComponentMonitor monitor = currentMonitor(); Constructor<T> ctor = ctorAndAdapters.getConstructor(); try { changeAccessToModifierifNeeded(ctor); T inst = newInstance(ctor, ctorParameters); monitor.instantiated(container, ConstructorInjector.this, ctor, inst, ctorParameters, System.currentTimeMillis() - startTime); return caughtInstantiationException(monitor, ctor, e, container); } catch (IllegalAccessException e) { return caughtIllegalAccessException(monitor, ctor, e, container);
@Test public void testComponentAdapterRegistrationOrderIsMaintained() throws NoSuchMethodException { ConstructorInjection.ConstructorInjector c1 = new ConstructorInjection.ConstructorInjector<Object>("1", Object.class); ConstructorInjection.ConstructorInjector c2 = new ConstructorInjection.ConstructorInjector<String>("2", String.class); MutablePicoContainer picoContainer = createPicoContainer(null); picoContainer.addAdapter(c1).addAdapter(c2); Collection<ComponentAdapter<?>> list2 = picoContainer.getComponentAdapters(); //registration order should be maintained assertEquals(2, list2.size()); assertEquals(c1.getComponentKey(), ((ComponentAdapter)list2.toArray()[0]).getComponentKey()); assertEquals(c2.getComponentKey(), ((ComponentAdapter)list2.toArray()[1]).getComponentKey()); picoContainer.getComponents(); // create all the instances at once assertFalse("instances should be created in same order as adapters are created", picoContainer.getComponents().get(0) instanceof String); assertTrue("instances should be created in same order as adapters are created", picoContainer.getComponents().get(1) instanceof String); MutablePicoContainer reversedPicoContainer = createPicoContainer(null); reversedPicoContainer.addAdapter(c2); reversedPicoContainer.addAdapter(c1); //registration order should be maintained list2 = reversedPicoContainer.getComponentAdapters(); assertEquals(2, list2.size()); assertEquals(c2.getComponentKey(), ((ComponentAdapter)list2.toArray()[0]).getComponentKey()); assertEquals(c1.getComponentKey(), ((ComponentAdapter)list2.toArray()[1]).getComponentKey()); reversedPicoContainer.getComponents(); // create all the instances at once assertTrue("instances should be created in same order as adapters are created", reversedPicoContainer.getComponents().get(0) instanceof String); assertFalse("instances should be created in same order as adapters are created", reversedPicoContainer.getComponents().get(1) instanceof String); }
/** * Creates a ConstructorInjector * * @param key the search key for this implementation * @param impl the concrete implementation * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @param rememberChosenCtor remember the chosen constructor (to speed up second/subsequent calls) * @param parameters the parameters to use for the initialization * @throws com.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is <code>null</code> * @return */ public static <T> ComponentAdapter<T> constructor(final Object key, final Class<T> impl, final ComponentMonitor monitor, final boolean useNames, final boolean rememberChosenCtor, final Parameter... parameters) { return new ConstructorInjection.ConstructorInjector<T>(monitor, useNames, rememberChosenCtor, key, impl, new ConstructorParameters(parameters) ); }
/** * Creates a ConstructorInjector * * @param key the search key for this implementation * @param impl the concrete implementation * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @param parameters the parameters to use for the initialization * @throws com.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is <code>null</code> * @return */ public static <T> ComponentAdapter<T> constructor(final Object key, final Class<T> impl, final ComponentMonitor monitor, final boolean useNames, final Parameter... parameters) { return new ConstructorInjection.ConstructorInjector<T>(monitor, useNames, key, impl, new ConstructorParameters(parameters)); }
/** * Creates a ConstructorInjector * * @param key the search key for this implementation * @param impl the concrete implementation * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @param rememberChosenCtor remember the chosen constructor (to speed up second/subsequent calls) * @param parameters the parameters to use for the initialization * @throws com.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is <code>null</code> * @return */ public static <T> ComponentAdapter<T> constructor(final Object key, final Class<T> impl, final ComponentMonitor monitor, final boolean useNames, final boolean rememberChosenCtor, final Parameter... parameters) { return new ConstructorInjection.ConstructorInjector<T>(monitor, useNames, rememberChosenCtor, key, impl, new ConstructorParameters(parameters) ); }
/** * Creates a ConstructorInjector * * @param key the search key for this implementation * @param impl the concrete implementation * @param monitor the component monitor used by this addAdapter * @param useNames use argument names when looking up dependencies * @param parameters the parameters to use for the initialization * @throws com.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException * if the implementation is not a concrete class. * @throws NullPointerException if one of the parameters is <code>null</code> * @return */ public static <T> ComponentAdapter<T> constructor(final Object key, final Class<T> impl, final ComponentMonitor monitor, final boolean useNames, final Parameter... parameters) { return new ConstructorInjection.ConstructorInjector<T>(monitor, useNames, key, impl, new ConstructorParameters(parameters)); }
protected <T>ConstructorInjector<T> newConstructorInjector(final ComponentMonitor monitor, final Object key, final Class<T> impl, final boolean useNames, final ConstructorParameters parameters) { return new ConstructorInjector<T>(monitor, useNames, rememberChosenConstructor, key, impl, parameters); }
@Override public Object run(final Object inst) { final Constructor constructor = getGreediestSatisfiableConstructor(guardedContainer).getConstructor(); final Class[] parameterTypes = constructor.getParameterTypes(); final ConstructorParameters constructorParameters = (ConstructorParameters) (parameters != null && parameters.length > 0 ? parameters[0] : new ConstructorParameters()); final Parameter[] currentParameters = constructorParameters.getParams() != null ? constructorParameters.getParams() : createDefaultParameters(parameterTypes.length); for (int i = 0; i < currentParameters.length; i++) { currentParameters[i].verify(container, ConstructorInjector.this, box(parameterTypes[i]), new ParameterNameBinding(getParanamer(), constructor, i), useNames(), getBindings(constructor.getParameterAnnotations())[i]); } return null; } };
@Override public Object run(final Object inst) { final Constructor constructor = getGreediestSatisfiableConstructor(guardedContainer).getConstructor(); final Class[] parameterTypes = constructor.getParameterTypes(); final ConstructorParameters constructorParameters = (ConstructorParameters) (parameters != null && parameters.length > 0 ? parameters[0] : new ConstructorParameters()); final Parameter[] currentParameters = constructorParameters.getParams() != null ? constructorParameters.getParams() : createDefaultParameters(parameterTypes.length); for (int i = 0; i < currentParameters.length; i++) { currentParameters[i].verify(container, ConstructorInjector.this, box(parameterTypes[i]), new ParameterNameBinding(getParanamer(), constructor, i), useNames(), getBindings(constructor.getParameterAnnotations())[i]); } return null; } };
protected <T>ConstructorInjector<T> newConstructorInjector(final ComponentMonitor monitor, final Object key, final Class<T> impl, final boolean useNames, final ConstructorParameters parameters) { return new ConstructorInjector<T>(monitor, useNames, rememberChosenConstructor, key, impl, parameters); }
/** * Constructor injector that uses no monitor and no lifecycle adapter. This is a more * convenient constructor for use when instantiating a constructor injector directly. * * @param key the search key for this implementation * @param impl the concrete implementation * @param parameters the parameters used for initialization * @return */ public static <T> ComponentAdapter<T> constructor(final Object key, final Class<T> impl, final Parameter... parameters) { return new ConstructorInjection.ConstructorInjector<T>(key, impl, new ConstructorParameters(parameters)); }
@SuppressWarnings("unchecked") public MultiInjector(final Object key, final Class<T> impl, final ComponentMonitor monitor, final String setterPrefix, final boolean useNames, final boolean useAllParameter, final ConstructorParameters constructorParams, final FieldParameters[] fieldParams, final MethodParameters[] methodParams) { super(key, impl, monitor, useNames, monitor.newInjector(new ConstructorInjection.ConstructorInjector<T>(monitor, useNames, key, impl, constructorParams)), monitor.newInjector(new SetterInjection.SetterInjector<T>(key, impl, monitor, setterPrefix, useNames, "", false, methodParams)), monitor.newInjector(new AnnotatedMethodInjection.AnnotatedMethodInjector<T>(key, impl, methodParams, monitor, useNames, useAllParameter, Inject.class, getInjectionAnnotation("javax.inject.Inject"))), monitor.newInjector(new AnnotatedFieldInjection.AnnotatedFieldInjector<T>(key, impl, fieldParams, monitor, useNames, useAllParameter, Inject.class, getInjectionAnnotation("javax.inject.Inject"))) ); }
public <T> ComponentAdapter<T> createComponentAdapter(final ComponentMonitor monitor, final LifecycleStrategy lifecycle, final Properties properties, final Object key, final Class<T> impl, final ConstructorParameters constructorParams, final FieldParameters[] fieldParams, final MethodParameters[] methodParams) throws PicoCompositionException { boolean useNames = AbstractBehavior.arePropertiesPresent(properties, Characteristics.USE_NAMES, true); ConstructorInjector<T> injector = newConstructorInjector(monitor, key, impl, useNames, constructorParams); injector.enableEmjection(AbstractBehavior.removePropertiesIfPresent(properties, Characteristics.EMJECTION_ENABLED)); return wrapLifeCycle(monitor.newInjector(injector), lifecycle); }
/** * Constructor injector that uses no monitor and no lifecycle adapter. This is a more * convenient constructor for use when instantiating a constructor injector directly. * * @param key the search key for this implementation * @param impl the concrete implementation * @param parameters the parameters used for initialization * @return */ public static <T> ComponentAdapter<T> constructor(final Object key, final Class<T> impl, final Parameter... parameters) { return new ConstructorInjection.ConstructorInjector<T>(key, impl, new ConstructorParameters(parameters)); }