文章目录
- 该方法的功能总共分为如下5步:
- ①、获取所有实现了BeanDefinitionRegistryPostProcessor接口的实现类
- ②、调用实现Ordered的BeanDefinitionRegistryPostProcessors
- ③、调用所有我们自定义的实现的BeanDefinitionRegistryPostProcessors
- ④、最后,先调用所有实现了BeanDefinitionRegistryPostProcessors类的postProcessBeanFactory
- ⑤、调用其他实现了BeanFactoryPostProcessors类的postProcessBeanFactory方法。
这集我们说上面我们refresh() 中的invokeBeanFactoryPostProcessors(beanFactory);
注意:
这个方法最主要的方法是invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
该方法的功能总共分为如下5步:
①、执行我们前面的this()方法装载的ConfigurationClassPostProcessor的beanDefinition后置处理器,解析每个@Configuration类,把所有标注找到@Componet及继承了@Componet接口的接口例如@Service等和标注了@import的类beanDefinition加入到beanFactory的beanDefinitionMap中,名称添加到beanDefinitionNames中。
②、接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessors。
③、之后,调用所有我们自定义的实现了BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry(),直到没有其他的BeanDefinition处理器出现为止。
④、最后,先调用所有实现了BeanDefinitionRegistryPostProcessors类的postProcessBeanFactory,
⑤、调用其他实现了BeanFactoryPostProcessors类的postProcessBeanFactory方法。
接下来一一解答上面5个步骤
代码有点长,大家只需要看我标注了①②③④⑤总共五块代码,就是上面5处总结的代码。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//重点执行这个方法。
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
========================PostProcessorRegistrationDelegate.java==================================
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
************************①begin*****************************
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
************************①end*****************************
*************************②、begin*************************
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
*************************②、end*************************
*************************③、beign********************************
// 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)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
*************************③、end********************************
********************************④、begin************************
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//现在,调用到目前为止处理的所有处理器的postProcessBeanFactory回调。
//我们自己实现的BeanFactoryPostProcessor会在这里执行。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
********************************④、end************************
}else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
********************************⑤、begin************************
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
********************************⑤、end************************
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
现在我们一步步说上面的代码块
①、获取所有实现了BeanDefinitionRegistryPostProcessor接口的实现类
目前只有 ConfigurationClassPostProcessor
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
**************a、获取所有实现了BeanDefinitionRegistryPostProcessor接口的实现类***
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
****************b、匹配实现了PriorityOrdered接口的类
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
******************c、执行postProcessBeanDefinitionRegistry()*****
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
具体说说c处的代码,看代码标注 +++++ 的就是我的标注,这里很重要,很重要,很重要,很重要,一定要debug进来看。。。。。。。
1、查找类是否有注释@Configuration?如果有就添加到configCandidates数组中
2、按照@Order排序configCandidates
3、实例化解析@Configuration 的解析类
4、把上面的configCandidates数组方法Set容器中
1-4直接看下面代码注解
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
+++++++++++++++执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
=====================ConfigurationClassPostProcessor.java
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
//前面干扰视听的删掉了,主要看这个方法。
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
String[] candidateNames = registry.getBeanDefinitionNames();
++++++++++++++++1、查找类是否有注释@Configuration?如果有就添加到configCandidates数组中
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));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
++++++++++++++++2、按照@Order排序configCandidates
// 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;
}
}
+++++++++++++++++3、实例化解析@Configuration 的解析类
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
+++++++++++++++++4、把上面的configCandidates数组方法Set容器中
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
do {
++++++++++++++++++5、解析@Configuration类下面将对这个方法做详细的解答。
parser.parse(candidates);
parser.validate();
++++++++++++++++++6、获取上面parser.parse(candidates)中@import中添加到ConfigurationClasses的类
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);
+++++++++++++++++++7、把这一次@configuration解析到的所有BeanDefinition和之前的做比较,
++++++++++++++++++++++如果之前没有的并且标注了@Configuration的就重新在循环do{}while()
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();
}
}
大家还记不记得在refresh()方法的上一个方法register(annotatedClasses);中主配置类的bean定义(BeanDefinition)是实现了AnnotatedBeanDefinition的。如下,不是RootBeanDefinition。
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
5、parser.parse(candidates);
回到上面代码标记++++++++++++++5 处,因为configCandidates是实现了AnnotatedBeanDefinition,所以执行
bd instanceof AnnotatedBeanDefinition 里面的parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
//删了部分无相关代码
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
}
processDeferredImportSelectors();
}
=================================================
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
=================================================
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
+++++++++++++++a、如果没有标注@Conditionalxxxx就直接跳过,如果有就做判断是否符合Conditional的条件
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
//中间删了一部分影响视听的代码。
SourceClass sourceClass = asSourceClass(configClass);
do {
++++++++++++++++b、重点,处理configuration类
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
}
=======================================================
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) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.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;
}
我们现在看看上面doProcessConfigurationClass方法到底做了什么
I、处理所有@PropertySource或@PropertySources的注解
II、处理所有@ComponentScan或@ComponentScans的注解
III、处理所有标注了@Import的注解,解析@import中实现了ImportSelector或ImportBeanDefinitionRegistrar接口的类
IV、处理@ImportResource注解。
V、处理单个@Bean方法。
I、处理所有@PropertySource或@PropertySources的注解
// Process any @PropertySource annotations
+++++++++++++++++1、把所有标注了的@PropertySource加上@PropertySources中的@PropertySource都合計出來
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
++++++++++++2、处理PropertySource
processPropertySource(propertySource);
}
else {
logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
1处、可以看一下代码理解
@PropertySources({
@PropertySource("classpath:config.properties"),
@PropertySource("classpath:db.properties")
})
public class AppConfig {
//something
}
2、处的代码processPropertySource(propertySource);如下,
a、工作就是实例化每个PropertySource的PropertySourceFactory,如果没有在@PropertySource(factory=xxxxx)指定factory是什么的话默认是DefaultPropertySourceFactory
b、执行factory.createPropertySource(name, new EncodedResource(resource, encoding)),在new ResourcePropertySource(name, resource)构造方法里面调用父类的方法执行PropertiesLoaderUtils.loadProperties(resource)方法加载Properties
c、最后在addPropertySource()方法中,把PropertySource加入到environment当中。
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
//删掉部分影响视听的代码
String[] locations = propertySource.getStringArray("value");
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
++++++++++++++++++++++该处获取PropertySourceFactory,默认为DefaultPropertySourceFactory
Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));
for (String location : locations) {
try {
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
Resource resource = this.resourceLoader.getResource(resolvedLocation);
addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
}
}
}
==============================
private void addPropertySource(PropertySource<?> propertySource) {
String name = propertySource.getName();
MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
//删掉一部分影响视听的代码。
propertySources.addLast(propertySource);
}
最终结果:
II、处理所有@ComponentScan或@ComponentScans的注解
// Process any @ComponentScan annotations
+++++++同上面@PropertyResouce一样,把所有@ComponentScans和@ComponentScan归集在一起
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
+++++++++++++++++++++++++++1、解析这个这个@ComponentScan
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
+++++++++++++++++++++++++++2、检查扫描过的定义集,看看是否有其他配置类,如果需要,递归解析
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
我们看上面1处代码:this.componentScanParser.parse(xxxxxx),作用如下:
a、new ClassPathBeanDefinitionScanner(xxxxx) 实例化scanner中有代码
if (useDefaultFilters) {
registerDefaultFilters(); //该方法会执行this.includeFilters.add(new ,AnnotationTypeFilter(Component.class));直接加入了Component.class,
就会导致我们例如@ComponetScan(includeFilters = {@Filter(type = FilterType.ANNOTATION,classes = {Controller.class})无效,
其他Component注解的继承了都会加入到includeFilters,所以@ComponetScan如果要加上includeFilters 就要把
useDefaultFilters=false
}
b、对scanner赋值、如下代码标注
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
=====================================================
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
++++++++++++++++++I、实例化scanner
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
+++++++++++++++++II、useInheritedGenerator,如果没有在@ComponentScan中指明nameGenerator=自定义的话,默认就是BeanNameGenerator.class
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
//上面useInheritedGenerator =true,所以InheritedGenerator=AnnotationBeanNameGenerator();
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
+++++++++++++++++III、同样如果@ComponetScan没有配置scopeResolver,默认为AnnotationScopeMetadataResolver,之后实例化放入scanner
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
+++++++++++++++++IV、同上,值为ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN="**/*.class";
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
+++++++++++++++++V、添加@componentScan中标注了IncludeFilter的filter
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
+++++++++++++++++VI、添加@componentScan中标注了excludeFilters的filter
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
+++++++++++++++++VII、判断是否懒加载
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
+++++++++++++++++VIII、获取@ComponetScan上面的所有应该扫描的路径,先获取basePackages
Set<String> basePackages = new LinkedHashSet<String>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
basePackages.addAll(Arrays.asList(tokenized));
}
++++++++++++++++IX、获取basePackageClasses属性的路径,注意:是basePackageClasses不是basePackages,
获取到basePackageClasses属性类所在的包路径-->ClassUtils.getPackageName(clazz)
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
++++++++++++++++X、如果@ComponetScan 没有指定basePackages属性,那么basePackages就是当前配置类的包路径。
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
++++++++++++++++X、添加excludeFilter
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
+++++++++++++++XI、这个方法最重要,在下面说明。
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
看上面标注XI处、scanner.doScan(StringUtils.toStringArray(basePackages));
该代码的作用如下:
看下面代码1处
a、findCandidateComponents(basePackage)先查找basePackage下的所有.class类,注意是所有,不管有没有标注@Componet等接口
b、findCandidateComponents(basePackage) 方法下的isCandidateComponent(metadataReader) 判断是否在@ComponentScan中的includeFilte或者excludeFilte 中(注意:上面已经说过如果沒有在@componetScan()中配置useDefaultFilters=false那就默认添加了includeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = {Component.class})})。如果和includeFilte匹配就实例化一个当前class的ScannedGenericBeanDefinition(实现了BeanDefinition接口,其实就是bean定义)对象,如果和excludeFilte 匹配就直接跳过这个类,最后把所有实例化的ScannedGenericBeanDefinition对象放到Set容器返回给doScan(String… basePackages)方法。
c、registerBeanDefinition(definitionHolder, this.registry);方法把所有扫描到的组件beanDefinition全部都加载到beanFactory中
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) {
//1、查找当前basePackage 下的所有.class
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
//2、遍历上面返回来的BeanDefinition,设置beanDefinition的相应属性,例如是否标注了 @Lazy,@Primary,@DependsOn等
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;
}
至此把所有@ComponetScan扫描到的组件全部都加入到了beanFacotry的beanDefinitionMap中。
III、处理@Import
首先说明一点处理@Import不会像上面处理@ComponetScan那样,直接把获取到的组件直接放到beanFacotry的beanDefinitionMap中,而是把扫描到的类(@import中的value值)全部添加到ConfigurationClassParser中的configurationClasses。
1、注意getImports(sourceClass);获取所有@import(value={xxx,xxxx})中的value放入集合importCandidates,循环importCandidates,
2、判断是否实现了ImportSelector,
3、判断是否实现了ImportBeanDefinitionRegistrar
//1、getImports(sourceClass)
processImports(configClass, sourceClass, getImports(sourceClass), true);
============================================
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
//2、判断当前candidate是否实现了ImportSelector
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
//3、判断是否实现了ImportBeanDefinitionRegistrar,可以动态注册bean定义。
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
看上面1、处的代码getImports(sourceClass):
进该方法收集所有标注了@Configuration类中含有@import标签里的value值,封装成sourceClass,之后把所有SourceClass 汇总到imports,
代码如下:
private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
Set<SourceClass> imports = new LinkedHashSet<SourceClass>();
Set<SourceClass> visited = new LinkedHashSet<SourceClass>();
//进该方法收集所有标注了@Configuration类中含有@import标签里的value值,汇总到imports
collectImports(sourceClass, imports, visited);
return imports;
}
================================
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)
throws IOException {
if (visited.add(sourceClass)) {
for (SourceClass annotation : sourceClass.getAnnotations()) {
String annName = annotation.getMetadata().getClassName();
if (!annName.startsWith("java") && !annName.equals(Import.class.getName())) {
collectImports(annotation, imports, visited);
}
}
imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
}
}
========================================
public Collection<SourceClass> getAnnotationAttributes(String annType, String attribute) throws IOException {
Map<String, Object> annotationAttributes = this.metadata.getAnnotationAttributes(annType, true);
if (annotationAttributes == null || !annotationAttributes.containsKey(attribute)) {
return Collections.emptySet();
}
String[] classNames = (String[]) annotationAttributes.get(attribute);
Set<SourceClass> result = new LinkedHashSet<SourceClass>();
for (String className : classNames) {
result.add(getRelated(className));
}
return result;
}
==================================================
private SourceClass getRelated(String className) throws IOException {
if (this.source instanceof Class) {
try {
//
Class<?> clazz = ((Class<?>) this.source).getClassLoader().loadClass(className);
return asSourceClass(clazz);
}
catch (ClassNotFoundException ex) {
// Ignore -> fall back to ASM next, except for core java types.
if (className.startsWith("java")) {
throw new NestedIOException("Failed to load class [" + className + "]", ex);
}
return new SourceClass(metadataReaderFactory.getMetadataReader(className));
}
}
return asSourceClass(className);
}
========================================================
//如果source 不是class就通过传值的className加载这个class
SourceClass asSourceClass(String className) throws IOException {
if (className.startsWith("java")) {
// Never use ASM for core java types
try {
return new SourceClass(this.resourceLoader.getClassLoader().loadClass(className));
}
catch (ClassNotFoundException ex) {
throw new NestedIOException("Failed to load class [" + className + "]", ex);
}
}
return new SourceClass(this.metadataReaderFactory.getMetadataReader(className));
}
看上面2、处的代码判断当前candidate是否实现了ImportSelector
代码如下:
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
+++++++++++++++++获取实现了ImportSelector接口的类
Class<?> candidateClass = candidate.loadClass();
+++++++++++++++++实例化该类,获取该类对的实例化对象。
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
+++++++++++++++++查看当前selector是否实现了Aware接口,赋值相应的aware的方法。
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
+++++++++++++++++判断是否是延迟的ImportSelector
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {
+++++++++++++++++执行selector重写的的selectImports(AnnotationMetadata importingClassMetadata)方法,返回String[]
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
+++++++++++++++++重点!!!获取了selectImports方法返回的所有importSourceClasses方法之后重新执行processImports
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
.....--------忽略继承了ImportBeanDefinitionRegistrar的部分代码在下面3代码块。
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
+++++++++++++++++重点!!!上面执行了processImports(configClass, currentSourceClass, importSourceClasses, false);
之后配置类像注解写的那样:候选类不是ImportSelector或ImportBeanDefinitionRegistrar ->将其作为@Configuration类处理,
+++++++++++++++++重新执行processConfigurationClass,但是把把候选类包装为配置类作为参数,
+++++++++++++++++之後会把配置类添加到 this.configurationClasses.put(configClass, configClass);
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
//configurationClasses
processConfigurationClass(candidate.asConfigClass(configClass));
}
看上面3、处的代码是否实现了ImportBeanDefinitionRegistrar
代码如下:
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
++++++++++++++++加载实现了ImportBeanDefinitionRegistrar的类。
Class<?> candidateClass = candidate.loadClass();
++++++++++++++++实例化该类
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
++++++++++++++++如果实现了aware方法就添加aware的相应方法
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
++++++++++++++++往importBeanDefinitionRegistrars中添加ImportBeanDefinitionRegistrar实例化对象
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
==========================================================================
public void addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, AnnotationMetadata importingClassMetadata) {
this.importBeanDefinitionRegistrars.put(registrar, importingClassMetadata);
}
至此所有@import注解的组件都已经出来了,但是目前为止都没有定义相应的Bean定义(BeanDefinition),其中@import中的value实现了importSelector 和什么都实现的类会把类放到configurationClasses中,实现了ImportBeanDefinitionRegistrar 的类会放入到importBeanDefinitionRegistrars中。
具体的beanDefinition会到configurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry registry)方法中处理,下面会说明
IV、处理@ImportResource注解。
@ImportResource注解用于导入Spring的配置文件(applicationContext.xml、springmvc.xml)
注意:Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
要想让Spring的配置文件生效,需要在配置类上标注@ImportResource(locations = “classpath:applicationContext.xml”)。
加载@importResource代码如下:
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);
}
}
=============================ConfigurationClass.java
public void addImportedResource(String importedResource, Class<? extends BeanDefinitionReader> readerClass) {
this.importedResources.put(importedResource, readerClass);
}
至此@ImportResource把所有的resourse添加到importedResources
V、处理单个@Bean方法。
1、retrieveBeanMethodMetadata反射获取所有标注了@Bean的方法
2、往beanMethods中添加new BeanMethod(methodMetadata, configClass)
// Process individual @Bean methods
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
============================================
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
AnnotationMetadata original = sourceClass.getMetadata();
+++++++++++++++++++++++获取所有标注了@Bean的方法
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
// Try reading the class file via ASM for deterministic declaration order...
// Unfortunately, the JVM's standard reflection returns methods in arbitrary
// order, even between different runs of the same application on the same JVM.
try {
AnnotationMetadata asm =
this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> selectedMethods = new LinkedHashSet<MethodMetadata>(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
for (MethodMetadata beanMethod : beanMethods) {
if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
selectedMethods.add(beanMethod);
break;
}
}
}
if (selectedMethods.size() == beanMethods.size()) {
// All reflection-detected methods found in ASM method set -> proceed
beanMethods = selectedMethods;
}
}
}
catch (IOException ex) {
logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
// No worries, let's continue with the reflection metadata we started with...
}
}
return beanMethods;
}
==============================================ConfigurationClass.java
public void addBeanMethod(BeanMethod method) {
this.beanMethods.add(method);
}
至此@Bean把所有的method添加到beanMethods
6、把5中的@import和标注@Bean的方法都定义BeanDefinition 并加入到beanFactory
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) {
//实例化ConfigurationClassBeanDefinitionReader
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//主要的loadBeanDefinitions(configClasses);
this.reader.loadBeanDefinitions(configClasses);
=============================ConfigurationClassBeanDefinitionReader.java
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
=================================
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
if (configClass.isImported()) {
--------------I、注册@Import类(除了实现了ImportBeanDefinitionRegistrar接口)的BeanDefinition
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
--------------II、注册@Bean方法的BeanDefinition
loadBeanDefinitionsForBeanMethod(beanMethod);
}
--------------III、注册@ImportedResource的BeanDefinition
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
--------------IV、注册@Import中实现了ImportBeanDefinitionRegistrar接口的BeanDefinition
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
主要看看上面的代码
I、注册@Import类(除了实现了ImportBeanDefinitionRegistrar接口)的BeanDefinition
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
AnnotationMetadata metadata = configClass.getMetadata();
AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
configBeanDef.setScope(scopeMetadata.getScopeName());
String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
configClass.setBeanName(configBeanName);
if (logger.isDebugEnabled()) {
logger.debug("Registered bean definition for imported class '" + configBeanName + "'");
}
}
II、注册@Bean方法的BeanDefinition
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
======================================
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(metadata, ConfigurationPhase.REGISTER_BEAN)) {
configClass.skippedBeanMethods.add(methodName);
return;
}
if (configClass.skippedBeanMethods.contains(methodName)) {
return;
}
// Consider name and any aliases
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
List<String> names = new ArrayList<String>(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;
}
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
beanDef.setResource(configClass.getResource());
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
if (metadata.isStatic()) {
// static @Bean method
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
beanDef.setFactoryMethodName(methodName);
}
else {
// instance @Bean method
beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName);
}
beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
Autowire autowire = bean.getEnum("autowire");
if (autowire.isAutowire()) {
beanDef.setAutowireMode(autowire.value());
}
String initMethodName = bean.getString("initMethod");
if (StringUtils.hasText(initMethodName)) {
beanDef.setInitMethodName(initMethodName);
}
String destroyMethodName = bean.getString("destroyMethod");
if (destroyMethodName != null) {
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.isDebugEnabled()) {
logger.debug(String.format("Registering bean definition for @Bean method %s.%s()",
configClass.getMetadata().getClassName(), beanName));
}
//最重要的一点就是这里了,注册beanDefinition
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
III、注册@ImportedResource的BeanDefinition
这个方法涉及到解析xml文件等操作,就不一一解答了,最终下面的reader.loadBeanDefinitions(resource)方法会解析xml,之后再
XmlBeanDefinitionReader.processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)中把xml中的bean注入到beanFactory中。
private void loadBeanDefinitionsFromImportedResources(
Map<String, Class<? extends BeanDefinitionReader>> importedResources) {
Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<Class<?>, BeanDefinitionReader>();
for (Map.Entry<String, Class<? extends BeanDefinitionReader>> entry : importedResources.entrySet()) {
String resource = entry.getKey();
Class<? extends BeanDefinitionReader> readerClass = entry.getValue();
// Default reader selection necessary?
if (BeanDefinitionReader.class == readerClass) {
if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) {
// When clearly asking for Groovy, that's what they'll get...
readerClass = GroovyBeanDefinitionReader.class;
}
else {
// Primarily ".xml" files but for any other extension as well
readerClass = XmlBeanDefinitionReader.class;
}
}
BeanDefinitionReader reader = readerInstanceCache.get(readerClass);
if (reader == null) {
try {
// Instantiate the specified BeanDefinitionReader
reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);
// Delegate the current ResourceLoader to it if possible
if (reader instanceof AbstractBeanDefinitionReader) {
AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader);
abdr.setResourceLoader(this.resourceLoader);
abdr.setEnvironment(this.environment);
}
readerInstanceCache.put(readerClass, reader);
}
catch (Throwable ex) {
throw new IllegalStateException(
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
}
}
// TODO SPR-6310: qualify relative path locations as done in AbstractContextLoader.modifyLocations
reader.loadBeanDefinitions(resource);
}
}
XmlBeanDefinitionReader.processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)代码如下:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
++++++++++这里就是熟悉的注册beanDefinition;
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
IV、注册@Import中实现了ImportBeanDefinitionRegistrar接口的BeanDefinition
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
for (Map.Entry<ImportBeanDefinitionRegistrar, AnnotationMetadata> entry : registrars.entrySet()) {
-------直接执行实现了ImportBeanDefinitionRegistrar接口的registerBeanDefinitions方法,
-------添加扫描的位置或者直接添加BeanDefinition
entry.getKey().registerBeanDefinitions(entry.getValue(), this.registry);
}
}
7、把这一次@configuration解析到的所有BeanDefinition和之前存在beanFactory的做比较
,如果之前没有的并且标注了@Configuration的就重新在循环do{}while(),代码如下。
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;
}
②、调用实现Ordered的BeanDefinitionRegistryPostProcessors
该方法和一方法一样,不过这里获取的是实现了BeanDefinitionRegistryPostProcessor的类,而且要实现Ordered接口
invokeBeanDefinitionRegistryPostProcessors(XXX)和①是一样的
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
③、调用所有我们自定义的实现的BeanDefinitionRegistryPostProcessors
①中已经把所有的组件加载到beanFactory了,所以这里可以拿到自定义的实现了BeanDefinitionRegistryPostProcessors的类
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
-------①中已经把所有的组件加载到beanFactory了,所以这里可以拿到自定义的实现了BeanDefinitionRegistryPostProcessors的类
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
④、最后,先调用所有实现了BeanDefinitionRegistryPostProcessors类的postProcessBeanFactory
//现在,调用到目前为止处理的所有处理器的postProcessBeanFactory回调。
//我们自己实现的BeanFactoryPostProcessor前提是实现了BeanDefinitionRegistryPostProcessor的都会在这里执行。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
=====================================
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
⑤、调用其他实现了BeanFactoryPostProcessors类的postProcessBeanFactory方法。
这些BeanFactoryPostProcessors是没有实现BeanDefinitionRegistryPostProcessor的。
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
至此invokeBeanFactoryPostProcessors(beanFactory)主要的功能 执行完成