Search in sources :

Example 61 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project spring-framework-5.2.9.RELEASE by somepeopleHavingDream.

the class SimpleAnnotationMetadataReadingVisitor method visitEnd.

@Override
public void visitEnd() {
    String[] memberClassNames = StringUtils.toStringArray(this.memberClassNames);
    MethodMetadata[] annotatedMethods = this.annotatedMethods.toArray(new MethodMetadata[0]);
    MergedAnnotations annotations = MergedAnnotations.of(this.annotations);
    this.metadata = new SimpleAnnotationMetadata(this.className, this.access, this.enclosingClassName, this.superClassName, this.independentInnerClass, this.interfaceNames, memberClassNames, annotatedMethods, annotations);
}
Also used : MethodMetadata(org.springframework.core.type.MethodMetadata) MergedAnnotations(org.springframework.core.annotation.MergedAnnotations)

Example 62 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project jeeagile by jeeagile.

the class AgileDubboReferencePostProcessor method processReferenceAnnotatedBeanDefinition.

/**
 * process @DubboReference at java-config @bean method
 * <pre class="code">
 * &#064;Configuration
 * public class ConsumerConfig {
 *
 *      &#064;Bean
 *      &#064;DubboReference(group="demo", version="1.2.3")
 *      public ReferenceBean&lt;DemoService&gt; demoService() {
 *          return new ReferenceBean();
 *      }
 *
 * }
 * </pre>
 *
 * @param beanName
 * @param beanDefinition
 */
private void processReferenceAnnotatedBeanDefinition(String beanName, AnnotatedBeanDefinition beanDefinition) {
    MethodMetadata factoryMethodMetadata = SpringCompatUtils.getFactoryMethodMetadata(beanDefinition);
    Class beanClass = getBeanFactory().getType(beanName);
    if (beanClass == Object.class) {
        beanClass = SpringCompatUtils.getGenericTypeOfReturnType(factoryMethodMetadata);
    }
    if (beanClass == Object.class) {
        // bean class is invalid, ignore it
        return;
    }
    if (beanClass == null) {
        String beanMethodSignature = factoryMethodMetadata.getDeclaringClassName() + "#" + factoryMethodMetadata.getMethodName() + "()";
        throw new BeanCreationException("The ReferenceBean is missing necessary generic type, which returned by the @Bean method of Java-config class. " + "The generic type of the returned ReferenceBean must be specified as the referenced interface type, " + "such as ReferenceBean<DemoService>. Please check bean method: " + beanMethodSignature);
    }
    // get dubbo reference annotation attributes
    Map<String, Object> annotationAttributes = null;
    // try all dubbo reference annotation types
    for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
        if (factoryMethodMetadata.isAnnotated(annotationType.getName())) {
            annotationAttributes = factoryMethodMetadata.getAnnotationAttributes(annotationType.getName());
            annotationAttributes = filterDefaultValues(annotationType, annotationAttributes);
        }
    }
    if (annotationAttributes != null) {
        // @DubboReference on @Bean method
        LinkedHashMap<String, Object> attributes = new LinkedHashMap<>(annotationAttributes);
        // reset id attribute
        attributes.put(ReferenceAttributes.ID, beanName);
        // convert annotation props
        ReferenceBeanSupport.convertReferenceProps(attributes, beanClass);
        // get interface
        String interfaceName = (String) attributes.get(ReferenceAttributes.INTERFACE);
        // check beanClass and reference interface class
        if (!StringUtils.isEquals(interfaceName, beanClass.getName()) && beanClass != GenericService.class) {
            String beanMethodSignature = factoryMethodMetadata.getDeclaringClassName() + "#" + factoryMethodMetadata.getMethodName() + "()";
            throw new BeanCreationException("The 'interfaceClass' or 'interfaceName' attribute value of @DubboReference annotation " + "is inconsistent with the generic type of the ReferenceBean returned by the bean method. " + "The interface class of @DubboReference is: " + interfaceName + ", but return ReferenceBean<" + beanClass.getName() + ">. " + "Please remove the 'interfaceClass' and 'interfaceName' attributes from @DubboReference annotation. " + "Please check bean method: " + beanMethodSignature);
        }
        Class interfaceClass = beanClass;
        // set attribute instead of property values
        beanDefinition.setAttribute(Constants.REFERENCE_PROPS, attributes);
        beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, interfaceClass);
        beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, interfaceName);
    } else {
        // raw reference bean
        // the ReferenceBean is not yet initialized
        beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, beanClass);
        if (beanClass != GenericService.class) {
            beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, beanClass.getName());
        }
    }
    // set id
    beanDefinition.getPropertyValues().add(ReferenceAttributes.ID, beanName);
}
Also used : BeanCreationException(org.springframework.beans.factory.BeanCreationException) GenericService(org.apache.dubbo.rpc.service.GenericService) MethodMetadata(org.springframework.core.type.MethodMetadata) LinkedHashMap(java.util.LinkedHashMap)

Example 63 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project spring-framework-debug by Joker-5.

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
 */
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {
    if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
        // Recursively process any member (nested) classes first
        processMemberClasses(configClass, sourceClass, filter);
    }
    // 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.info("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 needed
            for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                if (bdCand == null) {
                    bdCand = holder.getBeanDefinition();
                }
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                    parse(bdCand.getBeanClassName(), holder.getBeanName());
                }
            }
        }
    }
    // Process any @Import annotations
    processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
    // Process any @ImportResource annotations
    AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
    if (importResource != null) {
        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 != null && !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) AbstractBeanDefinition(org.springframework.beans.factory.support.AbstractBeanDefinition) AnnotatedBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) ConfigurableEnvironment(org.springframework.core.env.ConfigurableEnvironment) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) MethodMetadata(org.springframework.core.type.MethodMetadata) Component(org.springframework.stereotype.Component) Nullable(org.springframework.lang.Nullable)

Example 64 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project spring-framework-debug by Joker-5.

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 65 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project spring-framework-debug by Joker-5.

the class ConfigurationClassPostProcessor method enhanceConfigurationClasses.

/**
 * Post-processes a BeanFactory in search of Configuration class BeanDefinitions;
 * any candidates are then enhanced by a {@link ConfigurationClassEnhancer}.
 * Candidate status is determined by BeanDefinition attribute metadata.
 * @see ConfigurationClassEnhancer
 */
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
    Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
    for (String beanName : beanFactory.getBeanDefinitionNames()) {
        BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
        Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
        AnnotationMetadata annotationMetadata = null;
        MethodMetadata methodMetadata = null;
        if (beanDef instanceof AnnotatedBeanDefinition) {
            AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDef;
            annotationMetadata = annotatedBeanDefinition.getMetadata();
            methodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata();
        }
        if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
            // Configuration class (full or lite) or a configuration-derived @Bean method
            // -> eagerly resolve bean class at this point, unless it's a 'lite' configuration
            // or component class without @Bean methods.
            AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
            if (!abd.hasBeanClass()) {
                boolean liteConfigurationCandidateWithoutBeanMethods = (ConfigurationClassUtils.CONFIGURATION_CLASS_LITE.equals(configClassAttr) && annotationMetadata != null && !ConfigurationClassUtils.hasBeanMethods(annotationMetadata));
                if (!liteConfigurationCandidateWithoutBeanMethods) {
                    try {
                        abd.resolveBeanClass(this.beanClassLoader);
                    } catch (Throwable ex) {
                        throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
                    }
                }
            }
        }
        if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
            if (!(beanDef instanceof AbstractBeanDefinition)) {
                throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
            } else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
                logger.info("Cannot enhance @Configuration bean definition '" + beanName + "' since its singleton instance has been created too early. The typical cause " + "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + "return type: Consider declaring such methods as 'static'.");
            }
            configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
        }
    }
    if (configBeanDefs.isEmpty()) {
        // nothing to enhance -> return immediately
        return;
    }
    ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
    for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
        AbstractBeanDefinition beanDef = entry.getValue();
        // If a @Configuration class gets proxied, always proxy the target class
        beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
        // Set enhanced subclass of the user-specified bean class
        Class<?> configClass = beanDef.getBeanClass();
        Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
        if (configClass != enhancedClass) {
            if (logger.isTraceEnabled()) {
                logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " + "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
            }
            beanDef.setBeanClass(enhancedClass);
        }
    }
}
Also used : AnnotatedBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition) AbstractBeanDefinition(org.springframework.beans.factory.support.AbstractBeanDefinition) BeanDefinitionStoreException(org.springframework.beans.factory.BeanDefinitionStoreException) AnnotatedBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition) AbstractBeanDefinition(org.springframework.beans.factory.support.AbstractBeanDefinition) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) AnnotationMetadata(org.springframework.core.type.AnnotationMetadata) LinkedHashMap(java.util.LinkedHashMap) MethodMetadata(org.springframework.core.type.MethodMetadata) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Aggregations

MethodMetadata (org.springframework.core.type.MethodMetadata)73 AnnotatedBeanDefinition (org.springframework.beans.factory.annotation.AnnotatedBeanDefinition)33 BeanDefinition (org.springframework.beans.factory.config.BeanDefinition)32 AbstractBeanDefinition (org.springframework.beans.factory.support.AbstractBeanDefinition)20 AnnotationMetadata (org.springframework.core.type.AnnotationMetadata)15 StandardMethodMetadata (org.springframework.core.type.StandardMethodMetadata)14 ArrayList (java.util.ArrayList)12 BeanDefinitionHolder (org.springframework.beans.factory.config.BeanDefinitionHolder)12 AnnotationAttributes (org.springframework.core.annotation.AnnotationAttributes)12 RootBeanDefinition (org.springframework.beans.factory.support.RootBeanDefinition)11 Map (java.util.Map)10 StandardAnnotationMetadata (org.springframework.core.type.StandardAnnotationMetadata)10 Method (java.lang.reflect.Method)9 AnnotatedGenericBeanDefinition (org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition)9 BeanDefinitionRegistry (org.springframework.beans.factory.support.BeanDefinitionRegistry)8 Bean (org.springframework.context.annotation.Bean)8 IOException (java.io.IOException)6 HashSet (java.util.HashSet)6 BeanDefinitionBuilder (org.springframework.beans.factory.support.BeanDefinitionBuilder)6 NestedIOException (org.springframework.core.NestedIOException)6