zoukankan      html  css  js  c++  java
  • Spring源码解析之Configuration注解

    1、Spring有一个内部的BeanFactoryPostProcessor:

      org.springframework.context.annotation.internalConfigurationAnnotationProcessor (id)

        --------->   ConfigurationClassPostProcessor(实现类)

          --------->BeanDefinitionRegistryPostProcessor(接口)

             --------->BeanFactoryPostProcessor(接口)

           该类负责解析处理所有@Configuration标签类,并将Bean定义注册到BeanFactory中。

      该类的来源:

        AnnotationConfigApplicationContext类
        1、AnnotationConfigApplicationContext annotationConfigApplicationContext=new AnnotationConfigApplicationContext(ConfigAOP.class);
          2、this();
            3、this.reader = new AnnotatedBeanDefinitionReader(this);
         AnnotatedBeanDefinitionReader类:
              4、this(registry, getOrCreateEnvironment(registry));
                5、AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
         AnnotationConfigUtils类:
                  6、registerAnnotationConfigProcessors(registry, null);

     2、ConfigurationClassPostProcessor类的被解析位置

          refresh(); -------------------AnnotationConfigApplicationContext.class
            invokeBeanFactoryPostProcessors(beanFactory); ----------------------------AbstractApplicationContext.class
              PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
                                                     -----------------PostProcessorRegistrationDelegate.class

    3、ConfigurationClassPostProcessor类的作用:

    @Override
    	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    		int registryId = System.identityHashCode(registry);
    		if (this.registriesPostProcessed.contains(registryId)) {
    			throw new IllegalStateException(
    					"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    		}
    		if (this.factoriesPostProcessed.contains(registryId)) {
    			throw new IllegalStateException(
    					"postProcessBeanFactory already called on this post-processor against " + registry);
    		}
    		this.registriesPostProcessed.add(registryId);
    
    		processConfigBeanDefinitions(registry);//真正的解析的方法
    	}
    	public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    		List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
                    //此时获取到的bean只有框架自定义bean(名字以internal开头)以及传入的配置类
    		String[] candidateNames = registry.getBeanDefinitionNames();
    
    		for (String beanName : candidateNames) {
    			BeanDefinition beanDef = registry.getBeanDefinition(beanName);//获取bean定义
    			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
    					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
    				if (logger.isDebugEnabled()) {
    					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
    				}
    			}
    			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
    				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
    			}
    		}
    
    		// configCandidates数组保存的是带有@Configuration的类名
    		if (configCandidates.isEmpty()) {
    			return;
    		}
    
    		// Sort by previously determined @Order value, if applicable
    		Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
    			@Override
    			public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
    				int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
    				int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
    				return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
    			}
    		});
    
    		// Detect any custom bean name generation strategy supplied through the enclosing application context
    		SingletonBeanRegistry sbr = null;
    		if (registry instanceof SingletonBeanRegistry) {
    			sbr = (SingletonBeanRegistry) registry;
    			if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
    				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
    				this.componentScanBeanNameGenerator = generator;
    				this.importBeanNameGenerator = generator;
    			}
    		}
    
    		// Parse each @Configuration class
    		ConfigurationClassParser parser = new ConfigurationClassParser(
    				this.metadataReaderFactory, this.problemReporter, this.environment,
    				this.resourceLoader, this.componentScanBeanNameGenerator, registry);
    
    		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
    		Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
    		do {
    			parser.parse(candidates);//开始解析,详情看下一段代码
    			parser.validate();
    
    			Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
    			configClasses.removeAll(alreadyParsed);
    
    			// Read the model and create bean definitions based on its content
    			if (this.reader == null) {
    				this.reader = new ConfigurationClassBeanDefinitionReader(
    						registry, this.sourceExtractor, this.resourceLoader, this.environment,
    						this.importBeanNameGenerator, parser.getImportRegistry());
    			}
    			this.reader.loadBeanDefinitions(configClasses);
    			alreadyParsed.addAll(configClasses);
    
    			candidates.clear();
    			if (registry.getBeanDefinitionCount() > candidateNames.length) {
    				String[] newCandidateNames = registry.getBeanDefinitionNames();
    				Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
    				Set<String> alreadyParsedClasses = new HashSet<String>();
    				for (ConfigurationClass configurationClass : alreadyParsed) {
    					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
    				}
    				for (String candidateName : newCandidateNames) {
    					if (!oldCandidateNames.contains(candidateName)) {
    						BeanDefinition bd = registry.getBeanDefinition(candidateName);
    						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
    								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
    							candidates.add(new BeanDefinitionHolder(bd, candidateName));
    						}
    					}
    				}
    				candidateNames = newCandidateNames;
    			}
    		}
    		while (!candidates.isEmpty());
    
    		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
    		if (sbr != null) {
    			if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
    				sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
    			}
    		}
    
    		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
    			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    		}
    	}    

    ConfigurationClassParser将会进行如下解析处理:

    • 处理嵌套的MemberClass
    • 处理@PropertySource标签,用来解析属性文件并设置到Environment中。
    • 处理@ComponentScan标签,扫描package下的所有Class并进行迭代解析。
    • 处理@Import标签。
    • 处理@ImportResource标签。
    • 处理@Bean标签。
    • 处理所有继承的Interface上的@Bean标签。
    • 处理SuperClass。
    • 处理标签中的DeferredImport。
    	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 needed
    				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;
    	}
    

      

  • 相关阅读:
    Android零碎知识(一)
    Android零碎知识
    归属地查询(联网+本地)
    XML文件生成——借助JDOM
    XML文件生成
    Win32汇编语言语法基础
    Nmap 常用命令语法
    Flask 框架基础知识笔记
    Web前端开发JQuery框架
    Web前端开发JavaScript提高
  • 原文地址:https://www.cnblogs.com/yaohuiqin/p/10523471.html
Copyright © 2011-2022 走看看