【Spring】【03】解析配置類註冊BeanDefination

銀真發表於2020-11-13

1.new AnnotationConfigApplicationContext

1.1new DefaultListableBeanFactory賦值成成員變數beanFactory

BeanFacotry包含一個beanDefinitionMap和三級快取,BeanDefinationMap用來儲存bean資訊
三級快取儲存bean資訊

  public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
	
  }

  public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
    private final DefaultListableBeanFactory beanFactory; 
	
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}
  }  

  public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
		
		/** List of bean definition names, in registration order */
		private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
		/** Map of bean definition objects, keyed by bean name */
		private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
  }

  public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {}
  
  public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {}
  
  public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {}  
  
  public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	 /** Cache of singleton objects: bean name --> bean instance */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

	/** Cache of singleton factories: bean name --> ObjectFactory */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

	/** Cache of early singleton objects: bean name --> bean instance */
	private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
  }

1.2初始化AnnotatedBeanDefinitionReader,通過reader向beanDefinationMap中註冊一個BeanDefinationRegistryPostProcessor(ConfigerationClassPostProcessor)

  public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
	
	private final AnnotatedBeanDefinitionReader reader;
	
    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
		register(annotatedClasses);
		refresh();
	}
  
    public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
	}
  }
  
  public class AnnotatedBeanDefinitionReader {
    private final BeanDefinitionRegistry registry;
  
	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		this(registry, getOrCreateEnvironment(registry));
	}
    
	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		this.registry = registry;
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

  }
  
  public class AnnotationConfigUtils {
  
	public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
		registerAnnotationConfigProcessors(registry, null);
	}
	
	public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, Object source) {
			
		public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
			"org.springframework.context.annotation.internalConfigurationAnnotationProcessor";	
			
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		
	
	}

	private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) {
		if (registry instanceof DefaultListableBeanFactory) {
			return (DefaultListableBeanFactory) registry;
		}
		else if (registry instanceof GenericApplicationContext) {
			return ((GenericApplicationContext) registry).getDefaultListableBeanFactory();
		}
		else {
			return null;
		}
	}
  
  }

1.3通過AnnotatedBeanDefinitionReader向beanDefinationMap中註冊主配置類

  public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

    private final AnnotatedBeanDefinitionReader reader;

    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
		register(annotatedClasses);
		refresh();
	}
	
	public void register(Class<?>... annotatedClasses) {
		Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
		this.reader.register(annotatedClasses);
	}
	
  }

1.4再refresh方法中呼叫 BeanFactoryPostProcessor ( ConfigerationClassPostProcessor)的方法,解析@ComponentScan @import @bean註解註冊成bean定義

1.4.1 先呼叫BeanDefinationRegistryPostProcessor的介面方法(PriorityOrdered介面、Order介面、兩個介面都沒有實現的)

1.4.2 再呼叫BeanFactoryPostProcessor的介面方法

	public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext, DisposableBean {
	
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
		
		
			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);
			
			
		}
	}	
	
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
	}
	
	
	
  }
  
  class PostProcessorRegistrationDelegate {
  
     public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        
		if (beanFactory instanceof BeanDefinitionRegistry) {
		
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
					new LinkedList<BeanDefinitionRegistryPostProcessor>();
		
			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
					
			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}

			sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
			registryPostProcessors.addAll(priorityOrderedPostProcessors);
			invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);	
		
			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(beanFactory, orderedPostProcessors);
			registryPostProcessors.addAll(orderedPostProcessors);
			invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
			
			
			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
						registryPostProcessors.add(pp);
						processedBeans.add(ppName);
						pp.postProcessBeanDefinitionRegistry(registry);
						reiterate = true;
					}
				}
			}
			
			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
		
		
		
		}
	 }
  
  }

1.4.3ConfigurationClassPostProcessor的BeanDefinitionRegistryPostProcessor的介面方法postProcessBeanDefinitionRegistry

   
   public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
   
       void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
   }
   
   public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
		PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
		
		@Override
		public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
			processConfigBeanDefinitions(registry);
		}
		
		public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
			List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
			String[] candidateNames = registry.getBeanDefinitionNames();
			
			for (String beanName : candidateNames) {
				BeanDefinition beanDef = registry.getBeanDefinition(beanName);
				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));
				}
			}
			
			// 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);
			}while (!candidates.isEmpty());
		
		}
   
   }

    class ConfigurationClassParser {
		public void parse(Set<BeanDefinitionHolder> configCandidates) {
			this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();

			for (BeanDefinitionHolder holder : configCandidates) {
				BeanDefinition bd = holder.getBeanDefinition();
				try {
					if (bd instanceof AnnotatedBeanDefinition) {
						parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
					}
			}		
		}
		
		protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
			processConfigurationClass(new ConfigurationClass(metadata, beanName));
		}
		
		protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
			SourceClass sourceClass = asSourceClass(configClass);
			do {
				sourceClass = doProcessConfigurationClass(configClass, sourceClass);
			}
			while (sourceClass != null);

			this.configurationClasses.put(configClass, configClass);
		
		}
		
		protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
			// Recursively process any member (nested) classes first
			// 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
			AnnotationAttributes componentScan = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ComponentScan.class);
			if (componentScan != null && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
				// 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.getAliasedStringArray("locations", ImportResource.class, sourceClass);
				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 = sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName());
			for (MethodMetadata methodMetadata : beanMethods) {
				configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
			}
			
		}
	}

1.4.4ComponentScanAnnotationParser ClassPathBeanDefinitionScanner解析componentScan

class ConfigurationClassParser {
private final ComponentScanAnnotationParser componentScanParser;

public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
	ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader,
	BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry) {
	this.metadataReaderFactory = metadataReaderFactory;
	this.problemReporter = problemReporter;
	this.environment = environment;
	this.resourceLoader = resourceLoader;
	this.registry = registry;
	this.componentScanParser = new ComponentScanAnnotationParser(
			resourceLoader, environment, componentScanBeanNameGenerator, registry);
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);
}	

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
	Assert.state(this.environment != null, "Environment must not be null");
	ClassPathBeanDefinitionScanner scanner =
		new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"));
	scanner.setEnvironment(this.environment);
	
	
	for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
		for (TypeFilter typeFilter : typeFiltersFor(filter)) {
			scanner.addIncludeFilter(typeFilter);
		}
	}
	for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
		for (TypeFilter typeFilter : typeFiltersFor(filter)) {
			scanner.addExcludeFilter(typeFilter);
		}
	}
	
	Set<String> basePackages = new LinkedHashSet<String>();
	String[] basePackagesArray = componentScan.getAliasedStringArray("basePackages", ComponentScan.class, declaringClass);
	for (String pkg : basePackagesArray) {
		String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
				ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
		basePackages.addAll(Arrays.asList(tokenized));
	}
	for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
		basePackages.add(ClassUtils.getPackageName(clazz));
	}
	if (basePackages.isEmpty()) {
		basePackages.add(ClassUtils.getPackageName(declaringClass));
	}
	
	
	return scanner.doScan(StringUtils.toStringArray(basePackages));
}	

}

public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
	Assert.notEmpty(basePackages, "At least one base package must be specified");
	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
	for (String basePackage : basePackages) {
		Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
		for (BeanDefinition candidate : candidates) {
			ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
			candidate.setScope(scopeMetadata.getScopeName());
			String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
			if (candidate instanceof AbstractBeanDefinition) {
				postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
			}
			if (candidate instanceof AnnotatedBeanDefinition) {
				AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
			}
			if (checkCandidate(beanName, candidate)) {
				BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
				definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
				beanDefinitions.add(definitionHolder);
				registerBeanDefinition(definitionHolder, this.registry);
			}
		}
	}
	return beanDefinitions;
}

}

相關文章