Example usage for org.springframework.core MethodParameter forExecutable

List of usage examples for org.springframework.core MethodParameter forExecutable

Introduction

In this page you can find the example usage for org.springframework.core MethodParameter forExecutable.

Prototype

public static MethodParameter forExecutable(Executable executable, int parameterIndex) 

Source Link

Document

Create a new MethodParameter for the given method or constructor.

Usage

From source file:org.springframework.beans.factory.support.ConstructorResolver.java

/**
 * Create an array of arguments to invoke a constructor or factory method,
 * given the resolved constructor argument values.
 */// ww  w. j av a  2  s  .c  om
private ArgumentsHolder createArgumentArray(String beanName, RootBeanDefinition mbd,
        @Nullable ConstructorArgumentValues resolvedValues, BeanWrapper bw, Class<?>[] paramTypes,
        @Nullable String[] paramNames, Executable executable, boolean autowiring, boolean fallback)
        throws UnsatisfiedDependencyException {

    TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
    TypeConverter converter = (customConverter != null ? customConverter : bw);

    ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
    Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
    Set<String> autowiredBeanNames = new LinkedHashSet<>(4);

    for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
        Class<?> paramType = paramTypes[paramIndex];
        String paramName = (paramNames != null ? paramNames[paramIndex] : "");
        // Try to find matching constructor argument value, either indexed or generic.
        ConstructorArgumentValues.ValueHolder valueHolder = null;
        if (resolvedValues != null) {
            valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
            // If we couldn't find a direct match and are not supposed to autowire,
            // let's try the next generic, untyped argument value as fallback:
            // it could match after type conversion (for example, String -> int).
            if (valueHolder == null
                    && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
                valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
            }
        }
        if (valueHolder != null) {
            // We found a potential match - let's give it a try.
            // Do not consider the same value definition multiple times!
            usedValueHolders.add(valueHolder);
            Object originalValue = valueHolder.getValue();
            Object convertedValue;
            if (valueHolder.isConverted()) {
                convertedValue = valueHolder.getConvertedValue();
                args.preparedArguments[paramIndex] = convertedValue;
            } else {
                MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                try {
                    convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
                } catch (TypeMismatchException ex) {
                    throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName,
                            new InjectionPoint(methodParam),
                            "Could not convert argument value of type ["
                                    + ObjectUtils.nullSafeClassName(valueHolder.getValue())
                                    + "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
                }
                Object sourceHolder = valueHolder.getSource();
                if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
                    Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
                    args.resolveNecessary = true;
                    args.preparedArguments[paramIndex] = sourceValue;
                }
            }
            args.arguments[paramIndex] = convertedValue;
            args.rawArguments[paramIndex] = originalValue;
        } else {
            MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
            // No explicit match found: we're either supposed to autowire or
            // have to fail creating an argument array for the given constructor.
            if (!autowiring) {
                throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName,
                        new InjectionPoint(methodParam),
                        "Ambiguous argument values for parameter of type [" + paramType.getName()
                                + "] - did you specify the correct bean references as arguments?");
            }
            try {
                Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames,
                        converter, fallback);
                args.rawArguments[paramIndex] = autowiredArgument;
                args.arguments[paramIndex] = autowiredArgument;
                args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
                args.resolveNecessary = true;
            } catch (BeansException ex) {
                throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName,
                        new InjectionPoint(methodParam), ex);
            }
        }
    }

    for (String autowiredBeanName : autowiredBeanNames) {
        this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
        if (logger.isDebugEnabled()) {
            logger.debug("Autowiring by type from bean name '" + beanName + "' via "
                    + (executable instanceof Constructor ? "constructor" : "factory method")
                    + " to bean named '" + autowiredBeanName + "'");
        }
    }

    return args;
}

From source file:org.springframework.beans.factory.support.ConstructorResolver.java

/**
 * Resolve the prepared arguments stored in the given bean definition.
 *///from  w ww.  jav a 2  s .  c  om
private Object[] resolvePreparedArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
        Executable executable, Object[] argsToResolve, boolean fallback) {

    TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
    TypeConverter converter = (customConverter != null ? customConverter : bw);
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd,
            converter);
    Class<?>[] paramTypes = executable.getParameterTypes();

    Object[] resolvedArgs = new Object[argsToResolve.length];
    for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
        Object argValue = argsToResolve[argIndex];
        MethodParameter methodParam = MethodParameter.forExecutable(executable, argIndex);
        GenericTypeResolver.resolveParameterType(methodParam, executable.getDeclaringClass());
        if (argValue instanceof AutowiredArgumentMarker) {
            argValue = resolveAutowiredArgument(methodParam, beanName, null, converter, fallback);
        } else if (argValue instanceof BeanMetadataElement) {
            argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
        } else if (argValue instanceof String) {
            argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd);
        }
        Class<?> paramType = paramTypes[argIndex];
        try {
            resolvedArgs[argIndex] = converter.convertIfNecessary(argValue, paramType, methodParam);
        } catch (TypeMismatchException ex) {
            throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName,
                    new InjectionPoint(methodParam),
                    "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(argValue)
                            + "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
        }
    }
    return resolvedArgs;
}

From source file:org.springframework.cloud.stream.binder.kafka.streams.KafkaStreamsStreamListenerSetupMethodOrchestrator.java

private boolean methodParameterSupports(Method method) {
    boolean supports = false;
    for (int i = 0; i < method.getParameterCount(); i++) {
        MethodParameter methodParameter = MethodParameter.forExecutable(method, i);
        Class<?> parameterType = methodParameter.getParameterType();
        if (parameterType.equals(KStream.class) || parameterType.equals(KTable.class)
                || parameterType.equals(GlobalKTable.class)) {
            supports = true;//from ww w  .  ja  va 2s  .c  o m
        }
    }
    return supports;
}

From source file:org.springframework.cloud.stream.binder.kafka.streams.KafkaStreamsStreamListenerSetupMethodOrchestrator.java

@Override
@SuppressWarnings({ "unchecked" })
public Object[] adaptAndRetrieveInboundArguments(Method method, String inboundName,
        ApplicationContext applicationContext,
        StreamListenerParameterAdapter... streamListenerParameterAdapters) {
    Object[] arguments = new Object[method.getParameterTypes().length];
    for (int parameterIndex = 0; parameterIndex < arguments.length; parameterIndex++) {
        MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex);
        Class<?> parameterType = methodParameter.getParameterType();
        Object targetReferenceValue = null;
        if (methodParameter.hasParameterAnnotation(Input.class)) {
            targetReferenceValue = AnnotationUtils
                    .getValue(methodParameter.getParameterAnnotation(Input.class));
            Input methodAnnotation = methodParameter.getParameterAnnotation(Input.class);
            inboundName = methodAnnotation.value();
        } else if (arguments.length == 1 && StringUtils.hasText(inboundName)) {
            targetReferenceValue = inboundName;
        }// w w  w.ja  v  a  2  s  .  co  m
        if (targetReferenceValue != null) {
            Assert.isInstanceOf(String.class, targetReferenceValue, "Annotation value must be a String");
            Object targetBean = applicationContext.getBean((String) targetReferenceValue);
            BindingProperties bindingProperties = this.bindingServiceProperties
                    .getBindingProperties(inboundName);
            enableNativeDecodingForKTableAlways(parameterType, bindingProperties);
            //Retrieve the StreamsConfig created for this method if available.
            //Otherwise, create the StreamsBuilderFactory and get the underlying config.
            if (!this.methodStreamsBuilderFactoryBeanMap.containsKey(method)) {
                buildStreamsBuilderAndRetrieveConfig(method, applicationContext, inboundName);
            }
            try {
                StreamsBuilderFactoryBean streamsBuilderFactoryBean = this.methodStreamsBuilderFactoryBeanMap
                        .get(method);
                StreamsBuilder streamsBuilder = streamsBuilderFactoryBean.getObject();
                KafkaStreamsConsumerProperties extendedConsumerProperties = this.kafkaStreamsExtendedBindingProperties
                        .getExtendedConsumerProperties(inboundName);
                //get state store spec
                KafkaStreamsStateStoreProperties spec = buildStateStoreSpec(method);
                Serde<?> keySerde = this.keyValueSerdeResolver.getInboundKeySerde(extendedConsumerProperties);
                Serde<?> valueSerde = this.keyValueSerdeResolver
                        .getInboundValueSerde(bindingProperties.getConsumer(), extendedConsumerProperties);

                final KafkaConsumerProperties.StartOffset startOffset = extendedConsumerProperties
                        .getStartOffset();
                Topology.AutoOffsetReset autoOffsetReset = null;
                if (startOffset != null) {
                    switch (startOffset) {
                    case earliest:
                        autoOffsetReset = Topology.AutoOffsetReset.EARLIEST;
                        break;
                    case latest:
                        autoOffsetReset = Topology.AutoOffsetReset.LATEST;
                        break;
                    default:
                        break;
                    }
                }
                if (extendedConsumerProperties.isResetOffsets()) {
                    LOG.warn("Detected resetOffsets configured on binding " + inboundName + ". "
                            + "Setting resetOffsets in Kafka Streams binder does not have any effect.");
                }

                if (parameterType.isAssignableFrom(KStream.class)) {
                    KStream<?, ?> stream = getkStream(inboundName, spec, bindingProperties, streamsBuilder,
                            keySerde, valueSerde, autoOffsetReset);
                    KStreamBoundElementFactory.KStreamWrapper kStreamWrapper = (KStreamBoundElementFactory.KStreamWrapper) targetBean;
                    //wrap the proxy created during the initial target type binding with real object (KStream)
                    kStreamWrapper.wrap((KStream<Object, Object>) stream);
                    this.kafkaStreamsBindingInformationCatalogue
                            .addStreamBuilderFactory(streamsBuilderFactoryBean);
                    for (StreamListenerParameterAdapter streamListenerParameterAdapter : streamListenerParameterAdapters) {
                        if (streamListenerParameterAdapter.supports(stream.getClass(), methodParameter)) {
                            arguments[parameterIndex] = streamListenerParameterAdapter.adapt(kStreamWrapper,
                                    methodParameter);
                            break;
                        }
                    }
                    if (arguments[parameterIndex] == null
                            && parameterType.isAssignableFrom(stream.getClass())) {
                        arguments[parameterIndex] = stream;
                    }
                    Assert.notNull(arguments[parameterIndex], "Cannot convert argument " + parameterIndex
                            + " of " + method + "from " + stream.getClass() + " to " + parameterType);
                } else if (parameterType.isAssignableFrom(KTable.class)) {
                    String materializedAs = extendedConsumerProperties.getMaterializedAs();
                    String bindingDestination = this.bindingServiceProperties
                            .getBindingDestination(inboundName);
                    KTable<?, ?> table = getKTable(streamsBuilder, keySerde, valueSerde, materializedAs,
                            bindingDestination, autoOffsetReset);
                    KTableBoundElementFactory.KTableWrapper kTableWrapper = (KTableBoundElementFactory.KTableWrapper) targetBean;
                    //wrap the proxy created during the initial target type binding with real object (KTable)
                    kTableWrapper.wrap((KTable<Object, Object>) table);
                    this.kafkaStreamsBindingInformationCatalogue
                            .addStreamBuilderFactory(streamsBuilderFactoryBean);
                    arguments[parameterIndex] = table;
                } else if (parameterType.isAssignableFrom(GlobalKTable.class)) {
                    String materializedAs = extendedConsumerProperties.getMaterializedAs();
                    String bindingDestination = this.bindingServiceProperties
                            .getBindingDestination(inboundName);
                    GlobalKTable<?, ?> table = getGlobalKTable(streamsBuilder, keySerde, valueSerde,
                            materializedAs, bindingDestination, autoOffsetReset);
                    GlobalKTableBoundElementFactory.GlobalKTableWrapper globalKTableWrapper = (GlobalKTableBoundElementFactory.GlobalKTableWrapper) targetBean;
                    //wrap the proxy created during the initial target type binding with real object (KTable)
                    globalKTableWrapper.wrap((GlobalKTable<Object, Object>) table);
                    this.kafkaStreamsBindingInformationCatalogue
                            .addStreamBuilderFactory(streamsBuilderFactoryBean);
                    arguments[parameterIndex] = table;
                }
            } catch (Exception ex) {
                throw new IllegalStateException(ex);
            }
        } else {
            throw new IllegalStateException(StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
        }
    }
    return arguments;
}

From source file:org.springframework.cloud.stream.binder.kafka.streams.KafkaStreamsStreamListenerSetupMethodOrchestrator.java

private void validateStreamListenerMethod(StreamListener streamListener, Method method,
        String[] methodAnnotatedOutboundNames) {
    String methodAnnotatedInboundName = streamListener.value();
    if (methodAnnotatedOutboundNames != null) {
        for (String s : methodAnnotatedOutboundNames) {
            if (StringUtils.hasText(s)) {
                Assert.isTrue(isDeclarativeOutput(method, s), "Method must be declarative");
            }//from   w w  w .j av a2s  .  c  o m
        }
    }
    if (StringUtils.hasText(methodAnnotatedInboundName)) {
        int methodArgumentsLength = method.getParameterTypes().length;

        for (int parameterIndex = 0; parameterIndex < methodArgumentsLength; parameterIndex++) {
            MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex);
            Assert.isTrue(isDeclarativeInput(methodAnnotatedInboundName, methodParameter),
                    "Method must be declarative");
        }
    }
}