Search in sources :

Example 6 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project spring-framework by spring-projects.

the class ConfigurationClassParser method retrieveBeanMethodMetadata.

/**
	 * Retrieve the metadata for all <code>@Bean</code> methods.
	 */
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
    AnnotationMetadata original = sourceClass.getMetadata();
    Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
    if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
        // order, even between different runs of the same application on the same JVM.
        try {
            AnnotationMetadata asm = this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
            Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
            if (asmMethods.size() >= beanMethods.size()) {
                Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
                for (MethodMetadata asmMethod : asmMethods) {
                    for (MethodMetadata beanMethod : beanMethods) {
                        if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
                            selectedMethods.add(beanMethod);
                            break;
                        }
                    }
                }
                if (selectedMethods.size() == beanMethods.size()) {
                    // All reflection-detected methods found in ASM method set -> proceed
                    beanMethods = selectedMethods;
                }
            }
        } catch (IOException ex) {
            logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
        // No worries, let's continue with the reflection metadata we started with...
        }
    }
    return beanMethods;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) StandardAnnotationMetadata(org.springframework.core.type.StandardAnnotationMetadata) MethodMetadata(org.springframework.core.type.MethodMetadata) IOException(java.io.IOException) NestedIOException(org.springframework.core.NestedIOException) AnnotationMetadata(org.springframework.core.type.AnnotationMetadata) StandardAnnotationMetadata(org.springframework.core.type.StandardAnnotationMetadata)

Example 7 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project spring-framework by spring-projects.

the class ConfigurationClassParser method processInterfaces.

/**
	 * Register default methods on interfaces implemented by the configuration class.
	 */
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
    for (SourceClass ifc : sourceClass.getInterfaces()) {
        Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
        for (MethodMetadata methodMetadata : beanMethods) {
            if (!methodMetadata.isAbstract()) {
                // A default method or other concrete method on a Java 8+ interface...
                configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
            }
        }
        processInterfaces(configClass, ifc);
    }
}
Also used : MethodMetadata(org.springframework.core.type.MethodMetadata)

Example 8 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project spring-framework by spring-projects.

the class ConfigurationClassParser method doProcessConfigurationClass.

/**
	 * Apply processing and build a complete {@link ConfigurationClass} by reading the
	 * annotations, members and methods from the source class. This method can be called
	 * multiple times as relevant sources are discovered.
	 * @param configClass the configuration class being build
	 * @param sourceClass a source class
	 * @return the superclass, or {@code null} if none found or previously processed
	 */
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
    // Recursively process any member (nested) classes first
    processMemberClasses(configClass, sourceClass);
    // Process any @PropertySource annotations
    for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) {
        if (this.environment instanceof ConfigurableEnvironment) {
            processPropertySource(propertySource);
        } else {
            logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment");
        }
    }
    // Process any @ComponentScan annotations
    Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
    if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
        for (AnnotationAttributes componentScan : componentScans) {
            // The config class is annotated with @ComponentScan -> perform the scan immediately
            Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
            // Check the set of scanned definitions for any further config classes and parse recursively if necessary
            for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) {
                    parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
                }
            }
        }
    }
    // Process any @Import annotations
    processImports(configClass, sourceClass, getImports(sourceClass), true);
    // Process any @ImportResource annotations
    if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
        AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
        String[] resources = importResource.getStringArray("locations");
        Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
        for (String resource : resources) {
            String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
            configClass.addImportedResource(resolvedResource, readerClass);
        }
    }
    // Process individual @Bean methods
    Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
    for (MethodMetadata methodMetadata : beanMethods) {
        configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    }
    // Process default methods on interfaces
    processInterfaces(configClass, sourceClass);
    // Process superclass, if any
    if (sourceClass.getMetadata().hasSuperClass()) {
        String superclass = sourceClass.getMetadata().getSuperClassName();
        if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
            this.knownSuperclasses.put(superclass, configClass);
            // Superclass found, return its annotation metadata and recurse
            return sourceClass.getSuperClass();
        }
    }
    // No superclass -> processing is complete
    return null;
}
Also used : AnnotationAttributes(org.springframework.core.annotation.AnnotationAttributes) ConfigurableEnvironment(org.springframework.core.env.ConfigurableEnvironment) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) MethodMetadata(org.springframework.core.type.MethodMetadata)

Aggregations

MethodMetadata (org.springframework.core.type.MethodMetadata)8 AnnotatedBeanDefinition (org.springframework.beans.factory.annotation.AnnotatedBeanDefinition)2 BeanDefinition (org.springframework.beans.factory.config.BeanDefinition)2 BeanDefinitionHolder (org.springframework.beans.factory.config.BeanDefinitionHolder)2 RootBeanDefinition (org.springframework.beans.factory.support.RootBeanDefinition)2 AnnotationAttributes (org.springframework.core.annotation.AnnotationAttributes)2 AnnotationMetadata (org.springframework.core.type.AnnotationMetadata)2 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1 Test (org.junit.Test)1 AnnotatedGenericBeanDefinition (org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition)1 Autowire (org.springframework.beans.factory.annotation.Autowire)1 AbstractBeanDefinition (org.springframework.beans.factory.support.AbstractBeanDefinition)1 ConditionAndOutcome (org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcome)1 ConditionAndOutcomes (org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcomes)1 ConditionOutcome (org.springframework.boot.autoconfigure.condition.ConditionOutcome)1 Bean (org.springframework.context.annotation.Bean)1