diff --git a/spring-interface-smartInstantiationAwareBeanPostProcessor/README.md b/spring-interface-smartInstantiationAwareBeanPostProcessor/README.md index 74587be..6d58c47 100644 --- a/spring-interface-smartInstantiationAwareBeanPostProcessor/README.md +++ b/spring-interface-smartInstantiationAwareBeanPostProcessor/README.md @@ -257,7 +257,9 @@ sequenceDiagram ### 六、源码分析 -由于`predictBeanType`, `determineCandidateConstructors`, 和 `getEarlyBeanReference` 这三个方法虽然都属于 `SmartInstantiationAwareBeanPostProcessor` 接口,但它们处理不同的关注点,具有不同的目的。在进行源码分析时,此处只演示determineCandidateConstructors方法。 +首先来看看启动类入口,上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类。 + +PS:由于`predictBeanType`, `determineCandidateConstructors`, 和 `getEarlyBeanReference` 这三个方法虽然都属于 `SmartInstantiationAwareBeanPostProcessor` 接口,但它们处理不同的关注点,具有不同的目的。在进行源码分析时,此处只演示determineCandidateConstructors方法。 ```java public class SmartInstantiationAwareBeanPostProcessorApplication { @@ -268,7 +270,7 @@ public class SmartInstantiationAwareBeanPostProcessorApplication { } ``` -首先我们来看看源码中的,构造函数中,执行了三个步骤,我们重点关注`refresh()`方法 +在`org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext`构造函数中,执行了三个步骤,我们重点关注`refresh()`方法 ```java public AnnotationConfigApplicationContext(Class... componentClasses) { @@ -278,7 +280,7 @@ public AnnotationConfigApplicationContext(Class... componentClasses) { } ``` -`org.springframework.context.support.AbstractApplicationContext#refresh`方法中我们重点关注一下`finishBeanFactoryInitialization(beanFactory)`这方法,其他方法不是本次源码阅读的重点暂时忽略,在`finishBeanFactoryInitialization(beanFactory)`方法会对实例化所有剩余非懒加载的单列Bean对象。 +在`org.springframework.context.support.AbstractApplicationContext#refresh`方法中我们重点关注一下`finishBeanFactoryInitialization(beanFactory)`这方法会对实例化所有剩余非懒加载的单列Bean对象,其他方法不是本次源码阅读的重点暂时忽略。 ```java @Override @@ -290,6 +292,21 @@ public void refresh() throws BeansException, IllegalStateException { } ``` +在`org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization`方法中,会继续调用`DefaultListableBeanFactory`类中的`preInstantiateSingletons`方法来完成所有剩余非懒加载的单列Bean对象。 + +```java +/** + * 完成此工厂的bean初始化,实例化所有剩余的非延迟初始化单例bean。 + * + * @param beanFactory 要初始化的bean工厂 + */ +protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { + // ... [代码部分省略以简化] + // 完成所有剩余非懒加载的单列Bean对象。 + beanFactory.preInstantiateSingletons(); +} +``` + 在`org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons`方法中,主要的核心目的是预先实例化所有非懒加载的单例bean。在Spring的上下文初始化完成后,该方法会被触发,以确保所有单例bean都被正确地创建并初始化。其中`getBean(beanName)`是此方法的核心操作。对于容器中定义的每一个单例bean,它都会调用`getBean`方法,这将触发bean的实例化、初始化及其依赖的注入。如果bean之前没有被创建过,那么这个调用会导致其被实例化和初始化。 ```java @@ -297,47 +314,7 @@ public void preInstantiateSingletons() throws BeansException { // ... [代码部分省略以简化] // 循环遍历所有bean的名称 for (String beanName : beanNames) { - // 获取合并后的bean定义,这包括了从父容器继承的属性 - RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); - - // 检查bean是否不是抽象的、是否是单例的,以及是否不是懒加载的 - if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { - - // 判断当前bean是否是一个FactoryBean - if (isFactoryBean(beanName)) { - // 获取FactoryBean实例 - Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); - - // 如果bean确实是FactoryBean的实例 - if (bean instanceof FactoryBean) { - FactoryBean factory = (FactoryBean) bean; - - boolean isEagerInit; - - // 判断当前环境是否有安全管理器,并且工厂bean是否是SmartFactoryBean的实例 - if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { - // 使用AccessController确保在受限制的环境中安全地调用isEagerInit方法 - isEagerInit = AccessController.doPrivileged( - (PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit, - getAccessControlContext()); - } - else { - // 检查FactoryBean是否是SmartFactoryBean,并且是否需要立即初始化 - isEagerInit = (factory instanceof SmartFactoryBean && - ((SmartFactoryBean) factory).isEagerInit()); - } - - // 如果工厂bean需要立即初始化,则获取bean实例,这将触发bean的创建 - if (isEagerInit) { - getBean(beanName); - } - } - } - // 如果不是FactoryBean,则直接获取bean实例,这将触发bean的创建 - else { - getBean(beanName); - } - } + getBean(beanName); } // ... [代码部分省略以简化] } @@ -370,10 +347,7 @@ protected T doGetBean( return createBean(beanName, mbd, args); } catch (BeansException ex) { - // 如果在创建bean过程中出现异常,从单例缓存中移除它 - // 这样做是为了防止循环引用的情况 - destroySingleton(beanName); - throw ex; + // ... [代码部分省略以简化] } }); // 对于某些bean(例如FactoryBeans),可能需要进一步处理以获取真正的bean实例 @@ -402,15 +376,6 @@ public Object getSingleton(String beanName, ObjectFactory singletonFactory) { if (singletonObject == null) { // ... [代码部分省略以简化] - // 在创建单例之前执行某些操作,如记录创建状态 - beforeSingletonCreation(beanName); - - boolean newSingleton = false; - boolean recordSuppressedExceptions = (this.suppressedExceptions == null); - if (recordSuppressedExceptions) { - this.suppressedExceptions = new LinkedHashSet<>(); - } - try { // 使用工厂创建新的单例实例 singletonObject = singletonFactory.getObject(); @@ -426,10 +391,7 @@ public Object getSingleton(String beanName, ObjectFactory singletonFactory) { // ... [代码部分省略以简化] } - // 如果成功创建了新的单例,将其加入缓存 - if (newSingleton) { - addSingleton(beanName, singletonObject); - } + // ... [代码部分省略以简化] } // 返回单例对象