Search in sources :

Example 56 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project mats3 by centiservice.

the class ListBeanDefinitions method listAllBeansDefinitions.

public static void listAllBeansDefinitions(ConfigurableListableBeanFactory configurableListableBeanFactory) {
    log.info("BeanDefinitionCount: " + configurableListableBeanFactory.getBeanDefinitionCount());
    String[] beanDefinitionNames = configurableListableBeanFactory.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
        BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition(beanDefinitionName);
        log.info("BeanDefinitionName: " + beanDefinitionName + ": BeanDefinition TYPE: " + beanDefinition.getClass().getSimpleName() + ": [" + beanDefinition + "]");
        String[] attributeNames = beanDefinition.attributeNames();
        log.info("  \\- AttributeNames: " + Arrays.asList(attributeNames));
        String[] dependsOn = beanDefinition.getDependsOn();
        if (dependsOn != null) {
            log.info("  \\ - dependsOn: " + Arrays.asList(dependsOn));
        }
        log.info("  \\ - factoryMethod: " + beanDefinition.getFactoryMethodName());
        log.info("  \\ - factoryBean: " + beanDefinition.getFactoryBeanName());
        // ?: Is this an AnnotatedBeanDefinition
        if (beanDefinition instanceof AnnotatedBeanDefinition) {
            MethodMetadata factoryMethodMetadata = ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata();
            if (factoryMethodMetadata != null) {
                if (!(factoryMethodMetadata instanceof StandardMethodMetadata)) {
                    throw new IllegalStateException("The FactoryMethodMetadata found is not of type" + " StandardMethodMetadata - thus cannot run getIntrospectedMethod() on it," + " BeanDefinition: [" + beanDefinition + "].");
                }
                StandardMethodMetadata factoryMethodMetadata_Standard = (StandardMethodMetadata) factoryMethodMetadata;
                log.info("  |- Classname: " + factoryMethodMetadata.getReturnTypeName() + ".");
                Method introspectedMethod = factoryMethodMetadata_Standard.getIntrospectedMethod();
                log.info("  \\- Method@: " + introspectedMethod);
                log.info("       - annotations:[" + Arrays.asList(introspectedMethod.getAnnotations()) + "]");
            }
            AnnotationMetadata metadata = ((AnnotatedBeanDefinition) beanDefinition).getMetadata();
            if (metadata != null) {
                log.info("  \\- AnnotationTypes: [" + metadata.getAnnotationTypes() + "]");
            }
        }
    }
}
Also used : AnnotatedBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition) MethodMetadata(org.springframework.core.type.MethodMetadata) StandardMethodMetadata(org.springframework.core.type.StandardMethodMetadata) Method(java.lang.reflect.Method) AnnotatedBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) StandardMethodMetadata(org.springframework.core.type.StandardMethodMetadata) AnnotationMetadata(org.springframework.core.type.AnnotationMetadata)

Example 57 with MethodMetadata

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

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

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

the class ConfigurationClassBeanDefinitionReader method loadBeanDefinitionsForBeanMethod.

/**
 * Read the given {@link BeanMethod}, registering bean definitions
 * with the BeanDefinitionRegistry based on its contents.
 */
// for RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE
@SuppressWarnings("deprecation")
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
    ConfigurationClass configClass = beanMethod.getConfigurationClass();
    MethodMetadata metadata = beanMethod.getMetadata();
    String methodName = metadata.getMethodName();
    // Do we need to mark the bean as skipped by its condition?
    if (this.conditionEvaluator.shouldSkip(beanMethod, ConfigurationPhase.REGISTER_BEAN)) {
        configClass.skippedBeanMethods.add(methodName);
        return;
    }
    if (configClass.skippedBeanMethods.contains(methodName)) {
        return;
    }
    AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
    Assert.state(bean != null, "No @Bean annotation attributes");
    // Consider name and any aliases
    List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
    String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
    // Register aliases even when overridden
    for (String alias : names) {
        this.registry.registerAlias(beanName, alias);
    }
    // Has this effectively been overridden before (e.g. via XML)?
    if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
        if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
            throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(), beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() + "' clashes with bean name for containing configuration class; please make those names unique!");
        }
        return;
    }
    BeanMethodBeanDefinition beanDef = new BeanMethodBeanDefinition(beanMethod, beanName);
    beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
    if (metadata.isStatic()) {
        // static @Bean method
        if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
            beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
        } else {
            beanDef.setBeanClassName(configClass.getMetadata().getClassName());
        }
        beanDef.setUniqueFactoryMethodName(methodName);
    } else {
        // instance @Bean method
        beanDef.setFactoryBeanName(configClass.getBeanName());
        beanDef.setUniqueFactoryMethodName(methodName);
    }
    if (metadata instanceof StandardMethodMetadata) {
        beanDef.setResolvedFactoryMethod(((StandardMethodMetadata) metadata).getIntrospectedMethod());
    }
    beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
    beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
    AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
    Autowire autowire = bean.getEnum("autowire");
    if (autowire.isAutowire()) {
        beanDef.setAutowireMode(autowire.value());
    }
    boolean autowireCandidate = bean.getBoolean("autowireCandidate");
    if (!autowireCandidate) {
        beanDef.setAutowireCandidate(false);
    }
    String initMethodName = bean.getString("initMethod");
    if (StringUtils.hasText(initMethodName)) {
        beanDef.setInitMethodName(initMethodName);
    }
    String destroyMethodName = bean.getString("destroyMethod");
    beanDef.setDestroyMethodName(destroyMethodName);
    // Consider scoping
    ScopedProxyMode proxyMode = ScopedProxyMode.NO;
    AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
    if (attributes != null) {
        beanDef.setScope(attributes.getString("value"));
        proxyMode = attributes.getEnum("proxyMode");
        if (proxyMode == ScopedProxyMode.DEFAULT) {
            proxyMode = ScopedProxyMode.NO;
        }
    }
    // Replace the original bean definition with the target one, if necessary
    BeanDefinition beanDefToRegister = beanDef;
    if (proxyMode != ScopedProxyMode.NO) {
        BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS);
        beanDefToRegister = new BeanMethodBeanDefinition((RootBeanDefinition) proxyDef.getBeanDefinition(), beanMethod, beanName);
    }
    if (logger.isTraceEnabled()) {
        logger.trace(String.format("Registering bean definition for @Bean method %s.%s()", configClass.getMetadata().getClassName(), beanName));
    }
    this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
Also used : AnnotationAttributes(org.springframework.core.annotation.AnnotationAttributes) BeanDefinitionStoreException(org.springframework.beans.factory.BeanDefinitionStoreException) ArrayList(java.util.ArrayList) RootBeanDefinition(org.springframework.beans.factory.support.RootBeanDefinition) AbstractBeanDefinition(org.springframework.beans.factory.support.AbstractBeanDefinition) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) AnnotatedGenericBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition) StandardMethodMetadata(org.springframework.core.type.StandardMethodMetadata) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) StandardAnnotationMetadata(org.springframework.core.type.StandardAnnotationMetadata) RootBeanDefinition(org.springframework.beans.factory.support.RootBeanDefinition) MethodMetadata(org.springframework.core.type.MethodMetadata) StandardMethodMetadata(org.springframework.core.type.StandardMethodMetadata) Autowire(org.springframework.beans.factory.annotation.Autowire)

Example 59 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project springframework-source-5.1.x by wb02125055.

the class ConfigurationClassBeanDefinitionReader method loadBeanDefinitionsForBeanMethod.

/**
 * Read the given {@link BeanMethod}, registering bean definitions
 * with the BeanDefinitionRegistry based on its contents.
 */
// for RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE
@SuppressWarnings("deprecation")
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
    ConfigurationClass configClass = beanMethod.getConfigurationClass();
    MethodMetadata metadata = beanMethod.getMetadata();
    String methodName = metadata.getMethodName();
    // Do we need to mark the bean as skipped by its condition? 如果没有标注@Conditional注解,直接返回false,跳过if中的逻辑.
    if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
        configClass.skippedBeanMethods.add(methodName);
        return;
    }
    if (configClass.skippedBeanMethods.contains(methodName)) {
        return;
    }
    // 获取@Bean注解对应的注解元数据信息
    AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
    Assert.state(bean != null, "No @Bean annotation attributes");
    // Consider name and any aliases
    List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
    // 获取bean的名称,如果在@Bean中指定了名称,就用指定的。否则使用方法名称作为bean的名称
    String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
    // Register aliases even when overridden
    for (String alias : names) {
        this.registry.registerAlias(beanName, alias);
    }
    // Has this effectively been overridden before (e.g. via XML)?
    if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
        if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
            throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(), beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() + "' clashes with bean name for containing configuration class; please make those names unique!");
        }
        return;
    }
    ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
    beanDef.setResource(configClass.getResource());
    beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
    // 标注@Bean注解的方法是否为static的.
    if (metadata.isStatic()) {
        // static @Bean method
        // 如果是static方法,则设置该bean的className为配置类的类名称
        beanDef.setBeanClassName(configClass.getMetadata().getClassName());
        // 工厂方法为当前标注@Bean注解的方法
        beanDef.setFactoryMethodName(methodName);
    } else {
        // instance @Bean method
        // 否则设置工厂bean为当前的配置类,工厂方法为当前方法,在初始化时会使用.
        beanDef.setFactoryBeanName(configClass.getBeanName());
        beanDef.setUniqueFactoryMethodName(methodName);
    }
    beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
    beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
    // 处理普通注解:@Lazy @Primary @DependsOn @Description
    AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
    // 判断bean是否允许自动注入
    Autowire autowire = bean.getEnum("autowire");
    if (autowire.isAutowire()) {
        beanDef.setAutowireMode(autowire.value());
    }
    // 判断该bean是否参与自动注入.
    boolean autowireCandidate = bean.getBoolean("autowireCandidate");
    if (!autowireCandidate) {
        beanDef.setAutowireCandidate(false);
    }
    // 获取bean的初始化方法
    String initMethodName = bean.getString("initMethod");
    if (StringUtils.hasText(initMethodName)) {
        beanDef.setInitMethodName(initMethodName);
    }
    // 获取bean的销毁方法
    String destroyMethodName = bean.getString("destroyMethod");
    beanDef.setDestroyMethodName(destroyMethodName);
    // Consider scoping
    ScopedProxyMode proxyMode = ScopedProxyMode.NO;
    AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
    if (attributes != null) {
        beanDef.setScope(attributes.getString("value"));
        proxyMode = attributes.getEnum("proxyMode");
        if (proxyMode == ScopedProxyMode.DEFAULT) {
            proxyMode = ScopedProxyMode.NO;
        }
    }
    // Replace the original bean definition with the target one, if necessary
    BeanDefinition beanDefToRegister = beanDef;
    if (proxyMode != ScopedProxyMode.NO) {
        BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS);
        beanDefToRegister = new ConfigurationClassBeanDefinition((RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
    }
    if (logger.isTraceEnabled()) {
        logger.trace(String.format("Registering bean definition for @Bean method %s.%s()", configClass.getMetadata().getClassName(), beanName));
    }
    // 将@Bean标注的方法解析为beanDefinition,并注册到bean定义注册中心
    this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
Also used : AnnotationAttributes(org.springframework.core.annotation.AnnotationAttributes) BeanDefinitionStoreException(org.springframework.beans.factory.BeanDefinitionStoreException) ArrayList(java.util.ArrayList) RootBeanDefinition(org.springframework.beans.factory.support.RootBeanDefinition) AnnotatedBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition) AbstractBeanDefinition(org.springframework.beans.factory.support.AbstractBeanDefinition) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) AnnotatedGenericBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) RootBeanDefinition(org.springframework.beans.factory.support.RootBeanDefinition) MethodMetadata(org.springframework.core.type.MethodMetadata) Autowire(org.springframework.beans.factory.annotation.Autowire)

Example 60 with MethodMetadata

use of org.springframework.core.type.MethodMetadata in project springframework-source-5.1.x by wb02125055.

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) throws IOException {
    // 处理@Component注解和@Configuration注解。@Configuration注解上也标注的是@Component,被@Configuration标注的配置类本身也是一个bean组件
    if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
        // Recursively process any member (nested) classes first
        // 处理内部类,类似如下
        /**
         * @Component
         * @Configuration
         * class ClassA {
         * 		@Component
         * 		@Configuration
         * 		@ComponentScan({""})
         *		class ClassB {
         *
         *		}
         * }
         */
        processMemberClasses(configClass, sourceClass);
    }
    // 处理@PropertySource注解
    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");
        }
    }
    // 处理@ComponentScan注解或者@ComponentScans注解,并将扫描包下的所有bean转换成填充之后的ConfigurationClass
    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
            // 解析@ComponentScan和@ComponentScans配置的扫描包所包含的类。例如:basePackages="com.wb.spring"。则会在该步
            // 骤中扫描出这个包及子包下的class,然后将其解析为BeanDefinition。
            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();
                }
                // 判断当前的bean定义是否为一个配置类,如果是配置类,继续递归解析
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                    // 递归调用parse方法,继续解析。
                    parse(bdCand.getBeanClassName(), holder.getBeanName());
                }
            }
        }
    }
    // 处理@Import注解。其中会调用子类中的selectImports方法,获取导入的Bean组件的名称.
    processImports(configClass, sourceClass, getImports(sourceClass), true);
    // 处理@ImportResource注解
    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);
        }
    }
    // 处理配置类中标注有@Bean注解的方法.
    Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
    for (MethodMetadata methodMetadata : beanMethods) {
        configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    }
    // Process default methods on interfaces
    // 处理接口的默认实现方法,jdk8之后,接口中的方法也可以有默认实现。所以默认接口中默认实现的方法上也可能标注有@Bean注解
    processInterfaces(configClass, sourceClass);
    // Process superclass, if any
    if (sourceClass.getMetadata().hasSuperClass()) {
        // 获取配置类的父类class名称
        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) AnnotatedBeanDefinition(org.springframework.beans.factory.annotation.AnnotatedBeanDefinition) AbstractBeanDefinition(org.springframework.beans.factory.support.AbstractBeanDefinition) BeanDefinition(org.springframework.beans.factory.config.BeanDefinition) BeanDefinitionHolder(org.springframework.beans.factory.config.BeanDefinitionHolder) MethodMetadata(org.springframework.core.type.MethodMetadata) Component(org.springframework.stereotype.Component) Nullable(org.springframework.lang.Nullable)

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