Search in sources :

Example 1 with TypedStringValue

use of org.springframework.beans.factory.config.TypedStringValue in project dubbo by alibaba.

the class DubboBeanDefinitionParser method parseParameters.

@SuppressWarnings("unchecked")
private static ManagedMap parseParameters(NodeList nodeList, RootBeanDefinition beanDefinition) {
    if (nodeList != null && nodeList.getLength() > 0) {
        ManagedMap parameters = null;
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node instanceof Element) {
                if ("parameter".equals(node.getNodeName()) || "parameter".equals(node.getLocalName())) {
                    if (parameters == null) {
                        parameters = new ManagedMap();
                    }
                    String key = ((Element) node).getAttribute("key");
                    String value = ((Element) node).getAttribute("value");
                    boolean hide = "true".equals(((Element) node).getAttribute("hide"));
                    if (hide) {
                        key = Constants.HIDE_KEY_PREFIX + key;
                    }
                    parameters.put(key, new TypedStringValue(value, String.class));
                }
            }
        }
        return parameters;
    }
    return null;
}
Also used : Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) TypedStringValue(org.springframework.beans.factory.config.TypedStringValue) ManagedMap(org.springframework.beans.factory.support.ManagedMap)

Example 2 with TypedStringValue

use of org.springframework.beans.factory.config.TypedStringValue in project spring-framework by spring-projects.

the class AutowireUtils method resolveReturnTypeForFactoryMethod.

/**
	 * Determine the target type for the generic return type of the given
	 * <em>generic factory method</em>, where formal type variables are declared
	 * on the given method itself.
	 * <p>For example, given a factory method with the following signature, if
	 * {@code resolveReturnTypeForFactoryMethod()} is invoked with the reflected
	 * method for {@code creatProxy()} and an {@code Object[]} array containing
	 * {@code MyService.class}, {@code resolveReturnTypeForFactoryMethod()} will
	 * infer that the target return type is {@code MyService}.
	 * <pre class="code">{@code public static <T> T createProxy(Class<T> clazz)}</pre>
	 * <h4>Possible Return Values</h4>
	 * <ul>
	 * <li>the target return type, if it can be inferred</li>
	 * <li>the {@linkplain Method#getReturnType() standard return type}, if
	 * the given {@code method} does not declare any {@linkplain
	 * Method#getTypeParameters() formal type variables}</li>
	 * <li>the {@linkplain Method#getReturnType() standard return type}, if the
	 * target return type cannot be inferred (e.g., due to type erasure)</li>
	 * <li>{@code null}, if the length of the given arguments array is shorter
	 * than the length of the {@linkplain
	 * Method#getGenericParameterTypes() formal argument list} for the given
	 * method</li>
	 * </ul>
	 * @param method the method to introspect (never {@code null})
	 * @param args the arguments that will be supplied to the method when it is
	 * invoked (never {@code null})
	 * @param classLoader the ClassLoader to resolve class names against,
	 * if necessary (never {@code null})
	 * @return the resolved target return type or the standard method return type
	 * @since 3.2.5
	 */
public static Class<?> resolveReturnTypeForFactoryMethod(Method method, Object[] args, ClassLoader classLoader) {
    Assert.notNull(method, "Method must not be null");
    Assert.notNull(args, "Argument array must not be null");
    Assert.notNull(classLoader, "ClassLoader must not be null");
    TypeVariable<Method>[] declaredTypeVariables = method.getTypeParameters();
    Type genericReturnType = method.getGenericReturnType();
    Type[] methodParameterTypes = method.getGenericParameterTypes();
    Assert.isTrue(args.length == methodParameterTypes.length, "Argument array does not match parameter count");
    // Ensure that the type variable (e.g., T) is declared directly on the method
    // itself (e.g., via <T>), not on the enclosing class or interface.
    boolean locallyDeclaredTypeVariableMatchesReturnType = false;
    for (TypeVariable<Method> currentTypeVariable : declaredTypeVariables) {
        if (currentTypeVariable.equals(genericReturnType)) {
            locallyDeclaredTypeVariableMatchesReturnType = true;
            break;
        }
    }
    if (locallyDeclaredTypeVariableMatchesReturnType) {
        for (int i = 0; i < methodParameterTypes.length; i++) {
            Type methodParameterType = methodParameterTypes[i];
            Object arg = args[i];
            if (methodParameterType.equals(genericReturnType)) {
                if (arg instanceof TypedStringValue) {
                    TypedStringValue typedValue = ((TypedStringValue) arg);
                    if (typedValue.hasTargetType()) {
                        return typedValue.getTargetType();
                    }
                    try {
                        return typedValue.resolveTargetType(classLoader);
                    } catch (ClassNotFoundException ex) {
                        throw new IllegalStateException("Failed to resolve value type [" + typedValue.getTargetTypeName() + "] for factory method argument", ex);
                    }
                }
                // Only consider argument type if it is a simple value...
                if (arg != null && !(arg instanceof BeanMetadataElement)) {
                    return arg.getClass();
                }
                return method.getReturnType();
            } else if (methodParameterType instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) methodParameterType;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                for (Type typeArg : actualTypeArguments) {
                    if (typeArg.equals(genericReturnType)) {
                        if (arg instanceof Class) {
                            return (Class<?>) arg;
                        } else {
                            String className = null;
                            if (arg instanceof String) {
                                className = (String) arg;
                            } else if (arg instanceof TypedStringValue) {
                                TypedStringValue typedValue = ((TypedStringValue) arg);
                                String targetTypeName = typedValue.getTargetTypeName();
                                if (targetTypeName == null || Class.class.getName().equals(targetTypeName)) {
                                    className = typedValue.getValue();
                                }
                            }
                            if (className != null) {
                                try {
                                    return ClassUtils.forName(className, classLoader);
                                } catch (ClassNotFoundException ex) {
                                    throw new IllegalStateException("Could not resolve class name [" + arg + "] for factory method argument", ex);
                                }
                            }
                            // For now, just fall back...
                            return method.getReturnType();
                        }
                    }
                }
            }
        }
    }
    // Fall back...
    return method.getReturnType();
}
Also used : Method(java.lang.reflect.Method) BeanMetadataElement(org.springframework.beans.BeanMetadataElement) ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) TypeVariable(java.lang.reflect.TypeVariable) TypedStringValue(org.springframework.beans.factory.config.TypedStringValue)

Example 3 with TypedStringValue

use of org.springframework.beans.factory.config.TypedStringValue in project spring-framework by spring-projects.

the class BeanDefinitionParserDelegate method buildTypedStringValueForMap.

/**
	 * Build a typed String value Object for the given raw value.
	 * @see org.springframework.beans.factory.config.TypedStringValue
	 */
protected final Object buildTypedStringValueForMap(String value, String defaultTypeName, Element entryEle) {
    try {
        TypedStringValue typedValue = buildTypedStringValue(value, defaultTypeName);
        typedValue.setSource(extractSource(entryEle));
        return typedValue;
    } catch (ClassNotFoundException ex) {
        error("Type class [" + defaultTypeName + "] not found for Map key/value type", entryEle, ex);
        return value;
    }
}
Also used : TypedStringValue(org.springframework.beans.factory.config.TypedStringValue)

Example 4 with TypedStringValue

use of org.springframework.beans.factory.config.TypedStringValue in project spring-framework by spring-projects.

the class BeanDefinitionParserDelegate method buildTypedStringValue.

/**
	 * Build a typed String value Object for the given raw value.
	 * @see org.springframework.beans.factory.config.TypedStringValue
	 */
protected TypedStringValue buildTypedStringValue(String value, String targetTypeName) throws ClassNotFoundException {
    ClassLoader classLoader = this.readerContext.getBeanClassLoader();
    TypedStringValue typedValue;
    if (!StringUtils.hasText(targetTypeName)) {
        typedValue = new TypedStringValue(value);
    } else if (classLoader != null) {
        Class<?> targetType = ClassUtils.forName(targetTypeName, classLoader);
        typedValue = new TypedStringValue(value, targetType);
    } else {
        typedValue = new TypedStringValue(value, targetTypeName);
    }
    return typedValue;
}
Also used : TypedStringValue(org.springframework.beans.factory.config.TypedStringValue)

Example 5 with TypedStringValue

use of org.springframework.beans.factory.config.TypedStringValue in project spring-framework by spring-projects.

the class DefaultListableBeanFactoryTests method testPrototypeStringCreatedRepeatedly.

@Test
public void testPrototypeStringCreatedRepeatedly() {
    DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
    RootBeanDefinition stringDef = new RootBeanDefinition(String.class);
    stringDef.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
    stringDef.getConstructorArgumentValues().addGenericArgumentValue(new TypedStringValue("value"));
    lbf.registerBeanDefinition("string", stringDef);
    String val1 = lbf.getBean("string", String.class);
    String val2 = lbf.getBean("string", String.class);
    assertEquals("value", val1);
    assertEquals("value", val2);
    assertNotSame(val1, val2);
}
Also used : DefaultListableBeanFactory(org.springframework.beans.factory.support.DefaultListableBeanFactory) RootBeanDefinition(org.springframework.beans.factory.support.RootBeanDefinition) TypedStringValue(org.springframework.beans.factory.config.TypedStringValue) Test(org.junit.Test)

Aggregations

TypedStringValue (org.springframework.beans.factory.config.TypedStringValue)24 Element (org.w3c.dom.Element)9 RootBeanDefinition (org.springframework.beans.factory.support.RootBeanDefinition)7 RuntimeBeanReference (org.springframework.beans.factory.config.RuntimeBeanReference)6 ManagedMap (org.springframework.beans.factory.support.ManagedMap)6 Test (org.junit.Test)5 BeanDefinition (org.springframework.beans.factory.config.BeanDefinition)5 Node (org.w3c.dom.Node)5 BeanDefinitionHolder (org.springframework.beans.factory.config.BeanDefinitionHolder)4 Method (java.lang.reflect.Method)3 BeanMetadataElement (org.springframework.beans.BeanMetadataElement)3 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 HashSet (java.util.HashSet)2 Mockito (org.mockito.Mockito)2 PropertyValue (org.springframework.beans.PropertyValue)2 BeanCreationException (org.springframework.beans.factory.BeanCreationException)2 BeanDefinitionBuilder (org.springframework.beans.factory.support.BeanDefinitionBuilder)2 ManagedList (org.springframework.beans.factory.support.ManagedList)2 NamedNodeMap (org.w3c.dom.NamedNodeMap)2