spring IoC 容器的加载过程

1.实例化容器:  AnnotationConfigApplicationContext
  1. 实例化工厂: DefauiltListableBeanFactory
  2. 实例化创建BeanDefinition 读取其: AnnotatedBeanDefinitionReader
  3. 创建BeanDefinition 扫描器: ClassPathBeanDefinitionScanner
  4. 注册配置类为BeanDefinition :register(annotatedClasses)
  5. refresh()
  6. invokeBeanFactoryPostProcessors(beanFactory)
  7. finishBeanFactoryInitialization(beanFactory)

AnnotationConfigApplicationContext

1.1 spring boot 实例化 ApplicationContext

在 springBootApplication 启动进入 SpringApplication 类

public ConfigurableApplicationContext run(String... args) {
// 创建 ApplicationContext
context = this.createApplicationContext();
}

跟踪该方法:使用applicationContextFactory 创建 一个ApplicationContext

protected ConfigurableApplicationContext createApplicationContext() {
return this.applicationContextFactory.create(this.webApplicationType);
}

继续跟踪进入 ApplicationContextFactory 类,该类会根据项目的webApplicationType 创建不同的ApplicationContext 。

@FunctionalInterface
public interface ApplicationContextFactory {
ApplicationContextFactory DEFAULT = (webApplicationType) -> {
try {
switch(webApplicationType) {
case SERVLET:
return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
return new AnnotationConfigReactiveWebServerApplicationContext();
default:
return new AnnotationConfigApplicationContext();
}
} catch (Exception var2) {
throw new IllegalStateException("Unable create a default ApplicationContext instance, you may need a custom ApplicationContextFactory", var2);
}
};

ConfigurableApplicationContext create(WebApplicationType webApplicationType);
}

根据 ApplicationContextFactory 可知,springboot 会默认创建一个AnnotationConfigApplicationContext 的spring 容器。

这里解析AnnotationConfigApplicationContext 类的Ioc容器加载过程。

1.2 进入AnnotationConfigApplicationContext 类

1.1 中会根据webApplicationType创建一个对应的无参构造的AnnotationConfigApplicationContext实例对象:

public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 进行初始化
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}

在实例化AnnotationConfigApplicationContext 对象时,会先调用父类GenericApplicationContext的构造函数。父类的构造函数里面就是初始化DefaultListableBeanFactory,并且赋值给beanFactory 。

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
@Nullable
private ResourceLoader resourceLoader;
private boolean customClassLoader;
private final AtomicBoolean refreshed;

public GenericApplicationContext() {
// 实例化工厂:DefaultListableBeanFactory
// DefaultListableBeanFactory是相当重要的,用来生产 和获得Bean的。
this.beanFactory = new DefaultListableBeanFactory();
}
}

本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader read,一个扫描器ClassPathBeanDefinitionScanner scanner。scanner的用处不是很大,它仅仅是在我们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的。

让我们看看Spring在初始化 AnnotatedBeanDefinitionReader的时候做了什么:

public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;
private BeanNameGenerator beanNameGenerator;
private ScopeMetadataResolver scopeMetadataResolver;
private ConditionEvaluator conditionEvaluator;
// 在AnnotationConfigApplicationContext 初始化 AnnotatedBeanDefinitionReader进入该构造方法,registry 为 在AnnotationConfigApplicationContext的实例
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
// 调用该类的其他构造方法
this(registry, getOrCreateEnvironment(registry));
}

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
}

其中registerAnnotationConfigProcessors 会注册spring 内置的多个bean 。跟踪该方法,贴出最核心的代码:

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
// registerPostProcessor 注册Bean
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
}

}
  1. 判断容器中是否已经存在了ConfigurationClassPostProcessor Bean
  2. 如果不存在(当然这里肯定是不存在的),就通过RootBeanDefinition的构造方法获得

ConfigurationClassPostProcessor的BeanDefinition,RootBeanDefinition是BeanDefinition的子类

  1. 执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,当然这里注册

其他Bean也是一样的流程。

BeanDefinition它是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是 否懒加载,是否Primary等等,这个BeanDefinition也相当重要,我们以后会常常和它打交道。

继续追踪registerPostProcessor 方法,注册bean 

private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(2);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}

继续追踪registerBeanDefinition 方法,其中的核心实现是DefaultListableBeanFactory

//beanDefinitionMap是Map<String, BeanDefinition>, 
//这里就是把beanName作为key,ScopedProxyMode作为value,推到map里面 this.beanDefinitionMap.put(beanName, beanDefinition);
//beanDefinitionNames就是一个List<String>,这里就是把beanName放到List中去 this.beanDefinitionNames.add(beanName);

从这里可以看出DefaultListableBeanFactory就是我们所说的容器了,里面放着beanDefinitionMap,**

beanDefinitionNames,beanDefinitionMap是一个hashMap,beanName作为Key,beanDefinition作

为Value,beanDefinitionNames是一个集合,里面存放了beanName。

ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口,

BeanDefinitionRegistryPostProcessor接口又扩展了BeanFactoryPostProcessor接口,

BeanFactoryPostProcessor是Spring的扩展点之一,ConfigurationClassPostProcessor是Spring极

为重要的一个类

4.创建BeanDefinition扫描器:ClassPathBeanDefinitionScanner

由于常规使用方式是不会用到AnnotationConfigApplicationContext里面的scanner的,这里的scanner

仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法。所以这里就不看

scanner是如何被实例化的了。

5.注册配置类为BeanDefinition: register(annotatedClasses);

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
this.register(componentClasses);
this.refresh();
}

一直跟踪 register 方法:

AnnotationConfigApplicationContext. register(Class<?>... componentClasses)

------>AnnotatedBeanDefinitionReader.register(Class<?>... componentClasses)

------>AnnotatedBeanDefinitionReader.registerBean(Class<?> beanClass)

------->AnnotatedBeanDefinitionReader.doRegisterBean

查看doRegisterBean 方法的实现

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
//AnnotatedGenericBeanDefinition可以理解为一种数据结构,是用来描述Bean的,这里的作用就是把传入的标记了注解 的类
//转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
abd.setInstanceSupplier(supplier);
//解析bean的作用域,如果没有设置的话,默认为单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);
//解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Descri ption
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
int var10;
int var11;
if (qualifiers != null) {
Class[] var9 = qualifiers;
var10 = qualifiers.length;

for(var11 = 0; var11 < var10; ++var11) {
Class<? extends Annotation> qualifier = var9[var11];
//Primary注解优先
if (Primary.class == qualifier) {
abd.setPrimary(true);
//Lazy注解
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
//其他,AnnotatedGenericBeanDefinition有个Map<String,AutowireCandidateQualifier>属性,直接push进去
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册,
//DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap
//beanDefinitionNames是一个List<String>,用来保存beanName
//beanDefinitionMap是一个Map,用来保存beanName和beanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}

重点跟踪 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry)**该方法,该方法最终实现bean 的注册。

最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {

BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// 是否对已存在的bean 进行重写
if (!this.isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
} else {
// 如果注册的bean 不存在,则进行注册
if (this.hasBeanCreationStarted()) {
synchronized(this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
this.removeManualSingletonName(beanName);
}
} else {
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.removeManualSingletonName(beanName);
}

this.frozenBeanDefinitionNames = null;
}

}

到这里注册配置类也分析完毕了。

  1. refresh()

大家可以看到其实到这里,Spring还没有进行扫描,只是实例化了一个工厂,注册了一些内置的Bean和我

们传进去的配置类,真正的大头是在第三行代码

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
this.register(componentClasses);
this.refresh();
}

这个方法做了很多事情,让我们点开这个方法:

public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
//刷新预处理,和主流程关系不大,就是保存了容器的启动时间,启动标志等
this.prepareRefresh();
//和主流程关系也不大,最终获得了DefaultListableBeanFactory,
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//还是一些准备工作,添加了两个后置处理器:ApplicationContextAwareProcessor,ApplicationListenerDetector
//还设置了 忽略自动装配 和 允许自动装配 的接口,如果不存在某个bean的时候,spring就自动注册singleton bean
//还设置了bean表达式解析器 等
this.prepareBeanFactory(beanFactory);

try {
//这是一个空方法,用于扩展
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

//执行自定义的 BeanFactoryProcessor 和内置的 BeanFactoryProcessor
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
this.initMessageSource();
this.initApplicationEventMulticaster();
// 空方法
this.onRefresh();
this.registerListeners();
// 实例化所有剩余的(非懒加载)单例
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}

this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}

}
}

6.1 跟踪prepareBeanFactory 方法,该方法用于添加一些解析器和自动装配的配置,比较重要

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(this.getClassLoader());
if (!shouldIgnoreSpel) {
//设置bean表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
//属性编辑器支持
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
//添加一个后置处理器:ApplicationContextAwareProcessor,此后置处理处理器实现了BeanPostProcessor接口
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//以下接口,忽略自动装配
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartup.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
if (!IN_NATIVE_IMAGE && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}

if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}

if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}

if (!beanFactory.containsLocalBean("applicationStartup")) {
beanFactory.registerSingleton("applicationStartup", this.getApplicationStartup());
}

}

以上方法做的主要操作如下:

  1. 设置了一个类加载器
  2. 设置了bean表达式解析器
  3. 添加了属性编辑器的支持
  4. 添加了一个后置处理器:ApplicationContextAwareProcessor,此后置处理器实现了BeanPostProcessor接口
  5. 设置了一些忽略自动装配的接口
  6. 设置了一些允许自动装配的接口,并且进行了赋值操作
  7. 在容器中还没有XX的bean的时候,帮我们注册beanName为XX的singleton bean

6.2 invokeBeanFactoryPostProcessors该方法也比较重要,执行自定义的BeanFactoryProcessor和内置的BeanFactoryProcessor 。其体现了spring 的可扩展性及热插拔属性。该方法会查找实现了BeanFactoryPostProcessor的后置处理器,并且执行后置处理器中的方法。

查看ConfigurationClassPostProcessor中对BeanDefinitionRegistryPostProcessor。postProcessBeanDefinitionRegistry方法的实现

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 生成一个注册的Id
int registryId = System.identityHashCode(registry);
// 判断是否已注册
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
} else if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
} else {
// 没有注册则进行注册
this.registriesPostProcessed.add(registryId);
this.processConfigBeanDefinitions(registry);
}
}

继续跟踪processConfigBeanDefinitions(registry)方法,并解析该方法的实现逻辑

该方法主要用于解析带有 @Configuration 的每一个注解类: 

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList();
//获得所有的BeanDefinition的Name
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;

for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (this.logger.isDebugEnabled()) {
this.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));
}
}

if (!configCandidates.isEmpty()) {
//处理排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr = null;
// DefaultListableBeanFactory最终会实现SingletonBeanRegistry接口,所以可以进入到这个if
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry)registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}

if (this.environment == null) {
this.environment = new StandardEnvironment();
}

ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
HashSet alreadyParsed = new HashSet(configCandidates.size());

do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//解析配置类(传统意义上的配置类或者是普通bean,核心来了)
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
}

//直到这一步才把Import的类,@Bean @ImportRosource 转换 成BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> {
return String.valueOf(configClasses.size());
}).end();
candidates.clear();
//获得注册器里面BeanDefinition的数量 和 candidateNames进行比较
//如果大于的话,说明有新的BeanDefinition注册进来了
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet();
Iterator var13 = alreadyParsed.iterator();
} while(!candidates.isEmpty());

}
}

该方法中的ConfigurationClassUtils.checkConfigurationClassCandidate 这个方法会对添加有Full 与Lite 两个标记位的注解进行解析判断:

当我们注册配置类的时候,可以不加Configuration注解,直接使用Component ComponentScan Import ImportResou rce注解,称之为Lite配置类 。 

如果加了Configuration注解,就称之为Full配置类。

重点跟踪上面方法中的parser.parse(candidates) 方法,一直点击进去直到 ConfigurationClassParser 。doProcessConfigurationClass 方法

@Nullable
protected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass, Predicate<String> filter) throws IOException {
//递归处理内部类,一般不会写内部类
this.processMemberClasses(configClass, sourceClass, filter);

//处理@PropertySource注解,@PropertySource注解用来加载properties文件
Iterator var4 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator();

AnnotationAttributes importResource;
while(var4.hasNext()) {
importResource = (AnnotationAttributes)var4.next();
if (this.environment instanceof ConfigurableEnvironment) {
this.processPropertySource(importResource);
} else {
this.logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment");
}
}

//获得ComponentScan注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters,excludeFilters等
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
//如果没有打上ComponentScan,或者被@Condition条件跳过,就不再进入这个if
if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
Iterator var14 = componentScans.iterator();
//循环处理componentScans
while(var14.hasNext()) {
AnnotationAttributes componentScan = (AnnotationAttributes)var14.next();
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
Iterator var8 = scannedBeanDefinitions.iterator();

while(var8.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var8.next();
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}

if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
this.parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}

//处理@Import注解
//@Import注解是spring中很重要的一个注解,Springboot大量应用这个注解
//@Import三种类,一种是Import普通类,一种是Import ImportSelector,还有一种是Import ImportBeanDefinitionR egistrar
this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);
importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
String[] var20 = resources;
int var22 = resources.length;

for(int var23 = 0; var23 < var22; ++var23) {
String resource = var20[var23];
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
//处理@Bean的方法,可以看到获得了带有@Bean的方法后,不是马上转换成BeanDefinition,而是先用一个set接收
Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass);
Iterator var18 = beanMethods.iterator();

while(var18.hasNext()) {
MethodMetadata methodMetadata = (MethodMetadata)var18.next();
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

this.processInterfaces(configClass, sourceClass);
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
return sourceClass.getSuperClass();
}
}

return null;
}

实现的逻辑顺序:

  1. 递归处理内部类,一般不会使用内部类。
  2. 处理@PropertySource注解,@PropertySource注解用来加载properties文件。
  3. 获得ComponentScan注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters,

excludeFilters等。

  1. 判断有没有被@ComponentScans标记,或者被@Condition条件带过,如果满足条件的话,进入if,进行如下操作:
    4.1 执行扫描操作,把扫描出来的放入set,这个方法稍后再详细说明。
    4.2 循环set,判断是否是配置类,是的话,递归调用parse方法,因为被扫描出来的类,还是一个配置类,有@ComponentScans注解,

或者其中有被@Bean标记的方法 等等,所以需要再次被解析。

  1. 处理@Import注解,@Import是Spring中很重要的一个注解,正是由于它的存在,让Spring非常灵活,不管是Spring内部,还 是与Spring整合的第三方技术,都大量的运用了@Import注解,@Import有三种情况,一种是Import普通类,一种是ImportSelector,还有一种是Import ImportBeanDefinitionRegistrar,getImports(sourceClass)是获得import的内容,返回的 是一个set。
  2. 处理@ImportResource注解。
  3. 处理@Bean的方法,可以看到获得了带有@Bean的方法后,不是马上转换成BeanDefinition,而是先用一个set接收。

6.6-registerBeanPostProcessors(beanFactory);

实例化和注册beanFactory中扩展了BeanPostProcessor的bean。

例如:

AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)

RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)

CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。

6-11-finishBeanFactoryInitialization(beanFactory);

实例化所有剩余的(非懒加载)单例

比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。

实例化的过程各种BeanPostProcessor开始起作用。

finishBeanFactoryInitialization(beanFactory);

这个方法是用来实例化懒加载单例Bean的,也就是我们的Bean都是在这里被创建出来的

一直跟踪该方法,该方法也非常重要:

finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)

----〉 AbstractApplicationContext.getBean(String name)

------> 直到AbstractBeanFactory。doGetBean (AbstractBeanFactory也是核心类,非常重要)

if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

继续跟踪其中的createBean 方法直到doCreateBean 方法。

// 1.创建bean的实例。核心
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 2。填充属性
populateBean(beanName, mbd, instanceWrapper);//填充属性,炒鸡重要
// 3.进行aware系列接口的回调,并进行初始化方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
// 4. 执行BeanPostProcessor的postProcessBeforeInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
//5. afterPropertiesSet init-method位于initializeBean中的
invokeInitMethods(beanName, wrappedBean, mbd);

Spring Bean的生命周期

  1. 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为 连Autowired注解都是没有解析的;
  2. 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
  3. 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
  4. 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
  5. 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
  6. 调用BeanPostProcessor的postProcessBeforeInitialization方法;
  7. 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
  8. 如果Bean定义了init-method方法,则调用Bean的init-method方法;
  9. 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的

上下文中,直到被销毁;

  1. 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method

声明了销毁方法也会被调用。

6-12-finishRefresh();

refresh做完之后需要做的其他事情。

清除上下文资源缓存(如扫描中的ASM元数据)

初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。

发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作

Spring IOC源码解析(10)AbstractBeanFactory

​https://www.jianshu.com/p/ef6a92ce25b3​

Spring源码6:createApplicationContext()实例AnnotationConfigServletWebServerApplicationContext

​https://www.jianshu.com/p/17c8b15dd595​