protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
    AnnotationMetadata metadata = configClass.getMetadata();
    if (this.environment != null && ProfileHelper.isProfileAnnotationPresent(metadata)) {
      if (!this.environment.acceptsProfiles(ProfileHelper.getCandidateProfiles(metadata))) {
        return;
      }
    }

    while (metadata != null) {
      doProcessConfigurationClass(configClass, metadata);
      String superClassName = metadata.getSuperClassName();
      if (superClassName != null && !Object.class.getName().equals(superClassName)) {
        if (metadata instanceof StandardAnnotationMetadata) {
          Class<?> clazz = ((StandardAnnotationMetadata) metadata).getIntrospectedClass();
          metadata = new StandardAnnotationMetadata(clazz.getSuperclass());
        } else {
          MetadataReader reader = this.metadataReaderFactory.getMetadataReader(superClassName);
          metadata = reader.getAnnotationMetadata();
        }
      } else {
        metadata = null;
      }
    }
    if (this.configurationClasses.contains(configClass) && configClass.getBeanName() != null) {
      // Explicit bean definition found, probably replacing an import.
      // Let's remove the old one and go with the new one.
      this.configurationClasses.remove(configClass);
    }

    this.configurationClasses.add(configClass);
  }
 private void processFeatureAnnotations(AnnotationMetadata metadata) {
   try {
     for (String annotationType : metadata.getAnnotationTypes()) {
       MetadataReader metadataReader =
           new SimpleMetadataReaderFactory().getMetadataReader(annotationType);
       if (metadataReader.getAnnotationMetadata().isAnnotated(FeatureAnnotation.class.getName())) {
         Map<String, Object> annotationAttributes =
             metadataReader
                 .getAnnotationMetadata()
                 .getAnnotationAttributes(FeatureAnnotation.class.getName(), true);
         // TODO SPR-7420: this is where we can catch user-defined types and avoid instantiating
         // them for STS purposes
         FeatureAnnotationParser processor =
             (FeatureAnnotationParser)
                 BeanUtils.instantiateClass(
                     Class.forName((String) annotationAttributes.get("parser")));
         FeatureSpecification spec = processor.process(metadata);
         spec.execute(this.specificationContext);
       }
     }
   } catch (BeanDefinitionParsingException ex) {
     throw ex;
   } catch (Exception ex) {
     // TODO SPR-7420: what exception to throw?
     throw new RuntimeException(ex);
   }
 }
Пример #3
0
 /** method adds all the method names to map with annotation attribute value as key */
 private static void findAnnotationMethods(
     final Class<? extends Annotation> annotationClass, final String attributeName)
     throws IOException {
   final String basePackagePath =
       ClassUtils.convertClassNameToResourcePath(
           new StandardEnvironment().resolveRequiredPlaceholders(SEARCH_PACKAGE));
   final String packageSearchPath =
       ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + basePackagePath + "/" + RESOURCE_PATTERN;
   final Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
   for (final Resource resource : resources) {
     if (resource.isReadable()) {
       final MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
       final Set<MethodMetadata> metadataSet =
           metadataReader.getAnnotationMetadata().getAnnotatedMethods(annotationClass.getName());
       if (metadataSet != null && metadataSet.size() > 0) {
         for (final MethodMetadata metadata : metadataSet) {
           final Map<String, Object> attributes =
               metadata.getAnnotationAttributes(annotationClass.getName());
           final JobName attributeValue = (JobName) attributes.get(attributeName);
           final String className = metadata.getDeclaringClassName();
           final String[] mapVal = {className, metadata.getMethodName()};
           targetMethosMap.put(attributeValue.toString(), mapVal);
         }
       }
     }
   }
 }
  /** Register the {@link Configuration} class itself as a bean definition. */
  private void doLoadBeanDefinitionForConfigurationClassIfNecessary(
      ConfigurationClass configClass) {
    if (configClass.getBeanName() != null) {
      // a bean definition already exists for this configuration class -> nothing to do
      return;
    }

    // no bean definition exists yet -> this must be an imported configuration class (@Import).
    BeanDefinition configBeanDef = new GenericBeanDefinition();
    String className = configClass.getMetadata().getClassName();
    configBeanDef.setBeanClassName(className);
    if (checkConfigurationClassCandidate(configBeanDef, this.metadataReaderFactory)) {
      String configBeanName =
          BeanDefinitionReaderUtils.registerWithGeneratedName(configBeanDef, this.registry);
      configClass.setBeanName(configBeanName);
      if (logger.isDebugEnabled()) {
        logger.debug(
            String.format(
                "Registered bean definition for imported @Configuration class %s", configBeanName));
      }
    } else {
      try {
        MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
        AnnotationMetadata metadata = reader.getAnnotationMetadata();
        this.problemReporter.error(
            new InvalidConfigurationImportProblem(className, reader.getResource(), metadata));
      } catch (IOException ex) {
        throw new IllegalStateException("Could not create MetadataReader for class " + className);
      }
    }
  }
 @Test
 public void asmAnnotationMetadataForSubclass() throws Exception {
   MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
   MetadataReader metadataReader =
       metadataReaderFactory.getMetadataReader(AnnotatedComponentSubClass.class.getName());
   AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
   doTestSubClassAnnotationInfo(metadata);
 }
 @Test
 public void asmAnnotationMetadataForAnnotation() throws Exception {
   MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
   MetadataReader metadataReader =
       metadataReaderFactory.getMetadataReader(Component.class.getName());
   AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
   doTestMetadataForAnnotationClass(metadata);
 }
 /** https://jira.spring.io/browse/SPR-11649 */
 @Test
 public void multipleAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor()
     throws Exception {
   MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
   MetadataReader metadataReader =
       metadataReaderFactory.getMetadataReader(NamedAnnotationsClass.class.getName());
   AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
   assertMultipleAnnotationsWithIdenticalAttributeNames(metadata);
 }
 @Test
 public void metaAnnotationOverridesUsingAnnotationMetadataReadingVisitor() throws Exception {
   MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
   MetadataReader metadataReader =
       metadataReaderFactory.getMetadataReader(
           ComposedConfigurationWithAttributeOverridesClass.class.getName());
   AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
   assertMetaAnnotationOverrides(metadata);
 }
 /**
  * Determine whether the given class does not match any exclude filter and does match at least one
  * include filter.
  *
  * @param metadataReader the ASM ClassReader for the class
  * @return whether the class qualifies as a candidate component
  */
 protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
   for (TypeFilter tf : this.excludeFilters) {
     if (tf.match(metadataReader, this.metadataReaderFactory)) {
       return false;
     }
   }
   for (TypeFilter tf : this.includeFilters) {
     if (tf.match(metadataReader, this.metadataReaderFactory)) {
       AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
       if (!metadata.isAnnotated(Profile.class.getName())) {
         return true;
       }
       AnnotationAttributes profile = MetadataUtils.attributesFor(metadata, Profile.class);
       return this.environment.acceptsProfiles(profile.getStringArray("value"));
     }
   }
   return false;
 }
  /**
   * Check whether the given bean definition is a candidate for a configuration class, and mark it
   * accordingly.
   *
   * @param beanDef the bean definition to check
   * @param metadataReaderFactory the current factory in use by the caller
   * @return whether the candidate qualifies as (any kind of) configuration class
   */
  public static boolean checkConfigurationClassCandidate(
      BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
    AnnotationMetadata metadata = null;

    // Check already loaded Class if present...
    // since we possibly can't even load the class file for this Class.
    if (beanDef instanceof AbstractBeanDefinition
        && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
      metadata = new StandardAnnotationMetadata(((AbstractBeanDefinition) beanDef).getBeanClass());
    } else {
      String className = beanDef.getBeanClassName();
      if (className != null) {
        try {
          MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
          metadata = metadataReader.getAnnotationMetadata();
        } catch (IOException ex) {
          if (logger.isDebugEnabled()) {
            logger.debug(
                "Could not find class file for introspecting factory methods: " + className, ex);
          }
          return false;
        }
      }
    }

    if (metadata != null) {
      if (metadata.isAnnotated(Configuration.class.getName())) {
        beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
        return true;
      } else if (metadata.isAnnotated(Component.class.getName())
          || metadata.hasAnnotatedMethods(Bean.class.getName())) {
        beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
        return true;
      }
    }
    return false;
  }
  protected void doProcessConfigurationClass(
      ConfigurationClass configClass, AnnotationMetadata metadata) throws IOException {

    // recursively process any member (nested) classes first
    for (String memberClassName : metadata.getMemberClassNames()) {
      MetadataReader reader = this.metadataReaderFactory.getMetadataReader(memberClassName);
      AnnotationMetadata memberClassMetadata = reader.getAnnotationMetadata();
      if (isConfigurationCandidate(memberClassMetadata)) {
        processConfigurationClass(new ConfigurationClass(reader, null));
      }
    }

    // process any @PropertySource annotations
    Map<String, Object> propertySourceAttributes =
        metadata.getAnnotationAttributes(
            org.springframework.context.annotation.PropertySource.class.getName());
    if (propertySourceAttributes != null) {
      String name = (String) propertySourceAttributes.get("name");
      String[] locations = (String[]) propertySourceAttributes.get("value");
      ClassLoader classLoader = this.resourceLoader.getClassLoader();
      for (String location : locations) {
        location = this.environment.resolveRequiredPlaceholders(location);
        ResourcePropertySource ps =
            StringUtils.hasText(name)
                ? new ResourcePropertySource(name, location, classLoader)
                : new ResourcePropertySource(location, classLoader);
        this.propertySources.push(ps);
      }
    }

    // process any @ComponentScan annotions
    Map<String, Object> componentScanAttributes =
        metadata.getAnnotationAttributes(ComponentScan.class.getName());
    if (componentScanAttributes != null) {
      // the config class is annotated with @ComponentScan -> perform the scan immediately
      Set<BeanDefinitionHolder> scannedBeanDefinitions =
          this.componentScanParser.parse(componentScanAttributes);

      // 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(), metadataReaderFactory)) {
          try {
            this.parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
          } catch (ConflictingBeanDefinitionException ex) {
            throw new CircularComponentScanException(
                "A conflicting bean definition was detected while processing @ComponentScan annotations. "
                    + "This usually indicates a circle between scanned packages.",
                ex);
          }
        }
      }
    }

    // process any @Import annotations
    List<Map<String, Object>> allImportAttribs =
        AnnotationUtils.findAllAnnotationAttributes(Import.class, metadata.getClassName(), true);
    for (Map<String, Object> importAttribs : allImportAttribs) {
      processImport(configClass, (String[]) importAttribs.get("value"), true);
    }

    // process any @ImportResource annotations
    if (metadata.isAnnotated(ImportResource.class.getName())) {
      String[] resources =
          (String[]) metadata.getAnnotationAttributes(ImportResource.class.getName()).get("value");
      Class<?> readerClass =
          (Class<?>) metadata.getAnnotationAttributes(ImportResource.class.getName()).get("reader");
      if (readerClass == null) {
        throw new IllegalStateException(
            "No reader class associated with imported resources: "
                + StringUtils.arrayToCommaDelimitedString(resources));
      }
      for (String resource : resources) {
        configClass.addImportedResource(resource, readerClass);
      }
    }

    // process individual @Bean methods
    Set<MethodMetadata> beanMethods = metadata.getAnnotatedMethods(Bean.class.getName());
    for (MethodMetadata methodMetadata : beanMethods) {
      configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    }
  }