diff --git a/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java b/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java index 5539bbc70..eadaedcb4 100644 --- a/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java +++ b/core/src/main/java/com/opensymphony/xwork2/inject/ContainerImpl.java @@ -231,6 +231,33 @@ class ContainerImpl implements Container { ) throws MissingDependencyException { final List> parameterInjectors = new ArrayList<>(); + final Iterator annotationsIterator = Arrays.asList(annotations).iterator(); + for (Class parameterType : parameterTypes) { + Inject annotation = findInject(annotationsIterator.next()); + String name = annotation == null ? defaultName : annotation.value(); + Key key = Key.newInstance(parameterType, name); + parameterInjectors.add(createParameterInjector(key, member)); + } + + return toArray(parameterInjectors); + } + + /** + * Gets parameter injectors with nulls for optional dependencies. + * + * @param member to which the parameters belong + * @param annotations on the parameters + * @param parameterTypes parameter types + * @return injections + */ + ParameterInjector[] getParametersInjectorsWithNulls( + M member, + Annotation[][] annotations, + Class[] parameterTypes, + String defaultName + ) throws MissingDependencyException { + final List> parameterInjectors = new ArrayList<>(); + final Iterator annotationsIterator = Arrays.asList(annotations).iterator(); for (Class parameterType : parameterTypes) { Inject annotation = findInject(annotationsIterator.next()); @@ -241,6 +268,8 @@ class ContainerImpl implements Container { } catch (MissingDependencyException e) { if (annotation != null && annotation.required()) { throw e; + } else { + parameterInjectors.add(createNullParameterInjector(key, member)); } } } @@ -258,6 +287,23 @@ class ContainerImpl implements Container { return new ParameterInjector<>(externalContext, factory); } + ParameterInjector createNullParameterInjector(Key key, Member member) throws MissingDependencyException { + final InternalFactory factory = new InternalFactory() { + @Override + public T create(InternalContext context) { + return null; + } + + @Override + public Class type() { + return key.getType(); + } + }; + + final ExternalContext externalContext = ExternalContext.newInstance(member, key, this); + return new ParameterInjector<>(externalContext, factory); + } + private ParameterInjector[] toArray(List> parameterInjections) { return parameterInjections.toArray(new ParameterInjector[0]); } @@ -367,7 +413,7 @@ class ContainerImpl implements Container { Inject inject, ContainerImpl container, Constructor constructor) throws MissingDependencyException { return constructor.getParameterTypes().length == 0 ? null // default constructor. - : container.getParametersInjectors( + : container.getParametersInjectorsWithNulls( constructor, constructor.getParameterAnnotations(), constructor.getParameterTypes(), @@ -425,18 +471,8 @@ class ContainerImpl implements Container { // First time through... constructionContext.startConstruction(); try { - if (constructor.getParameterCount() == 0) { - t = constructor.newInstance(); - } else if (constructor.getParameterCount() > 0 && parameterInjectors == null) { - t = constructor.newInstance(new Object[constructor.getParameterCount()]); - } else if (constructor.getParameterCount() > parameterInjectors.length) { - final Object[] parameters = getParameters(constructor, context, parameterInjectors); - final Object[] finalParameters = Arrays.copyOf(parameters, constructor.getParameterCount()); - t = constructor.newInstance(finalParameters); - } else { - final Object[] parameters = getParameters(constructor, context, parameterInjectors); - t = constructor.newInstance(parameters); - } + final Object[] parameters = getParameters(constructor, context, parameterInjectors); + t = constructor.newInstance(parameters); constructionContext.setProxyDelegates(t); } finally { constructionContext.finishConstruction();