该后置处理器是扫描、解析、注册所有配置类的Bean
入口
扫描、解析、注册所有配置类bean的流程图:
ConfigurationClassPostProcessor类processConfigBeanDefinitions方法
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List configCandidates = new ArrayList();
// 获取BeanFactory中的beanDefinitionNames,我debug时有8个。
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);
}
}
// 判断该bean是否为配置类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 我debug的时候最终加到配置类候选的只有启动类
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
// 对configCandidates 进行 排序,按照@Order 配置的值进行排序
Collections.sort(configCandidates, new Comparator() {
@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
// 检测是否有自定义bean名称生成器
SingletonBeanRegistry singletonRegistry = null;
if (registry instanceof SingletonBeanRegistry) {
singletonRegistry = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet && singletonRegistry.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
BeanNameGenerator generator = (BeanNameGenerator) singletonRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
// Parse each @Configuration class
// 解析每一个@Configuration注解修饰的配置类
// 创建配置类解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set candidates = new LinkedHashSet(configCandidates);
Set alreadyParsed = new HashSet(configCandidates.size());
do {
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());
}
// 这个方法主要是把前面解析出来的配置类的beanDefinition都注册到容器中
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 beanDef = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(beanDef.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(beanDef, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (singletonRegistry != null) {
if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
做了4件事:
1.获取BeanFactory中的已注册的beanDefinitionNames,8个,从中找出@Configuration注解修饰的类,我debug的时候只有自己写的启动类进入了候选配置类。如果找不到@Configuration修饰的配置类,则返回。对找到的@Configuration修饰的配置类们进行排序。
这里的candidateNames变量就是Bean工厂中已经有了的beanDefinition的名字,这时有
0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
2 = "org.springframework.context.annotation.internalRequiredAnnotationProcessor"
3 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
4 = "org.springframework.context.event.internalEventListenerProcessor"
5 = "org.springframework.context.event.internalEventListenerFactory"
6 = "app"
7 = "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory"
configCandidates变量就是@Configuration注解修饰的类,这里只有app
2.检测是否有自定义bean名称生成器
3. 解析每一个@Configuration注解修饰的配置类
4.删除缓存
判断该bean是否为@Configuration修饰的配置类
源码:
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
// 获取类名
String className = beanDef.getBeanClassName();
if (className == null) {
return false;
}
AnnotationMetadata metadata;
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// Check already loaded Class if present...
// since we possibly can't even load the class file for this Class.
Class> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
metadata = new StandardAnnotationMetadata(beanClass, true);
}
else {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex);
}
return false;
}
}
// 如果存在Configuration 注解,则为BeanDefinition 设置configurationClass属性为full
if (isFullConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
// 如果AnnotationMetadata 中有Component,ComponentScan,Import,ImportResource 注解中的任意一个,或者存在 被@bean 注解的方法, 则设置configurationClass属性为lite
else if (isLiteConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
// It's a full or lite configuration candidate... Let's determine the order value, if any.
Map orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
if (orderAttributes != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, orderAttributes.get(AnnotationUtils.VALUE));
}
return true;
}
这里可以看到,判断是否为配置类的标准是,有@Configuration注解 或者@Component 或者@ComponentScan 或者@Import 或者 @ImportResource 或者@Bean
该方法的入口及往后的调用顺序图:
源码:ConfigurationClassParser类的parse方法
public void parse(Set configCandidates) {
// 实例化deferredImportSelectors
this.deferredImportSelectors = new LinkedList();
// 遍历配置类,得到BeanDefinition,根据bd类型不同,调用不用的parse方法解析
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
//debug的时候是自己写的启动类走的这个if
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
// 处理deferredImportSelectors
processDeferredImportSelectors();
}
做了3件事
1.实例化deferredImportSelectors
2.遍历配置类,得到BeanDefinition,根据bd类型不同,调用不用的parse方法解析
3.处理deferredImportSelectors
这里的parse方法再往下调用会调到ConfigurationClassParser类的processConfigurationClass方法
源码:
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
// 是否跳过
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
// 处理Imported
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);
for (Iterator it = this.knownSuperclasses.values().iterator(); it.hasNext(); ) {
if (configClass.equals(it.next())) {
it.remove();
}
}
}
}
// Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass);
// 递归解析
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
// 添加到ConfigurationClassParser的configurationClasses中
this.configurationClasses.put(configClass, configClass);
}
做了4件事
1.shouldSkip 方法判断是否跳过:
没有被@Conditional注解所修饰,返回false
如果参数中沒有设置条件注解的生效阶段,是配置类的话直接使用PARSE_CONFIGURATION阶段,递归调用shouldSkip,
否则使用REGISTER_BEAN阶段,递归调用shouldSkip 。获取配置类的条件注解得到条件数据,并添加到集合中
遍历conditions,进行判断,如果阶段不满足条件的话,返回true并跳过这个bean的解析2.判断ConfigurationClassParser的configurationClasses中是否已有该配置类,判断是否需要处理imported
3.递归解析
4.添加到ConfigurationClassParser的configurationClasses中
源码:
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
// Recursively process any member (nested) classes first
// 处理内部类
processMemberClasses(configClass, sourceClass);
// Process any @PropertySource annotations
// 处理@PropertySource注解
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
// 处理@ComponentScan注解
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 necessary
//遍历扫描到的配置类进行解析
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) {
parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
// 处理@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations.
// 处理@ImportResource 注解
if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
String[] resources = importResource.getStringArray("locations");
// 遍历配置的locations,加入到configClass 中的ImportedResource
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
// 处理@Bean修饰的方法
Set beanMethods = retrieveBeanMethodMetadata(sourceClass);
// 遍历@Bean注释的方法,添加到configClass
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;
}
做了8件事:
1.处理内部类
2.处理@PropertySource注解
3.处理@ComponentScan注解
4.处理@Import注解
5.处理@ImportResource注解
6.处理@Bean修饰的方法
7.处理接口定义的方法
8.处理父类
举个例子,项目目录:其中App.java有注解@SpringBootApplication,TestConfiguration.java有注解@Configuration,ZipkinController有注解@RestController,TestUser没有注解。
到了这个方法后,进来的是app启动类。
1.app启动类,它会触发处理@ComponentScan注解,扫com.sid包下所有bean找到app、ZipkinController、TestUser、TestConfiguration,再从中找出@Component注解修饰的bean,这里即是(ZipkinController、TestConfiguration),注册这两个@Component注解修饰的Bean。此时,把这两个@Component注解修饰的bean(ZipkinController、TestConfiguration)拿来递归调用ConfigurationClassParser类的parser.parse()方法,解析他们。
2.TestConfiguration,ZipkinController进到这个方法后什么都没触发,注册到容器中。
3.回到上层,继续是app类在这个方法的后续,它会触发处理@Import注解,得到两个处理@Import的类org.springframework.boot.autoconfigure.AutoConfigurationPackages$Registrar
org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector
实例化他们并且设置到app类Import相关属性中。
5.结束该方法,结束该方法的上层方法ConfigurationClassParser类的processConfigurationClass方法,回到parser.parse()中继续往下走,进入processDeferredImportSelectors方法
源码:
private void processDeferredImportSelectors() {
List deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);
for (DeferredImportSelectorHolder deferredImport : deferredImports) {
ConfigurationClass configClass = deferredImport.getConfigurationClass();
try {
// getImportSelector得到的是EnableAutoConfigurationImportSelector
// selectImports调用的是AutoConfigurationImportSelector类的该方法
String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());
processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
}
}
做了2件事:
源码:
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
configurations = sort(configurations, autoConfigurationMetadata);
Set exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return configurations.toArray(new String[configurations.size()]);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
1 调用AutoConfigurationImportSelector类的selectImports方法,该方法中又调用了getCandidateConfigurations方法。getCandidateConfigurations方法用SpringFactoriesLoader加载了每个引用的包下的spring.factoris文件中定义的类,从中挑选出factoryName=org.springframework.boot.autoconfigure.EnableAutoConfiguration的类
这里加载了这3个spring.factoris文件。其中,只有spring-boot-autoconfigure-1.5.8.RELEASE.jar!/META-INF/spring.factories文件中有factoryName=org.springframework.boot.autoconfigure.EnableAutoConfiguration的类96个。
spring-boot-1.5.8.RELEASE.jar!/META-INF/spring.factories
spring-boot-autoconfigure-1.5.8.RELEASE.jar!/META-INF/spring.factories
spring-beans-4.3.7.RELEASE.jar!/META-INF/spring.factories
2. 回到selectImports方法中,把这96个类,排序,去重,移除不要的。
filter方法从spring.factories中得到factoryName=org.springframework.boot.autoconfigure.AutoConfigurationImportFilter的类,即是org.springframework.boot.autoconfigure.condition.OnClassCondition。用Filter过滤掉96个类中不要的,最后只剩下了 20个类。
3.selectImports方法中fireAutoConfigurationImportEvents方法 ,从spring.factories中得到factoryName=org.springframework.boot.autoconfigure.AutoConfigurationImportListener,即是org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener。使用AutoConfigurationImportEvent事件记录20个类的评测
源码:
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection importCandidates, boolean checkForCircularImports) throws IOException {
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) {
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 importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
// 如果@Import导入的类实现了ImportBeanDefinitionRegister接口
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class> candidateClass = candidate.loadClass();
//实例化这个@Import导入的类
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
// 这里基本上是走的这个else
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.调用ConfigurationClassParser类的processImports方法,处理这20个类。该方法又会去调用processConfigurationClass方法,里面调用doProcessConfigurationClass方法,里面调用doProcessConfigurationClass方法。相当于又把这20个内来拿做了一遍doProcessConfigurationClass方法去处理这20个内中的:内部类、@PropertySource注解、@ComponentScan注解、@Import注解、@ImportResource注解、@Bean修饰的方法、接口定义的方法、父类
这里调用的是ConfigurationClassBeanDefinitionReader类的loadBeanDefinitions方法
源码:
public void loadBeanDefinitions(Set configurationModel) {
// 实例化TrackedConditionEvaluator
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
// 调用loadBeanDefinitionsForConfigurationClass
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
loadBeanDefinitionsForConfigurationClass方法源码:
这个方法主要是把前面解析出来的配置类的beanDefinition都注册到容器中
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass,
TrackedConditionEvaluator trackedConditionEvaluator) {
// 使用条件注解判断是否需要跳过这个配置类
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
// 跳过配置类的话在Spring容器中移除bean的注册
this.registry.removeBeanDefinition(beanName);
}
// 从importRegistry 中移除
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
if (configClass.isImported()) {
// 如果自身是被@Import注释修饰,注册自己
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 将@Bean方法注册为bean
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 将configClass中ImportResource指定的资源注册为bean
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 如果该类有@Import,且Import进来的类实现了ImportBeanDefinitionRegistrar接口,则调用Import进来的类的registerBeanDefinitions方法。
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
做了5件事:
1.使用条件注解判断是否要跳过配置类,如果要跳过配置类的话,在spring中移除该bean的注册,从importRegistry 中移除,返回。
2.如果该bean自身被@Import注释修饰,注册自己。
3.将@Bean方法注册为bean
4.将configClass中中ImportResource指定的资源注册为bean
5.loadBeanDefinitionsFromRegistrars方法,如果该类有@Import,且Import进来的类实现了ImportBeanDefinitionRegistrar接口,则调用Import进来的类的registerBeanDefinitions方法。
AOP相关的AspectJAutoProxyRegistrar类的registerBeanDefinitions方法(注册AnnotationAwareAspectJAutoProxyCreator,设置AOP属性)的调用就是在这里