Search in sources :

Example 41 with AnnotationAttributes

use of org.springframework.core.annotation.AnnotationAttributes in project apollo by ctripcorp.

the class DefaultApolloConfigRegistrarHelper method registerBeanDefinitions.

@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableApolloConfig.class.getName()));
    final String[] namespaces = attributes.getStringArray("value");
    final int order = attributes.getNumber("order");
    final String[] resolvedNamespaces = this.resolveNamespaces(namespaces);
    PropertySourcesProcessor.addNamespaces(Lists.newArrayList(resolvedNamespaces), order);
    Map<String, Object> propertySourcesPlaceholderPropertyValues = new HashMap<>();
    // to make sure the default PropertySourcesPlaceholderConfigurer's priority is higher than PropertyPlaceholderConfigurer
    propertySourcesPlaceholderPropertyValues.put("order", 0);
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesPlaceholderConfigurer.class.getName(), PropertySourcesPlaceholderConfigurer.class, propertySourcesPlaceholderPropertyValues);
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesProcessor.class.getName(), PropertySourcesProcessor.class);
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloAnnotationProcessor.class.getName(), ApolloAnnotationProcessor.class);
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueProcessor.class.getName(), SpringValueProcessor.class);
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueDefinitionProcessor.class.getName(), SpringValueDefinitionProcessor.class);
}
Also used : AnnotationAttributes(org.springframework.core.annotation.AnnotationAttributes) SpringValueDefinitionProcessor(com.ctrip.framework.apollo.spring.property.SpringValueDefinitionProcessor) HashMap(java.util.HashMap) PropertySourcesProcessor(com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor) PropertySourcesPlaceholderConfigurer(org.springframework.context.support.PropertySourcesPlaceholderConfigurer) SpringValueProcessor(com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor) ApolloAnnotationProcessor(com.ctrip.framework.apollo.spring.annotation.ApolloAnnotationProcessor)

Example 42 with AnnotationAttributes

use of org.springframework.core.annotation.AnnotationAttributes 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)

Example 43 with AnnotationAttributes

use of org.springframework.core.annotation.AnnotationAttributes in project spring-framework by spring-projects.

the class AnnotationReadingVisitorUtils method convertClassValues.

public static AnnotationAttributes convertClassValues(Object annotatedElement, ClassLoader classLoader, AnnotationAttributes original, boolean classValuesAsString) {
    if (original == null) {
        return null;
    }
    AnnotationAttributes result = new AnnotationAttributes(original);
    AnnotationUtils.postProcessAnnotationAttributes(annotatedElement, result, classValuesAsString);
    for (Map.Entry<String, Object> entry : result.entrySet()) {
        try {
            Object value = entry.getValue();
            if (value instanceof AnnotationAttributes) {
                value = convertClassValues(annotatedElement, classLoader, (AnnotationAttributes) value, classValuesAsString);
            } else if (value instanceof AnnotationAttributes[]) {
                AnnotationAttributes[] values = (AnnotationAttributes[]) value;
                for (int i = 0; i < values.length; i++) {
                    values[i] = convertClassValues(annotatedElement, classLoader, values[i], classValuesAsString);
                }
                value = values;
            } else if (value instanceof Type) {
                value = (classValuesAsString ? ((Type) value).getClassName() : classLoader.loadClass(((Type) value).getClassName()));
            } else if (value instanceof Type[]) {
                Type[] array = (Type[]) value;
                Object[] convArray = (classValuesAsString ? new String[array.length] : new Class<?>[array.length]);
                for (int i = 0; i < array.length; i++) {
                    convArray[i] = (classValuesAsString ? array[i].getClassName() : classLoader.loadClass(array[i].getClassName()));
                }
                value = convArray;
            } else if (classValuesAsString) {
                if (value instanceof Class) {
                    value = ((Class<?>) value).getName();
                } else if (value instanceof Class[]) {
                    Class<?>[] clazzArray = (Class<?>[]) value;
                    String[] newValue = new String[clazzArray.length];
                    for (int i = 0; i < clazzArray.length; i++) {
                        newValue[i] = clazzArray[i].getName();
                    }
                    value = newValue;
                }
            }
            entry.setValue(value);
        } catch (Throwable ex) {
            // Class not found - can't resolve class reference in annotation attribute.
            result.put(entry.getKey(), ex);
        }
    }
    return result;
}
Also used : AnnotationAttributes(org.springframework.core.annotation.AnnotationAttributes) Type(org.springframework.asm.Type) Map(java.util.Map) LinkedMultiValueMap(org.springframework.util.LinkedMultiValueMap)

Example 44 with AnnotationAttributes

use of org.springframework.core.annotation.AnnotationAttributes in project spring-framework by spring-projects.

the class AnnotationReadingVisitorUtils method getMergedAnnotationAttributes.

/**
	 * Retrieve the merged attributes of the annotation of the given type,
	 * if any, from the supplied {@code attributesMap}.
	 * <p>Annotation attribute values appearing <em>lower</em> in the annotation
	 * hierarchy (i.e., closer to the declaring class) will override those
	 * defined <em>higher</em> in the annotation hierarchy.
	 * @param attributesMap the map of annotation attribute lists, keyed by
	 * annotation type name
	 * @param metaAnnotationMap the map of meta annotation relationships,
	 * keyed by annotation type name
	 * @param annotationName the fully qualified class name of the annotation
	 * type to look for
	 * @return the merged annotation attributes, or {@code null} if no
	 * matching annotation is present in the {@code attributesMap}
	 * @since 4.0.3
	 */
public static AnnotationAttributes getMergedAnnotationAttributes(LinkedMultiValueMap<String, AnnotationAttributes> attributesMap, Map<String, Set<String>> metaAnnotationMap, String annotationName) {
    // Get the unmerged list of attributes for the target annotation.
    List<AnnotationAttributes> attributesList = attributesMap.get(annotationName);
    if (attributesList == null || attributesList.isEmpty()) {
        return null;
    }
    // To start with, we populate the result with a copy of all attribute values
    // from the target annotation. A copy is necessary so that we do not
    // inadvertently mutate the state of the metadata passed to this method.
    AnnotationAttributes result = new AnnotationAttributes(attributesList.get(0));
    Set<String> overridableAttributeNames = new HashSet<>(result.keySet());
    overridableAttributeNames.remove(AnnotationUtils.VALUE);
    // Since the map is a LinkedMultiValueMap, we depend on the ordering of
    // elements in the map and reverse the order of the keys in order to traverse
    // "down" the annotation hierarchy.
    List<String> annotationTypes = new ArrayList<>(attributesMap.keySet());
    Collections.reverse(annotationTypes);
    // No need to revisit the target annotation type:
    annotationTypes.remove(annotationName);
    for (String currentAnnotationType : annotationTypes) {
        List<AnnotationAttributes> currentAttributesList = attributesMap.get(currentAnnotationType);
        if (!ObjectUtils.isEmpty(currentAttributesList)) {
            Set<String> metaAnns = metaAnnotationMap.get(currentAnnotationType);
            if (metaAnns != null && metaAnns.contains(annotationName)) {
                AnnotationAttributes currentAttributes = currentAttributesList.get(0);
                for (String overridableAttributeName : overridableAttributeNames) {
                    Object value = currentAttributes.get(overridableAttributeName);
                    if (value != null) {
                        // Store the value, potentially overriding a value from an attribute
                        // of the same name found higher in the annotation hierarchy.
                        result.put(overridableAttributeName, value);
                    }
                }
            }
        }
    }
    return result;
}
Also used : AnnotationAttributes(org.springframework.core.annotation.AnnotationAttributes) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 45 with AnnotationAttributes

use of org.springframework.core.annotation.AnnotationAttributes in project spring-framework by spring-projects.

the class RecursiveAnnotationArrayVisitor method visitAnnotation.

@Override
public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) {
    String annotationType = Type.getType(asmTypeDescriptor).getClassName();
    AnnotationAttributes nestedAttributes = new AnnotationAttributes(annotationType, this.classLoader);
    this.allNestedAttributes.add(nestedAttributes);
    return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader);
}
Also used : AnnotationAttributes(org.springframework.core.annotation.AnnotationAttributes)

Aggregations

AnnotationAttributes (org.springframework.core.annotation.AnnotationAttributes)90 Test (org.junit.jupiter.api.Test)17 ArrayList (java.util.ArrayList)8 LinkedHashSet (java.util.LinkedHashSet)7 AnnotationMetadata (org.springframework.core.type.AnnotationMetadata)7 Annotation (java.lang.annotation.Annotation)6 Method (java.lang.reflect.Method)6 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)3 Map (java.util.Map)3 AnnotatedBeanDefinition (org.springframework.beans.factory.annotation.AnnotatedBeanDefinition)3 ConditionOutcome (org.springframework.boot.autoconfigure.condition.ConditionOutcome)3 StandardAnnotationMetadata (org.springframework.core.type.StandardAnnotationMetadata)3 PropertySourcesProcessor (com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor)2 SpringValueDefinitionProcessor (com.ctrip.framework.apollo.spring.property.SpringValueDefinitionProcessor)2 DubboReference (org.apache.dubbo.config.annotation.DubboReference)2 ReferenceBean (org.apache.dubbo.config.spring.ReferenceBean)2 Test (org.junit.Test)2 AbstractBeanDefinition (org.springframework.beans.factory.support.AbstractBeanDefinition)2 BeanNameGenerator (org.springframework.beans.factory.support.BeanNameGenerator)2