Spring注解扫描原理浅析
4、ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
//
省略...
processConfigBeanDefinitions(registry);
}}
进入processConfigBeanDefinitions方法
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 省略...
do {
//
通过pase方法解析配置类,其实也就是在这个方法中去做的Spring的扫描
parser.parse(candidates);
parser.validate();
Set configClasses
= new LinkedHashSet<>(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 oldCandidateNames
= new HashSet<>(Arrays.asList(candidateNames));
Set alreadyParsedClasses
= new HashSet<>();
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());}
接着进入parse方法
public void parse(Set configCandidates) {
//
省略...
//
解析通过注解得到的Bean
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
//
省略...
}
进入到解析AnnotatedBeanDefinition的parse方法中,然后再进入processConfigurationClass方法
protected void processConfigurationClass(ConfigurationClass configClass, Predicate filter) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
//
用ConfigurationClass保存配置类种的信息
ConfigurationClass existingClass
= this.configurationClasses.get(configClass);
if (existingClass
!= null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
//
Otherwise ignore new imported config class; existing non-imported
class overrides it.
return;
}
else {
//
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.knownSuperclasses.values().removeIf(configClass::equals);
}
}
//
在此处递归地处理配置类及其超类层次结构
//
Recursively process the configuration class and its superclass
hierarchy.
SourceClass sourceClass
= asSourceClass(configClass, filter);
do {
//
doProcessConfigurationClass中会解析配置类上的注解
sourceClass
= doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass
!= null);
this.configurationClasses.put(configClass, configClass);}
接着进入到进入到doProcessConfigurationClass中就会看到核心代码了
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate filter)
throws IOException {
//
如果加了@Component注解就会首先递归地处理内部类
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
//
Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
//
解析@PropertySource注解
//
Process any @PropertySource annotations
for (AnnotationAttributes propertySource
: AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment
instanceof ConfigurableEnvironment) {
//
处理注解中的内容,并抽象成PropertySource对象
processPropertySource(propertySource);
}
else {
logger.info("Ignoring
@PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"].
Reason: Environment must implement
ConfigurableEnvironment");
}
}
//
开始解析@ComponentScans和@ComponentScan注解
//
Process any @ComponentScan annotations
Set 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 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());
}
}
}
}
//
解析@Import注解
//
Process any @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
//
解析@ImportResource注解
//
Process any @ImportResource annotations
AnnotationAttributes importResource
=
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource
!= null) {
String[] resources
= importResource.getStringArray("locations");
Class
加载中,请稍候......