spring源码分析1
接着上一篇文章将 refresh方法
首先看一下测试项目代码
主类,将Myconfiguration.class注入进ApplictionContext
image.png
配置类
image.png
Car类实现了BeanDefinitionRegistryPostProcessor接口
image.png
MySpringBean标注了@Component
image.png
看一下refresh方法,(AbstractApplicationContext#refresh)
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// AnnotationConfigApplicationContext因为继承 GenericApplicationContext
//点进obtainFreshBeanFactory()方法,发现beanFactory是DefaultListableBeanFactory();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
这里就是spring里关于bean的核心方法,笔者并没有全部看过,这里也介绍bean的主线代码,继续分析
AbstractApplicationContext#invokeBeanFactoryPostProcessors方法,
这里就涉及到最重要的类ConfigurationClassPostProcess,首先看一下继承关系,实现了
BeanDefinitionRegistryPostProcessor(postProcessBeanDefinitionRegistry)和
BeanFactoryPostProcessor(postProcessBeanFactory),后续对调用这两个方法
image.png
image.png
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中
主要作用就是通过实现BeanDefinitionRegistryPostProcessor 接口类(一般指的是ConfigurationClassPostProcessor类)的postProcessBeanDefinitionRegistry方法扫面项目,将需要的类(比如@service @controller @configuration注解标注的类)加入到beanDefinitionMap中,并调用实现BeanFactoryPostProcessor的类的
postProcessBeanFactory方法修改beanDefinition,
在invokeBeanFactoryPostProcessors有getBean方法,会将bean放到一级缓存中,但是没有赋值属性
image.png
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
//已经处理过的bean,防止bean后置处理器被重复的执行
Set<String> processedBeans = new HashSet<>();
//判断beanFacroty是否实现BeanDefinitionRegistry,因为需要获取bean和注册bean的功能
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// BeanFactoryPostProcessor实现类的集合,过滤的是入参beanFactoryPostProcessors中的
// BeanFactoryPostProcessor接口的实现类
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// BeanDefinitionRegistryPostProcessor实现类的集合
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// beanFactoryPostProcessors通过AbstractApplicationContext#addBeanFactoryPostProcessor方法添加的,
//springboot在启动的时候会调用addBeanFactoryPostProcessor方法
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//如果手动添加的BeanDefinitionRegistry是BeanDefinitionRegistryPostProcessor的实现类
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//调用postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到registryProcessors中
registryProcessors.add(registryProcessor);
}
else {
//如果不是BeanDefinitionRegistryPostProcessor的实现类,就是BeanFactoryPostProcessor的实现类,添加到regularPostProcessors
regularPostProcessors.add(postProcessor);
}
}
// 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.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//从DefaultListableBeanFactory的beanDefinitionNames成员变量中获取//BeanDefinitionRegistryPostProcessor的bean的处理器名称
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//过滤,只留实现PriorityOrdered接口的类,排序用
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//getBean获取bean,添加到currentRegistryProcessors中,这是马上就要处理的集合,
// getBean获取的类是ConfigurationClassPostProcessor
//getBean的源码后续会分析到
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//添加到processedBeans中,这是代表已经处理的集合
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加registryProcessors集合
registryProcessors.addAll(currentRegistryProcessors);
//执行postProcessBeanDefinitionRegistry方法,这里出现的一般都是
//ConfigurationClassPostProcessor ,这个类是springioc容器最重要的类
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//清空currentRegistryProcessors,后续还会用到
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
//从DefaultListableBeanFactory的beanDefinitionNames成员变量中获取
//BeanDefinitionRegistryPostProcessor的bean的处理器名称,代码和上面一样,执行实现
//Ordered接口的类,排序用
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//唯一不同的是,这里多了一个判断条件,过滤掉已经指定过的bean
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
//执行剩下的bean,因为项目中创建了Car类并且实现BeanDefinitionRegistryPostProcessor
//接口,所以这里剩下的只有car
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
// currentRegistryProcessors马上就要处理的集合
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//已经处理的bean,避免重复执行
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//调用registryProcessors和regularPostProcessors的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
//如果bean工厂没有实现BeanDefinitionRegistry 接口,说明没有注册Bean定义的能力
// 那么就直接调用BeanDefinitionRegistryPostProcessor#postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
//获取BeanFactoryPostProcessor接口的实例名称
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
//实现PriorityOrdered和BeanFactoryPostProcessors接口的类
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//实现Ordered和BeanFactoryPostProcessors接口类名称(beanDefinitionMap的key)
List<String> orderedPostProcessorNames = new ArrayList<>();
//没有实现PriorityOrdered和Ordered接口的类名称(beanDefinitionMap的key)
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
//已经处理过的bean,什么也不做
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//实现PriorityOrdered接口的类getBean并add进priorityOrderedPostProcessors
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//实现Ordered接口类名称add orderedPostProcessorNames
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
//剩余类名称的add进nonOrderedPostProcessorNames
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//下面的代码就是执行BeanFactoryPostProcessor的postProcessBeanFactory方法
// 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<>(orderedPostProcessorNames.size());
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<>(nonOrderedPostProcessorNames.size());
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();
}
下面两张图体现了当调用
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法之后将car注入到beanDefinitionMap中
image.png
image.png
invokeBeanDefinitionRegistryPostProcessors方法调用类的
postProcessBeanDefinitionRegistry方法,其实就是调用
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法,为什么是这个类,已经分析过了,当调用postProcessBeanDefinitionRegistry方法的时候,最终调用的是processConfigBeanDefinitions方法,上两张图注意到car的注入,那car是如何通过processConfigBeanDefinitions方法,注入进ioc容器中的
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//从现有的beanDefinitionNames中获取bean的名称①
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
//获取beanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断类是否被解析过,解析过的类返回不为null,这里涉及到类是完成配置类还是非完全配置类
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//判断类是否有@Configuration注解,如果没有看是否标注了@Component@ComponentScan
//@Import@ImportResource,如果还没有则看是否包含@Bean注解的方法,以上都没有则返回false ②
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//执行完下面的方法时configCandidates只有MyConfiguration配置类,
//有MyConfiguration,不是因为标注了@configuration注解是在new AnnotationConfigApplicationContext(Myconfiguration.class)时候,存入进beanDefinitionMaps中的
//这里有个疑问为什么
//没有MySpringBean呢,到现在为止还没有涉及到注解,在解析MyConfiguration配置类的代码的时候
//通过MyConfiguration类的@ComponentScan注解就会
//把MySpringBean扫描出来并放到beanDefinitionMap中,
//MyConfiguration标注了@Configuration,不但满足了上面的
//checkConfigurationClassCandidate条件,而且还是FULL类型的配置类
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
//根据类的@Order排序,这就是我们经常使用的,用@Order来决定类解析的顺序,
//@order小的排在前面
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 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) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
//创建解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//此时configCandidates只有MyConfiguration一个类
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//解析配置类,当执行这个方法的时候,就会解析出很多类,其中就包括MySpringBean类③
parser.parse(candidates);
parser.validate();
//获取扫描到的类,此时还没有放到beanDefinitionMap中
Set<ConfigurationClass> 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());
}
//将解析出来的配置类存放到beanDefinitionMap中,④
this.reader.loadBeanDefinitions(configClasses);
//将加载的类放到alreadyParsed中
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
candidates.clear();
//因为有扫描的类存放到beanDefinitionMap中,并且类中可能还有@Bean @Import等注解,所以下面一定大于
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
// candidateNames 为方法最开始定义的,里面只有spring启动的时候存放的配置类
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> 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());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
①解释为什么configCandidates只有MyConfiguration配置类
image.png
②ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)
我们只关注checkConfigurationClassCandidate方法中的部分代码
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
//判断是否标注了@Configuration并且proxyBeanMethods属性是否为false再取反即使判断是否为true,默认为true
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
//定义该类为完全配置类,对于什么是完全配置类后续会分析
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
//判断否标注了@Component@ComponentScan@Import@ImportResource,如果还没有则看是否包含@Bean注解的方法,
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
//以上都没有则返回false
else {
return false;
}
③ 解析到的配置类
Parse方法调用结束后,共扫描出3个类
image.png
查看parser.parse(candidates)
ConfigurationClassParser#parse(Set<BeanDefinitionHolder> configCandidates)
-->ConfigurationClassParser#processConfigurationClass
-->ConfigurationClassParser#doProcessConfigurationClass
在doProcessConfigurationClass方法中可以大概的看出
主要是看类是否包含@Component @PropertySources @ComponentScans @ImportResource注释 如果ComponentScans注解,通过路径还要扫描类,
提一下在spring解析的时候,如果@ComponentScans的basePackages为空的时候,扫描路径就是当前类所在的包,这段代码在ComponentScanAnnotationParser的parse方法中
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
//如果为null,使用当前类所在的包
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
下一步呢 就是把包下所有的类都找到,并根据excludeFilters includeFilters的规则,找到标注了@Component注解的类,这里就不分析了,关注一下
ClassPathBeanDefinitionScanner#doScan方法下的
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
basePackage就是包的扫描路径, findCandidateComponents方法中查找包下的所有类,在遍历,过滤出标注了@Component注解的类
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); 方法的第一行代码就new ClassPathBeanDefinitionScanner,并没有使用AnnotationConfigApplicationContext构造方法new ClassPathBeanDefinitionScanner对象,方法里面解析了@ConfigurationScan注解的属性,根据属性扫描类,最后scanner.doScan(StringUtils.toStringArray(basePackages));来扫描,并判断beanName 不能重复,如果重复则抛出异常
还要介绍一下
ConfigurationClassParser# doProcessConfigurationClass的下面这段代码
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
主要是通过@Import(ImportSelector实现类.class) 的selectImports导入的类
包装成configClass,并赋值importBy为标注了@import的元类
https://www.jianshu.com/p/4223ea69eb1f 这篇文章分析过是符合导入的
到此为止,把所有@ConfigurationScan扫描的类和@import的类都放到configClasses中
是通过ConfigurationClassParser#processConfigurationClass
this.configurationClasses.put(configClass, configClass);
这个方法存放进configClasses的
image.png
- ④this.reader.loadBeanDefinitions(configClasses); 将扫描的类加载进beanDefinitionMap中,并在加载之前,扫面类中是否含有@Bean注解,如果有也将扫面进beanDefinitionMap中
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;
}
//如果当前的类是通过@Import导入的,是在
// ConfigurationClassParser#doProcessConfigurationClass的
//processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
//将标注@Import获取出来的,这段代码就是将@Import标注的类存放beanDefinitionMap中
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
//如果configClass中有@bean方法,也将返回类存放进beanDefinitionMap中,key为方法名称
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
//是不是通过@ImportResources注解导入进来的
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//是否实现ImportBeanDefinitionRegistrar, ImportBeanDefinitionRegistrar是扩展接口//通过registerBeanDefinitions手动的注册beanDefinition, 实现//ImportBeanDefinitionRegistrar的类都是通过@Import导入的,并且实现类本身不会注入进//beanDefinitionMap中
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
以上是关于ConfigruationClassPostProcessor的postProcessBeanDefinitionRegistry方法
下面介绍ConfigruationClassPostProcessor#postProcessBeanFactory方法
那我们在回到最开始说的
AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中的
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);调用的就
ConfigruationClassPostProcessor#postProcessBeanFactory方法
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
enhanceConfigurationClasses方法对Bean的增强
遍历所有的beanDefinitionMap中的beanDefinition
如果类ConfigurationClassUtils.CONFIGURATION_CLASS_FULL前面提到过,就是类被@Configuration注释了,就会被CGLIB代理,将beanDefinition中的beanClass属性替换成被代理之后的类,
代理类的用处是什么呢,下面两张图可以解释,本次分析的
AbstractApplicationContext#refresh方法的invokeBeanFactoryPostProcessors(beanFactory);代码不会创建Bean,下面两张图不是执行invokeBeanFactoryPostProcessors代码时打印的
image.png
image.png
还没有介绍@Conditional的注解的使用,
this.reader.loadBeanDefinitions(configClasses)执行这个方法的时候,会解析@Conditional的一系列注解,springboot 中使用的是SpringBootCondition#matches方法,
ConditionOutcome outcome = getMatchOutcome(context, metadata);
getMatchOutcome方法是抽象方法具体的实现,如下就是OnBeanCondition的getMatchOutcome方法
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean
总结一下
本文其实主要介绍的就是
AbstractApplicationContext#refresh方法的invokeBeanFactoryPostProcessors(beanFactory);方法
invokeBeanFactoryPostProcessors方法主要就是调用ConfigruationClassPostProcessor的postProcessBeanDefinitionRegistry方法和postProcessBeanFactory方法
postProcessBeanDefinitionRegistry方法的作用是首先通过@ComponentScans扫描标注了@Component的类添加到beanDefinitionMap,遍历beanDefinitionMap如果标注@Import注解,根据selectImports返回的数组添加到configClasses中,再遍历configClasses,把标注@Bean @ImportSource 包装成beanDefintion添加到beanDefinitionMap中.
postProcessBeanFactory方法标注了@Configuration类,定义为增强类CGLIB代理,将beanDefinition中的beanClass属性替换成被代理之后的类.