🏆「推荐收藏」【Spring 源码专题】彻底让你明白【IOC 容器初始化】运行原理和源码流程
前言介绍
本篇文章篇幅较大,希望读者可以慢慢阅读,建议收藏,分多次阅读学习。
学习源码的过程当中,有几点建议:
一定要学会抓重点,归纳核心类、核心方法、核心步骤;
分析源码我们不需要太过于纠结细节,不然,这个源码最起码得分析月才能分析完;
主要的目的是分析整个容器初始化过程,怎么初始化 bean,怎么设置动态代理;我们主要学习的是他们的思想,以及代码中运用到的设计模式;
容器框架重要对象
BeanFactory:用于访问容器中 bean 的接口,使用的是工厂模式,重点注意 DefaultListableBeanFactory,是贯穿的整个容器的基本工厂类。
BeanDefinition:BeanDefinition 是 bean 在 Spring 中的描述,先读取到 bean 的各种元素,然后利用 BeanDefinition 去初始化 bean,是 spring 从起管理 bean 对象的数据模型。
BeanDefinitionRegistry 接口:注册 bean 定义到 Spring 容器中,与 BeanFactory 接口相对应,主要针对于 Bean 的注册,BeanFactory 主要针对于 bean 对象的管理。
BeanFactoryPostProcessor 接口:bean 工厂后置处理器,该接口的作用主要是提供扩展点,用于各种 bean 定义的注册和实例化等,比较需要主要关注 ConfigurationClassPostProcessor 该类;
BeanPostProcessor 接口:bean 的后置处理器,该接口提供的扩展点,用于初始化 bean,以及初始化完成后的各种扩展;
IOC 容器初始化的大致流程
首先读取
BeanDefinition
放到容器中。通过 BeanFactoryPostProcessor 对象的扩展
通过 BeanPostProcessor 对象的扩展
然后根据 BeanDefinition 去初始化 bean。
最后实际进行初始化然后保存到容器中。
来实现各种不同的功能;IOC 容器初始化大致的一个流程,主要是看AnnotationConfigApplicationContext
和refresh
AnnotationConfigApplicationContext 构造器分析
传入配置类的构造函数
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//初始化容器,创建bean工厂,加载各种内部重要类的bean定义,用于初始化我们或者其他引入类
this();
//注册我们配置类的bean定义,初始化容器,从这个类开始
register(componentClasses);
//准备工作做好后,开始初始化容器
refresh();
}
先看下 this()这一行代码
AnnotatedBeanDefinitionReader:主要用于读取相关内部的 Spring 容器的 Bean 对象。
public AnnotationConfigApplicationContext() {
//初始化读取bean定义的读取器,完成Spring内部bean定义的注册
this.reader = new AnnotatedBeanDefinitionReader(this);
//初始化一个类扫描器,其实这个方法进来,是没有用到这个扫描器的
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
从上面创建 bean 定义读取器,看下构造方法
//从上面创建bean定义读取器,看下构造方法
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
//把ApplicationContext对象赋值给bean定义读取器
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//主要是看这个方法,注册Spring内部重要的bean定义
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
到这里 this(),这个方法流程就过完了,主要就是注册 spring 内部重要的 bean 定义,来看下 register(componentClasses)方法
//此目的主要针对于上面注册的reader进行注册相关的bean
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
//使用上面初始化的bean定义读取器,去注册我们配置类的bean定义
this.reader.register(annotatedClasses);
}
//遍历去注册传入进来的注解相关的Bean对象
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
//
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
//注册bean定义
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//根据配置类创建一个bean定义
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
//解析bean的作用域,如果没有设置,则默认是单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 创建bean对象的bean名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析该bean是否有Lazy,Primary,DependsOn,Description等注解,有则填充进去
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
//判断是否是Primary
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
// 判断是否属于懒惰加载
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 构建BeanDefinitionHolder对象去引用对象
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//最后把该bean定义注册到Bean工厂中去
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
register(componentClasses),方法到此结束,然后我们分析 refresh();方法,该方法初始化了 IOC 容器。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//设置容器状态,准备刷新容器
prepareRefresh();
//获取到容器的bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//填充bean工厂的各种属性
prepareBeanFactory(beanFactory);
try {
//留给子类实现,我们看的AnnotationConfigApplicationContext继承了GenericApplicationContext,该类主要是注册了ServletContextAwareProcessor
postProcessBeanFactory(beanFactory);
//主要调用bean工厂的后置处理器,把我们的类,注册成bean定义
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
//初始化国际化资源(这个方法不重要)
initMessageSource();
//Spring事件相关,主要是创建一个事件多播器
initApplicationEventMulticaster();
//留给子类实现
onRefresh();
//把我们的事件注册到容器中
registerListeners();
//实例化我们需要的bean,放入IOC容器
finishBeanFactoryInitialization(beanFactory);
//完成容器IOC容器初始化,并且发布初始化完成事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
分析主要的步骤
首先 prepareRefresh():方法主要是为容器设置一个状态(准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符)
然后接下来是获取相应的工厂类,AnnotationConfigApplicationContext 主要是获取到 DefaultListableBeanFactory,但是如果是 XML 方式,会在该方法去加载 bean 定义,我们不分析这种方式
这步比较关键,这步完成后,配置文件/配置类就会解析成一个 Bean 定义,注册到 BeanFactory 中,
这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
prepareRefresh() 创建容器前的准备工作
protected void prepareRefresh() {
// 记录启动时间,
// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
initPropertySources();
// 校验 xml 配置文件
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
obtainFreshBeanFactory() 创建 Bean 容器,加载并注册 BeanIoC 初始化里面最重要的部分。
关键是以下几步:
初始化 BeanFactory
加载 Bean
注册 Bean
注意:这步完成后,Bean 并没有完成初始化,实际的实例并没有被创建。
AbstractApplicationContext#obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory(){
// 关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等等
refreshBeanFactory();
// 返回上一步刚刚创建的BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
AbstractRefreshableApplicationContext#refreshBeanFactory()
protected final void refreshBeanFactory() throws BeansException {
// 如果 ApplicationContext 已经加载过 BeanFactory,销毁所有的Bean,关闭BeanFactory
// 注意点:应用中BeanFactory是可以有多个的,这里可不是说全局是否有BeanFactory
// 而是说当前的ApplicationContext有没有BeanFactory!
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 初始化一个 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 用于 BeanFactory 的序列化,一般人应该用不到吧...
beanFactory.setSerializationId(getId());
// 下面是两个重点方法
// 设置 BeanFactory 的两个重要属性
// 是否允许 Bean 覆盖、是否允许循环引用
customizeBeanFactory(beanFactory);
// 加载BeanDefinition到BeanFactory 单独拉出来讲
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
可以感觉到一个设计思路,ApplicationContext 继承自 BeanFactory,但是它不应该被理解为 BeanFactory 的实现类,而是说其内部持有一个实例化的 BeanFactory(DefaultListableBeanFactory)。以后所有的 BeanFactory 相关的操作其实是委托给这个实例来处理的。
customizeBeanFactory
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
BeanDefinition 的覆盖问题可能会有开发者碰到这个坑,就是在配置文件中定义 bean 时使用了相同的 id 或 name。
默认情况下,allowBeanDefinitionOverriding 属性为 null(Boolean 类型),如果在同一配置文件中重复了,会抛错,但是如果不是同一配置文件中,会发生覆盖。
循环引用也很好理解:A 依赖 B,而 B 依赖 A。或 A 依赖 B,B 依赖 C,而 C 依赖 A。
默认情况下,Spring 允许循环依赖,当然如果你在 A 的构造方法中依赖 B,在 B 的构造方法中依赖 A 是不行的。
loadBeanDefinitions(beanFactory) 加载 BeanDefinition
/**
* Load bean definitions into the given bean factory, typically through
* delegating to one or more bean definition readers.
* @param beanFactory the bean factory to load bean definitions into
* @throws BeansException if parsing of the bean definitions failed
* @throws IOException if loading of bean definition files failed
* @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
*/
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException;
ClassPathXmlApplicationContext 是按照解析 XML 的加载方式。看 javadoc 的描述,是通过
XmlBeanDefinitionReader
来载入 Bean Definitions。
/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see #initBeanDefinitionReader
* @see #loadBeanDefinitions
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// 初始化Reader 不重要,看下这个方法的javadoc就很好理解了
initBeanDefinitionReader(beanDefinitionReader);
// 真正重要的步骤!!
// 用Reader去加载XML配置
loadBeanDefinitions(beanDefinitionReader);
}
loadBeanDefinitions(beanDefinitionReader)
/**
* Load the bean definitions with the given XmlBeanDefinitionReader.
* 看这句注释:this method is just supposed to load and/or register bean definitions.
*/
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
// 这个分支,通过路径名去获取Resource,会和上面的方法殊途同归
reader.loadBeanDefinitions(configLocations);
}
}
AbstractBeanDefinitionReader#loadBeanDefinitions(Resource... resources)
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources) {
// 遍历解析XML文件,加载 BeanDefinition
counter += loadBeanDefinitions(resource);
}
return counter;
}
接下去的源码不细讲,这里载入分为两大步,
就是通过调用 XML 的解析器获取到 document 对象,完成通用 XML 解析;
就是按照 Spring 的 Bean 规则进行解析。
Spring 的 Bean 规则进行解析这个过程是 BeanDefinitionDocumentReader 来实现的,里面包含了各种 Spring Bean 定义规则的处理。
这里我觉得核心知识点就是 Spring Bean 规则的解析,简单点来说,里面包含了我们在 XML 配置的那些信息,怎么解析成容器中 BeanDefinition 的规则和步骤。这部分由于和主要流程关系不大。
在这因为 Spring 的 Bean 配置方式有很多,解析配置信息到 BeanDefinition 的实现方式也有很多,XML 又是现在少用的方式,所以关于 XML 中的 Spring Bean 规则的解析的详细源码就先略过了。
我们来看下 prepareBeanFactory(beanFactory)这个方法
设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//设置类加载器,为当前应用的application的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//为bean工厂设置一个标准的SPEL表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//为bean工厂设置一个资源编辑器,为了后面bean初始化时,给bean对象赋值
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//忽略以下接口的bean,这些bean都有set方法,不会对这些bean进行属性赋值
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,就是从这里注册的获取到的
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//注册事件监听器的bean后置处理接口
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//处理AOP的后置处理器
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//注册bean工厂的环境属性
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
接下来分析 postProcessBeanFactory(beanFactory);
这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口, 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。
提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化。
具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事。
该方法没有做实际的事情,主要是把 ServletContextAwareProcessor 后置处理器,给注册进去。
实现 ServletContextAware 接口获取上下文容器,就是从这里注入的。
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.servletContext != null) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
接下来分析 invokeBeanFactoryPostProcessors(beanFactory);
调用 BeanFactoryPostProcessor 实现类 postProcessBeanFactory(factory) 方法
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//获取FactoryPostProcessors,Spring内置的和自己设置的,然后供接下来的调用
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()));
}
}
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//放入已经被处理过的bean
Set<String> processedBeans = new HashSet<>();
//当前bean工厂是否实现了BeanDefinitionRegistry,如果有的话,则可以注册bean定义
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//循环我们传入的bean工厂后置处理器,并加入到处理器集合中
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
//保存当前实例化的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//从bean工厂中获取到继承了BeanDefinitionRegistryPostProcessor的bean
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//实例化优先级最高的BeanDefinitionRegistryPostProcessor
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//实例化出BeanDefinitionRegistryPostProcessor的类,我们正常初始化这里只有ConfigurationClassPostProcessor
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//对实例化出来的BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//把实例化出来的BeanDefinitionRegistryPostProcessor添加进总的集合中供后面调用
registryProcessors.addAll(currentRegistryProcessors);
//调用刚实例化出来的bean,注册bean定义
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空调用后的BeanDefinitionRegistryPostProcessor
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//实例化实现了Ordered接口的BeanDefinitionRegistryPostProcessor
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();
//调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor
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();
}
//调用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//调用自己实现的BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
//没有实现BeanDefinitionRegistry接口的bean工厂,直接调用invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//调用所有的BeanDefinitionRegistryPostProcessor完毕
//获取容器中所有的 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
//执行所有BeanFactoryPostProcessor.postProcessBeanFactory方法,按照order接口排序
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
}
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);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//执行完成所有BeanFactoryPostProcessor.postProcessBeanFactory方法,清除所有缓存信息
beanFactory.clearMetadataCache();
}
//我们接下来主要是看ConfigurationClassPostProcessor调用postProcessBeanDefinitionRegistry方法
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
接下来主要针对于,ConfigurationClassParser 类进行解析操作处理
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
//循环最开始初始化的所有bean定义
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//对配置类(带有@Configuration标签)进行标记,后续实例化时有用
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnable()) {
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()) {
return;
}
//对所有配置类进行排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 创建我们通过@ComponentScan导入进来的bean name的生成器
// 创建我们通过@Import导入进来的bean的名称
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();
}
//创建一个类解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
/**解析配置类,包括@Component、@ComponentScans等需要扫描的类,都会被解析出来放入bean定义容器
*@Configuration配置类为full配置类,其他的为lite配置类
**/
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解析出来的bean定义放入容器
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
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());
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
//我们再来看看ConfigurationClassPostProcessor.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
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)) {
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
//这里会修改@Configuration配置类的bean定义,到时候实例化bean时,会使用CGLIB创建动态代理,@Bean中调用获取的bean都是容器中的bean,其他配置类的bean,获取的都是new出来的
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
讲了 bean 定义的加载过程,现在我们来讲一下 bean 的实例化过程,bean 的实例化,主要是 finishBeanFactoryInitialization(beanFactory);这个方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//bean工厂创建转化器
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
//实例化AOP相关的组件
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
//调用工厂实例化方法,这个方法我们后面来分析
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
//冻结所有bean定义,在实例化时,不允许再修改bean定义
beanFactory.freezeConfiguration();
//实例化所有bean
beanFactory.preInstantiateSingletons();
}
Spring IOC 容器 bean 的实例化,到这基本就完成了,这次所有源代码的分析把重要的地方,大致流程都讲了一遍,但是有很多细节没有讲到,整体属于框架总体深入流程原理介绍。
版权声明: 本文为 InfoQ 作者【李浩宇/Alex】的原创文章。
原文链接:【http://xie.infoq.cn/article/f8a15aedad18d8a9265520cfb】。文章转载请联系作者。
李浩宇/Alex
我们始于迷惘,终于更高水平的迷惘。 2020.03.25 加入
🏆 【酷爱计算机技术、醉心开发编程、喜爱健身运动、热衷悬疑推理的”极客狂人“】 🏅 【Java技术领域,MySQL技术领域,APM全链路追踪技术及微服务、分布式方向的技术体系等】 🤝未来我们希望可以共同进步🤝
评论