Search in sources :

Example 46 with BeanDefinitionHolder

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

the class ConfigurationClassPostProcessor method processConfigBeanDefinitions.

/**
	 * Build and validate a configuration model based on the registry of
	 * {@link Configuration} classes.
	 */
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    String[] candidateNames = registry.getBeanDefinitionNames();
    for (String beanName : candidateNames) {
        BeanDefinition beanDef = registry.getBeanDefinition(beanName);
        if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        } else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
            configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
        }
    }
    // Return immediately if no @Configuration classes were found
    if (configCandidates.isEmpty()) {
        return;
    }
    // Sort by previously determined @Order value, if applicable
    Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {

        @Override
        public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
            int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
            int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
            return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
        }
    });
    // Detect any custom bean name generation strategy supplied through the enclosing application context
    SingletonBeanRegistry singletonRegistry = null;
    if (registry instanceof SingletonBeanRegistry) {
        singletonRegistry = (SingletonBeanRegistry) registry;
        if (!this.localBeanNameGeneratorSet && singletonRegistry.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
            BeanNameGenerator generator = (BeanNameGenerator) singletonRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
            this.componentScanBeanNameGenerator = generator;
            this.importBeanNameGenerator = generator;
        }
    }
    // Parse each @Configuration class
    ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        parser.parse(candidates);
        parser.validate();
        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);
        // Read the model and create bean definitions based on its content
        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
        }
        this.reader.loadBeanDefinitions(configClasses);
        alreadyParsed.addAll(configClasses);
        candidates.clear();
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
            String[] newCandidateNames = registry.getBeanDefinitionNames();
            Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
            Set<String> alreadyParsedClasses = new HashSet<>();
            for (ConfigurationClass configurationClass : alreadyParsed) {
                alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
            }
            for (String candidateName : newCandidateNames) {
                if (!oldCandidateNames.contains(candidateName)) {
                    BeanDefinition beanDef = registry.getBeanDefinition(candidateName);
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) && !alreadyParsedClasses.contains(beanDef.getBeanClassName())) {
                        candidates.add(new BeanDefinitionHolder(beanDef, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    } while (!candidates.isEmpty());
    // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
    if (singletonRegistry != null) {
        if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
            singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
        }
    }
    if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
        // Clear cache in externally provided MetadataReaderFactory; this is a no-op
        // for a shared cache since it'll be cleared by the ApplicationContext.
        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) CachingMetadataReaderFactory(org.springframework.core.type.classreading.CachingMetadataReaderFactory) SingletonBeanRegistry(org.springframework.beans.factory.config.SingletonBeanRegistry) AbstractBeanDefinition(org.springframework.beans.factory.support.AbstractBeanDefinition) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) BeanNameGenerator(org.springframework.beans.factory.support.BeanNameGenerator) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 47 with BeanDefinitionHolder

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

the class ConfigurationClassBeanDefinitionReader method registerBeanDefinitionForImportedConfigurationClass.

/**
	 * Register the {@link Configuration} class itself as a bean definition.
	 */
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
    AnnotationMetadata metadata = configClass.getMetadata();
    AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
    ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
    configBeanDef.setScope(scopeMetadata.getScopeName());
    String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
    AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
    configClass.setBeanName(configBeanName);
    if (logger.isDebugEnabled()) {
        logger.debug("Registered bean definition for imported class '" + configBeanName + "'");
    }
}
Also used : BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) AnnotatedGenericBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition) AnnotationMetadata(org.springframework.core.type.AnnotationMetadata)

Example 48 with BeanDefinitionHolder

use of org.springframework.beans.factory.config.BeanDefinitionHolder in project spring-security-oauth by spring-projects.

the class RestTemplateBeanDefinitionParser method doParse.

@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
    String accessTokenProviderRef = element.getAttribute("access-token-provider");
    builder.addConstructorArgReference(element.getAttribute("resource"));
    BeanDefinitionBuilder request = BeanDefinitionBuilder.genericBeanDefinition(DefaultAccessTokenRequest.class);
    request.setScope("request");
    request.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    request.addConstructorArgValue("#{request.parameterMap}");
    request.addPropertyValue("currentUri", "#{request.getAttribute('currentUri')}");
    BeanDefinitionHolder requestDefinition = new BeanDefinitionHolder(request.getRawBeanDefinition(), parserContext.getReaderContext().generateBeanName(request.getRawBeanDefinition()));
    parserContext.getRegistry().registerBeanDefinition(requestDefinition.getBeanName(), requestDefinition.getBeanDefinition());
    BeanDefinitionHolder requestHolder = ScopedProxyUtils.createScopedProxy(requestDefinition, parserContext.getRegistry(), false);
    BeanDefinitionBuilder scopedContext = BeanDefinitionBuilder.genericBeanDefinition(DefaultOAuth2ClientContext.class);
    scopedContext.setScope("session");
    scopedContext.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    BeanDefinitionHolder contextDefinition = new BeanDefinitionHolder(scopedContext.getRawBeanDefinition(), parserContext.getReaderContext().generateBeanName(scopedContext.getRawBeanDefinition()));
    parserContext.getRegistry().registerBeanDefinition(contextDefinition.getBeanName(), contextDefinition.getBeanDefinition());
    BeanDefinitionHolder contextHolder = ScopedProxyUtils.createScopedProxy(contextDefinition, parserContext.getRegistry(), false);
    scopedContext.addConstructorArgValue(requestHolder.getBeanDefinition());
    BeanDefinitionBuilder bareContext = BeanDefinitionBuilder.genericBeanDefinition(DefaultOAuth2ClientContext.class);
    BeanDefinitionBuilder context = BeanDefinitionBuilder.genericBeanDefinition(OAuth2ClientContextFactoryBean.class);
    context.addPropertyValue("scopedContext", contextHolder.getBeanDefinition());
    context.addPropertyValue("bareContext", bareContext.getBeanDefinition());
    context.addPropertyReference("resource", element.getAttribute("resource"));
    builder.addConstructorArgValue(context.getBeanDefinition());
    if (StringUtils.hasText(accessTokenProviderRef)) {
        builder.addPropertyReference("accessTokenProvider", accessTokenProviderRef);
    }
    parserContext.getDelegate().parsePropertyElements(element, builder.getBeanDefinition());
}
Also used : BeanDefinitionBuilder(org.springframework.beans.factory.support.BeanDefinitionBuilder) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder)

Example 49 with BeanDefinitionHolder

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

the class ScopedProxyBeanDefinitionDecorator method decorate.

@Override
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
    boolean proxyTargetClass = true;
    if (node instanceof Element) {
        Element ele = (Element) node;
        if (ele.hasAttribute(PROXY_TARGET_CLASS)) {
            proxyTargetClass = Boolean.valueOf(ele.getAttribute(PROXY_TARGET_CLASS));
        }
    }
    // Register the original bean definition as it will be referenced by the scoped proxy
    // and is relevant for tooling (validation, navigation).
    BeanDefinitionHolder holder = ScopedProxyUtils.createScopedProxy(definition, parserContext.getRegistry(), proxyTargetClass);
    String targetBeanName = ScopedProxyUtils.getTargetBeanName(definition.getBeanName());
    parserContext.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(definition.getBeanDefinition(), targetBeanName));
    return holder;
}
Also used : Element(org.w3c.dom.Element) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) BeanComponentDefinition(org.springframework.beans.factory.parsing.BeanComponentDefinition)

Example 50 with BeanDefinitionHolder

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

the class BeanDefinitionValueResolver method resolveValueIfNecessary.

/**
	 * Given a PropertyValue, return a value, resolving any references to other
	 * beans in the factory if necessary. The value could be:
	 * <li>A BeanDefinition, which leads to the creation of a corresponding
	 * new bean instance. Singleton flags and names of such "inner beans"
	 * are always ignored: Inner beans are anonymous prototypes.
	 * <li>A RuntimeBeanReference, which must be resolved.
	 * <li>A ManagedList. This is a special collection that may contain
	 * RuntimeBeanReferences or Collections that will need to be resolved.
	 * <li>A ManagedSet. May also contain RuntimeBeanReferences or
	 * Collections that will need to be resolved.
	 * <li>A ManagedMap. In this case the value may be a RuntimeBeanReference
	 * or Collection that will need to be resolved.
	 * <li>An ordinary object or {@code null}, in which case it's left alone.
	 * @param argName the name of the argument that the value is defined for
	 * @param value the value object to resolve
	 * @return the resolved object
	 */
public Object resolveValueIfNecessary(Object argName, Object value) {
    // to another bean to be resolved.
    if (value instanceof RuntimeBeanReference) {
        RuntimeBeanReference ref = (RuntimeBeanReference) value;
        return resolveReference(argName, ref);
    } else if (value instanceof RuntimeBeanNameReference) {
        String refName = ((RuntimeBeanNameReference) value).getBeanName();
        refName = String.valueOf(doEvaluate(refName));
        if (!this.beanFactory.containsBean(refName)) {
            throw new BeanDefinitionStoreException("Invalid bean name '" + refName + "' in bean reference for " + argName);
        }
        return refName;
    } else if (value instanceof BeanDefinitionHolder) {
        // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
        BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
        return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
    } else if (value instanceof BeanDefinition) {
        // Resolve plain BeanDefinition, without contained name: use dummy name.
        BeanDefinition bd = (BeanDefinition) value;
        String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(bd);
        return resolveInnerBean(argName, innerBeanName, bd);
    } else if (value instanceof ManagedArray) {
        // May need to resolve contained runtime references.
        ManagedArray array = (ManagedArray) value;
        Class<?> elementType = array.resolvedElementType;
        if (elementType == null) {
            String elementTypeName = array.getElementTypeName();
            if (StringUtils.hasText(elementTypeName)) {
                try {
                    elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
                    array.resolvedElementType = elementType;
                } catch (Throwable ex) {
                    // Improve the message by showing the context.
                    throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error resolving array type for " + argName, ex);
                }
            } else {
                elementType = Object.class;
            }
        }
        return resolveManagedArray(argName, (List<?>) value, elementType);
    } else if (value instanceof ManagedList) {
        // May need to resolve contained runtime references.
        return resolveManagedList(argName, (List<?>) value);
    } else if (value instanceof ManagedSet) {
        // May need to resolve contained runtime references.
        return resolveManagedSet(argName, (Set<?>) value);
    } else if (value instanceof ManagedMap) {
        // May need to resolve contained runtime references.
        return resolveManagedMap(argName, (Map<?, ?>) value);
    } else if (value instanceof ManagedProperties) {
        Properties original = (Properties) value;
        Properties copy = new Properties();
        for (Map.Entry<Object, Object> propEntry : original.entrySet()) {
            Object propKey = propEntry.getKey();
            Object propValue = propEntry.getValue();
            if (propKey instanceof TypedStringValue) {
                propKey = evaluate((TypedStringValue) propKey);
            }
            if (propValue instanceof TypedStringValue) {
                propValue = evaluate((TypedStringValue) propValue);
            }
            copy.put(propKey, propValue);
        }
        return copy;
    } else if (value instanceof TypedStringValue) {
        // Convert value to target type here.
        TypedStringValue typedStringValue = (TypedStringValue) value;
        Object valueObject = evaluate(typedStringValue);
        try {
            Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
            if (resolvedTargetType != null) {
                return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
            } else {
                return valueObject;
            }
        } catch (Throwable ex) {
            // Improve the message by showing the context.
            throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error converting typed String value for " + argName, ex);
        }
    } else {
        return evaluate(value);
    }
}
Also used : BeanCreationException(org.springframework.beans.factory.BeanCreationException) BeanDefinitionStoreException(org.springframework.beans.factory.BeanDefinitionStoreException) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) Properties(java.util.Properties) RuntimeBeanNameReference(org.springframework.beans.factory.config.RuntimeBeanNameReference) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) ArrayList(java.util.ArrayList) List(java.util.List) TypedStringValue(org.springframework.beans.factory.config.TypedStringValue) RuntimeBeanReference(org.springframework.beans.factory.config.RuntimeBeanReference) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Aggregations

BeanDefinitionHolder (org.springframework.beans.factory.config.BeanDefinitionHolder)94 BeanDefinition (org.springframework.beans.factory.config.BeanDefinition)30 RootBeanDefinition (org.springframework.beans.factory.support.RootBeanDefinition)20 AbstractBeanDefinition (org.springframework.beans.factory.support.AbstractBeanDefinition)18 Element (org.w3c.dom.Element)18 BeanComponentDefinition (org.springframework.beans.factory.parsing.BeanComponentDefinition)16 BeanDefinitionBuilder (org.springframework.beans.factory.support.BeanDefinitionBuilder)16 RuntimeBeanReference (org.springframework.beans.factory.config.RuntimeBeanReference)12 ManagedList (org.springframework.beans.factory.support.ManagedList)11 Node (org.w3c.dom.Node)11 ArrayList (java.util.ArrayList)8 ManagedMap (org.springframework.beans.factory.support.ManagedMap)6 LinkedHashSet (java.util.LinkedHashSet)5 Test (org.junit.jupiter.api.Test)5 BeanDefinitionStoreException (org.springframework.beans.factory.BeanDefinitionStoreException)5 AnnotatedGenericBeanDefinition (org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition)5 NamedNodeMap (org.w3c.dom.NamedNodeMap)5 NodeList (org.w3c.dom.NodeList)5 Method (java.lang.reflect.Method)4 HashSet (java.util.HashSet)4