文章目錄
- 前言
- 類的體系結構
- 源碼解析
- ClassPathScanningCandidateComponentProvider
- ClassPathBeanDefinitionScanner
- AnnotatedBeanDefinitionReader
- AnnotationConfigUtils
- BeanDefinitionReaderUtils
- AbstractApplicationContext
- PostProcessorRegistrationDelegate
- ConfigurationClassPostProcessor
- ConfigurationClassParser
- ComponentScanAnnotationParser
- ConfigurationClassBeanDefinitionReader
- ConfigurationClassUtils
- DefaultListableBeanFactory
- AbstractBeanFactory
- DefaultSingletonBeanRegistry
- AbstractAutowireCapableBeanFactory
前言
最近工作之餘有時間和精力,加上本人對源碼比較感興趣,就斗膽開始領略Spring源碼的魅力,爲加深印象和理解,適時進行文檔輸出。如有理解或表述錯誤,還望各位大佬不吝指正。
我看的是Spring5.2的源碼,從同性社區下載下來後編譯,然後看源碼、寫註釋、一步一步debug,先嚐試理解,再debug驗證和更正理解。
一開始想着將所有調用到的方法都貼上來寫上註釋進行一番解析,後來發現不現實,而且也不好寫,所以只能貼主要邏輯代碼,其他的可以私下交流。
本人能力和理解都有限,不可能寫一篇博客就完全領略到Spring的精髓,相信我,Spring源碼自己看了真的會上癮。
由於基於註解的開發是現在比較主流的開發模式,SpringBoot又將猿猿們從搭建開發環境的繁瑣工作中解脫出來,專注於業務代碼的開發,那麼就從 AnnotationConfigApplicationContext 開始看起。
廢話不多說,閒話不多聊,一起看代碼吧。
類的體系結構
源碼解析
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AmbitionConfig.class);
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
/**
* 由於繼承了父類,這裏會先去調用父類的構造方法,然後調用自身的構造方法
*
* this.classLoader = ClassUtils.getDefaultClassLoader();
* this.beanFactory = new DefaultListableBeanFactory();
*
* 其實就是實例化 DefaultListableBeanFactory 和 ClassLoader
*/
this();
/**
* 將傳入的 @Configuration 配置類轉換爲 BeanDefinition
* 並添加到 DefaultListableBeanFactory 工廠的 BeanDefinitionMap 中
*/
register(annotatedClasses);
refresh();
}
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
// 用實例化的讀取器註冊註解類
this.reader.register(annotatedClasses);
}
}
由於AnnotationConfigApplicationContext繼承了GenericApplicationContext,所以執行this()方法之前會先去執行父類的構造函數,代碼如下:
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
}
可以看到父類的構造函數實例化了一個DefaultListableBeanFactory,這就是Spring的BeanFactory,也可以說是Spring容器。
然後執行this()方法,這裏實例化了一個ClassPathBeanDefinitionScanner掃描器,先說一下,實際負責Spring掃描工作的並不是這個對象,Spring在後面又實例化了一個這個掃描器,然後把屬性值都拷貝過去,再執行掃描工作,這裏只是爲了提供一個ClassPathBeanDefinitionScanner對象的scanner()的API供外部調用。
還實例化了一個AnnotatedBeanDefinitionReader讀取器,這裏比較關鍵,Spring可以處理外部的註解,但是也需要相應的組件來處理,而這些組件不可能通過加@Component註解的方式加載進來,所以就需要硬編碼將組件加載進來,加載Spring內部組件的邏輯就包含在這裏面。
ClassPathScanningCandidateComponentProvider
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
// 包含過濾器
private final List<TypeFilter> includeFilters = new LinkedList<>();
// 排除過濾器
private final List<TypeFilter> excludeFilters = new LinkedList<>();
// 爲@Component註解組件註冊默認的過濾器
protected void registerDefaultFilters() {
// 爲包含過濾器集合添加 @Component 註解過濾器
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
// 爲包含過濾器集合添加 @ManagedBean 註解過濾器以支持 JSR-250 規範
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
// 爲包含過濾器集合添加 @Named 註解過濾器以支持 JSR-330 規範
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
}
ClassPathBeanDefinitionScanner
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry,
boolean useDefaultFilters) {
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry,
boolean useDefaultFilters,
Environment environment) {
this(registry, useDefaultFilters, environment,
(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry,
boolean useDefaultFilters,
Environment environment,
@Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
// 如果使用默認的掃描過濾器
if (useDefaultFilters) {
// 註冊默認的掃描過濾器
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
}
ClassPathBeanDefinitionScanner的父類ClassPathScanningCandidateComponentProvider有兩個屬性List<TypeFilter> includeFilters
和List<TypeFilter> excludeFilters
,指定了掃描器的掃描規則,registerDefaultFilters()
方法就是註冊Spring默認的掃描規則,如果不想使用默認的,可以通過addIncludeFilter()
和addExcludeFilter()
自定義掃描規則。
AnnotatedBeanDefinitionReader
public class AnnotatedBeanDefinitionReader {
// BeanName 生成器,用來爲掃描到的組件起名稱,默認使用AnnotationBeanNameGenerator
private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
// 條件評估器
private ConditionEvaluator conditionEvaluator;
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry,
Environment environment) {
this.registry = registry;
// 實例化條件評估器
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 最重要的工作
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
// 註冊註解類
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null, null);
}
}
實例化讀取器最重要的工作就是將Spring內部的註解後置處理器組件手動註冊到 BeanDefinitionRegistry 中,即AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
這個方法。
AnnotationConfigUtils
public abstract class AnnotationConfigUtils {
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry,
@Nullable Object source) {
// 獲取 BeanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
/**
* AnnotationAwareOrderComparator 主要能解析 @Order 註解和 @Priority 註解
**/
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
/**
* ContextAnnotationAutowireCandidateResolver 提供處理延遲加載的功能
**/
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// 存放所有輔助Spring初始化的類
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/**
* BeanDefinition 的註冊,很重要,需要理解註冊的每個 Bean 的類型和作用
*
* 1.ConfigurationClassPostProcessor 類型是 BeanFactoryPostProcessor
*
* 2.AutowiredAnnotationBeanPostProcessor 類型是 BeanPostProcessor
*
* 3.CommonAnnotationBeanPostProcessor 類型是 BeanPostProcessor
*
* 4.PersistenceAnnotationBeanPostProcessor 類型是 BeanPostProcessor
*
* 5.EventListenerMethodProcessor 類型是 BeanFactoryPostProcessor
*
* 6.DefaultEventListenerFactory 類型是 EventListenerFactory
*/
/**
* BeanName 是否包含 org.springframework.context.annotation.internalConfigurationAnnotationProcessor
*
* BeanClass 是 ConfigurationClassPostProcessor,類型是 BeanFactoryPostProcessor
*/
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/**
* BeanName 是否包含 org.springframework.context.annotation.internalAutowiredAnnotationProcessor
*
* BeanClass 是 AutowiredAnnotationBeanPostProcessor,類型是 BeanPostProcessor,用來處理@Autowired註解
*/
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/**
* 檢查 JSR-250 支持,存在則添加 CommonAnnotationBeanPostProcessor
*
* BeanName 是否包含 org.springframework.context.annotation.internalCommonAnnotationProcessor
*
* BeanClass 是 CommonAnnotationBeanPostProcessor,類型是 BeanPostProcessor,用來處理@Resource註解
*/
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/**
* 檢查 JPA 支持,存在則添加 PersistenceAnnotationBeanPostProcessor
*
* BeanName 是否包含 org.springframework.context.annotation.internalPersistenceAnnotationProcessor
*
* BeanClass 是 PersistenceAnnotationBeanPostProcessor,類型是 BeanPostProcessor
*/
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
/**
* BeanName 是否包含 org.springframework.context.event.internalEventListenerProcessor
*
* BeanClass 是 EventListenerMethodProcessor,類型是 BeanFactoryPostProcessor
*/
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
/**
* BeanName 是否包含 org.springframework.context.event.internalEventListenerFactory
*
* BeanClass 是 DefaultEventListenerFactory,類型是 EventListenerFactory
*/
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry,
RootBeanDefinition definition,
String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 註冊 BeanDefinition
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
processCommonDefinitionAnnotations(abd, abd.getMetadata());
}
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd,
AnnotatedTypeMetadata metadata) {
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
abd.setRole(role.getNumber("value").intValue());
}
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
abd.setDescription(description.getString("value"));
}
}
}
Spring 在初始化 ApplicationContext 和 BeanFactory 時,在 BeanFactory 中註冊了很多輔助初始化工作的類,這裏的邏輯就是添加這些類,如果支持JPA就是6個輔助類,不需要就是5個。
特別注意ConfigurationClassPostProcessor這個類,輔助初始化工作主要由這個類來完成。
這一步執行完,可以看到BeanFactory中多了5個BeanDefinition,因爲我這裏沒有JPA的組件,所以不需要JPA的輔助初始化類。
這樣this()
方法就執行完了,然後執行register(annotatedClasses)
方法,代碼跟進去可以看到最後調用的是AnnotatedBeanDefinitionReader的doRegisterBeandoRegisterBean()
方法,AnnotatedBeanDefinitionReader就是之前實例化的讀取器。
Spring的命令規範真的很形象易懂,看方法名字就可以知道代碼的功能,而且幾乎完全遵守了設計規範,將很多邏輯拆分成小的代碼塊,有專門的類負責,完全符合了設計模式的單一職責原則。
private <T> void doRegisterBean(Class<T> annotatedClass,
@Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers,
@Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 根據指定的 Bean 創建一個 AnnotatedGenericBeanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
// 用之前實例化的條件評估器,根據 @Conditional 註解確定是否應跳過註冊
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
// 解析類的作用域元數據
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 如果爲空則用之前實例化的 AnnotationBeanNameGenerator 生成主要的 BeanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
/**
* 處理類當中的通用註解
* 主要處理 @Lazy @DependsOn @Primary @Role @Description 註解
* 處理完成之後將值賦給 AnnotatedGenericBeanDefinition 對應的屬性中
*/
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// 爲空不執行
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
// 設置 primary 屬性值
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
// 設置 lazyInit 屬性值
abd.setLazyInit(true);
}
else {
/**
* 如果使用了除 @Primary 和 @Lazy 以外的其他註解
* 則爲該 Bean 添加一個根據名字自動裝配的限定符
*/
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
// 爲空不執行
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
/**
* 獲取 BeanDefinitionHolder 持有者容器
* 裏面包含的屬性值有 beanName, beanDefinition 和 aliases 別名集合
*/
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 解析作用域代理模型
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
/**
* 將最終獲取到的 BeanDefinitionHolder 持有者容器中包含的信息註冊給 BeanDefinitionRegistry
*
* AnnotationConfigApplicationContext 在初始化的時候通過調用父類的構造方法,實例化了一個 DefaultListableBeanFactory
* 這一步就是把 BeanDefinitionHolder 這個數據結構中包含的信息註冊到 DefaultListableBeanFactory 中
*
* DefaultListableBeanFactory 實現了 BeanDefinitionRegistry
*
* 此時傳入的 @Configuration 配置類已經註冊到 DefaultListableBeanFactory 工廠中
*/
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
這一步執行完,通過AnnotationConfigApplicationContext構造器傳進來的配置類就註冊到BeanFactory中了。
BeanDefinitionReaderUtils
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder,
BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
// 用類的主要名稱註冊 BeanDefinition
String beanName = definitionHolder.getBeanName();
// 註冊 BeanDefinition
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 如果有別名則註冊別名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
// 註冊別名
registry.registerAlias(beanName, alias);
}
}
}
AbstractApplicationContext
然後就到了大名鼎鼎的refresh()
方法了,邏輯過分複雜,只能挑兩個重要的方法進行解析。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
/**
* 準備刷新上下文,設置其啓動日期和活動標誌以及執行屬性源的任何初始化
*
* 設置刷新前的準備參數
* 校驗啓動參數
* 創建收集 ApplicationEvent 的集合
*/
prepareRefresh();
/**
* 通知子類刷新內部的 bean 工廠
* 得到創建的 DefaultListableBeanFactory 工廠
* DefaultListableBeanFactory 實現了 ConfigurableListableBeanFactory
* 接下來對工廠進行初始化
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/**
* 配置工廠的標準上下文特徵
*
* 這裏添加了 2 個 BeanPostProcessor
* 1、ApplicationContextAwareProcessor
* 2、ApplicationListenerDetector
*/
prepareBeanFactory(beanFactory);
try {
/**
* 允許在上下文子類中對 bean 工廠進行後置處理
*
* 當前版本的 Spring 代碼中沒有任何作用,可能是 Spring 爲了在後面的版本中方便擴展
*/
postProcessBeanFactory(beanFactory);
/**
* 第一重要的方法
*
* 完成掃描和解析操作
*
* 比較重要的一個是 ConfigurationClassPostProcessor
* 實例化 AnnotationConfigApplicationContext 時初始化了一個 AnnotatedBeanDefinitionReader
* AnnotatedBeanDefinitionReader 的構造方法中將 ConfigurationClassPostProcessor 註冊到 BeanDefinition 中
*
* Spring 會先執行 BeanDefinitionRegistryPostProcessor
* 的所有實現類【ConfigurationClassPostProcessor】的 postProcessBeanDefinitionRegistry 方法完成掃描
* {@link org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)}
* 掃描後 轉換爲 BeanDefinition 並放入 BeanFactory 的 beanDefinitionMap 中
* 再執行 Spring 內部的和外部擴展的 BeanFactoryPostProcessor 修改 BeanFactory 的數據
* {@link BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}
*/
invokeBeanFactoryPostProcessors(beanFactory);
/**
* 註冊 BeanPostProcessor,Spring AOP 就是在這裏進行註冊的
* 這裏注意 1 個 BeanPostProcessor : BeanPostProcessorChecker
**/
registerBeanPostProcessors(beanFactory);
/**
* 初始化此上下文的消息源
**/
initMessageSource();
/**
* 初始化應用事件廣播器【SpringBoot 的啓動源碼中與該方法有很大關係】
*
* 初始化 ApplicationEventMulticaster
* 如果 BeanFactory 中不存在 applicationEventMulticaster 則初始化一個 SimpleApplicationEventMulticaster
* 並註冊其爲單例到 BeanFactory 中
**/
initApplicationEventMulticaster();
/**
* 開放式方法,在特定的上下文子類中初始化其他特殊 Bean
* 【啓動 Spring Boot,Tomcat】
**/
onRefresh();
/**
* 檢查監聽器 Bean 並註冊它們
**/
registerListeners();
/**
* 第二重要的方法
* 實例化所有剩餘(非延遲初始化)單例類
*/
finishBeanFactoryInitialization(beanFactory);
/**
* 最後一步:發佈相應的事件
* 【EUREKA 服務就是在這裏啓動的】
*/
finishRefresh();
}
catch (BeansException ex) {
/**
* 摧毀已經創建的單例 Bean 以避免懸空資源
*/
destroyBeans();
/**
* 重置 active 屬性值
*/
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
/**
* 實例化並調用所有註冊的 BeanFactoryPostProcessor Bean,並遵循顯式順序(如果給定的話)
* 必須在單例實例化之前調用
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/**
* 執行所有
* {@link org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}
* 再執行所有
* {@link BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)}
**/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
......
}
/**
* 完成此上下文的 BeanFactory 的初始化,初始化所有剩餘的單例 Bean
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
/**
* 初始化此上下文的轉換服務
*/
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));
}
/**
* 如果之前沒有註冊 beanPostProcessor(例如 PropertyPlaceholderConfigurer)
* 則註冊默認的嵌入值解析器:此時主要用於註釋屬性值的解析
*/
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 獲取 LoadTimeWeaverAware 的 BeanName 集合
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
// 初始化 LoadTimeWeaverAware 以允許儘早註冊其變換器
getBean(weaverAwareName);
}
// 停止使用臨時 ClassLoader 進行類型匹配
beanFactory.setTempClassLoader(null);
// 允許緩存所有 BeanDefinition 元數據,此時不再允許進一步的更改
beanFactory.freezeConfiguration();
// 實例化所有不是懶加載的單例對象
beanFactory.preInstantiateSingletons();
}
第一個重要且複雜的方法是PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()
,第二個重要且複雜的方法是DefaultListableBeanFactory的preInstantiateSingletons()
方法,請做好防護,保護我方頭髮,非戰鬥人員自行撤離,這不是演習。
PostProcessorRegistrationDelegate
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory,
List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
/**
* beanFactory 是 DefaulLisableBeanFactory
* beanFactoryPostProcessors 集合大小爲0,只有通過外部API添加纔會有值
**/
/**
* 如果有的話,首先調用 BeanDefinitionRegistryPostProcessors
* 存放所有的 BeanDefinitionRegistryPostProcessors
**/
Set<String> processedBeans = new HashSet<>();
/**
* 如果是 BeanDefinitionRegistry 的子類
*
* beanFactory 是 DefaultListableBeanFactory
* DefaultListableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry
*/
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
/**
* BeanDefinitionRegistryPostProcessor 繼承了 BeanFactoryPostProcessor
*/
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
/**
* 區分 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor,初始化集合元素
*
* 此時還沒有任何元素,只有通過 API 添加了 BeanFactoryPostProcessor 纔會執行
* {@link AbstractApplicationContext#addBeanFactoryPostProcessor(org.springframework.beans.factory.config.BeanFactoryPostProcessor)}
* 這種情形很少,一般是通過註解來添加一個 BeanFactoryPostProcessor
* 所以下面這個循環很少會執行
**/
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
/**
* 實現了 BeanDefinitionRegistryPostProcessor
*
* 這裏只有一個 ConfigurationClassPostProcessor
*
* public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor
* 這裏 Spring 需要保證自己內置的先執行,爲了和外部擴展的區分,進行了判斷
**/
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
/**
* 執行完後添加到集合中,稍後執行其父類的方法
**/
registryProcessors.add(registryProcessor);
}
// 實現了 BeanFactoryPostProcessor
else {
/**
* 直接添加到集合中,稍後執行其父類的方法
**/
regularPostProcessors.add(postProcessor);
}
}
/**
* 將實現 PriorityOrdered,Ordered 和其餘的 BeanDefinitionRegistryPostProcessors 分開執行
*
* 存放當前正在註冊的 BeanDefinitionRegistryPostProcessor
* 臨時變量,分別找到實現 PriorityOrdered、Ordered 和其他的 BeanDefinitionRegistryPostProcessor
* 執行其 postProcessBeanDefinitionRegistry 方法
*/
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
/**
* 根據類型從 List<String> beanDefinitionNames 和 Set<String> manualSingletonNames 中獲取名稱
*
* 獲取 BeanDefinitionRegistryPostProcessor bean 名稱
*
* 此時至少包含了一個 ConfigurationClassPostProcessor
* ConfigurationClassPostProcessor 實現了 BeanDefinitionRegistryPostProcessor
* 名稱爲 internalConfigurationAnnotationProcessor
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
/**
* ConfigurationClassPostProcessor 最重要的類
*/
for (String ppName : postProcessorNames) {
/**
* 首先,調用實現 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors
*
* ConfigurationClassPostProcessor 實現了 PriorityOrdered
*/
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
/**
* 獲取該 Bean,並添加到集合中
*
* beanFactory.getBean() 方法做了兩件事
* 首先從容器中獲取,獲取到則返回
* 否則會實例化這個 Bean
**/
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 調用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法【重要】
* 掃描配置類並註冊所有符合條件的 BeanDefinition
*
* 集合中的元素包含 ConfigurationClassPostProcessor
* {@link ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry)}
*
* 此時 Spring 已經加載完所有輔助初始化的內部類,開始構建和解析配置類
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
/**
* 執行完成,清空當前註冊的處理器集合數據
*
* 至少清除包含的 ConfigurationClassPostProcessor
**/
currentRegistryProcessors.clear();
/**
* 獲取 BeanDefinitionRegistryPostProcessor BeanName
* 下面的代碼理論上不會執行,只是 Spring 確保初始化過程中沒有新的類被添加進來
**/
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
/**
* 接下來,調用實現 Ordered 的 BeanDefinitionRegistryPostProcessors
*/
for (String ppName : postProcessorNames) {
// 不在 processedBeans 中且實現了 Ordered 的 BeanDefinitionRegistryPostProcessors
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 獲取該 bean,並添加到集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 調用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 執行完成,清空集合數據
currentRegistryProcessors.clear();
/**
* 最後,調用所有剩餘的 BeanDefinitionRegistryPostProcessors
* 直到不再出現其他 BeanDefinitionRegistryPostProcessors
*/
boolean reiterate = true;
while (reiterate) {
reiterate = false;
// 獲取 BeanDefinitionRegistryPostProcessor 名稱
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 不在 processedBeans 中的 BeanDefinitionRegistryPostProcessors
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
/**
* 已經添加的 BeanDefinitionRegistryPostProcessor 可能還會產生新的 BeanDefinitionRegistryPostProcessor
* {@link BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(org.springframework.beans.factory.support.BeanDefinitionRegistry)}
* 有了 BeanDefinitionRegistry 變量可以往 beanDefinitionMap 中添加新的元素
* 所以將 reiterate 置爲 true 表示再找一遍
**/
reiterate = true;
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 調用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 執行完成,清空集合數據
currentRegistryProcessors.clear();
}
/**
* 執行所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法
*/
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
/**
* 執行所有 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
**/
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
/**
* 調用在上下文實例中註冊的工廠處理器
*/
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
/**
* 獲取 BeanFactoryPostProcessor 名稱
* 此時至少有兩個元素:
* org.springframework.context.annotation.internalConfigurationAnnotationProcessor
* org.springframework.context.event.internalEventListenerProcessor
*
* 需要保留所有未初始化的常規 bean,以使 bean 工廠後處理器適用於這些 bean
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
/**
* 分隔實現了 PriorityOrdered,Ordered 和其餘的 BeanFactoryPostProcessors
*/
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// 處理過則跳過
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
// 實現了 PriorityOrdered
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// 實現了 Ordered
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
// 普通類
else {
// org.springframework.context.event.internalEventListenerProcessor 是普通類
nonOrderedPostProcessorNames.add(ppName);
}
}
/**
* 首先,調用實現 PriorityOrdered 的 BeanFactoryPostProcessors
*/
// 排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
/**
* 調用 BeanFactoryPostProcessor#postProcessBeanFactory 方法
**/
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
/**
* 接下來,調用實現 Ordered 的 BeanFactoryPostProcessors
*/
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 排序
sortPostProcessors(orderedPostProcessors, beanFactory);
/**
* 調用 BeanFactoryPostProcessor#postProcessBeanFactory 方法
**/
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
/**
* 最後,調用所有其他 BeanFactoryPostProcessors
*/
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
/**
* 調用 BeanFactoryPostProcessor#postProcessBeanFactory 方法
**/
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
/**
* 清除緩存的合併 bean 定義,因爲後處理器可能已經修改了原始元數據,例如,替換值中的佔位符
*/
beanFactory.clearMetadataCache();
}
這段代碼很長,很複雜,其實主要做了這麼幾件事:
1.首先找外部通過API添加的BeanFactoryPostProcessor,將其和BeanDefinitionRegistryPostProcessor區分開(因爲雖然BeanDefinitionRegistryPostProcessor繼承了BeanFactoryPostProcessor,但是它們有不同的行爲)。如果外部添加了,是BeanDefinitionRegistryPostProcessor,則執行其postProcessBeanDefinitionRegistry()
方法,並加入到集合中。如果是BeanFactoryPostProcessor,則直接加入到集合中。
2.接着從Spring容器中獲取BeanDefinitionRegistryPostProcessor類型的組件(這裏就有之前硬編碼註冊到容器中的ConfigurationClassPostProcessor),調用beanFactory.getBean()
方法實例化,這裏beanFactory.getBean()
方法又是一個極其複雜的過程,涉及到三級緩存、解循環依賴、推斷構造方法、屬性填充等,後面會一起說明。
然後執行invokeBeanDefinitionRegistryPostProcessors()
方法,其實就是執行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()
方法,基於配置類的註冊表構建並驗證配置模型,將符合條件(指定掃描包下加了@Component、@Bean註解、@Import註解等)的類註冊到BeanFactory中。
3.此時Spring內部的組件和外部用戶的組件都註冊到Spring容器中了,然後再從Spring容器中獲取BeanDefinitionRegistryPostProcessor類型的組件
,沒有處理過且實現了Ordered接口的會調用其postProcessBeanDefinitionRegistry()
方法。
4.再從Spring容器中獲取BeanDefinitionRegistryPostProcessor類型的組件,這次只要沒有處理就會調用beanFactory.getBean()
實例化,並執行其postProcessBeanDefinitionRegistry()
方法,直到不再有新的組件被找到。其實就是Spring防止在執行過程中又有新的組件被添加進來了,畢竟Spring提供了很多開放式的接口和API供外部調用,所以要確保全部處理完成。
5.執行所有找到的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()
方法。
6.執行所有找到的BeanFactoryPostProcessor的postProcessBeanFactory()
方法。
7.從Spring容器中獲取BeanFactoryPostProcessor類型的組件,沒有處理過的,將其按實現了PriorityOrdered、Ordered和普通的進行區分,調用其postProcessBeanFactory()
方法,這裏有一個之前硬編碼註冊進去的EventListenerMethodProcessor。
ConfigurationClassPostProcessor
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 存放候選配置類的 BeanDefinitionHolder 集合
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
/**
* 獲取容器中註冊的所有 BeanDefinition 名稱
*
* 此時包括 AnnotatedBeanDefinitionReader 掃描的 5 個或者 6 個
* 和初始化 Spring 上下文環境時傳入的一個配置類
*/
String[] candidateNames = registry.getBeanDefinitionNames();
/**
* 遍歷獲取需要解析的類,即獲取配置類
*
* 只有加了 @Configuration 註解的配置類纔有 configurationClass 屬性值
**/
for (String beanName : candidateNames) {
// 獲取 BeanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
/**
* 如果 BeanDefinition 中的 configurationClass 屬性爲 full 或者 lite,則表示已經解析過了,直接跳過
*
* 因爲解析過的話,Spring 會將 configurationClass 屬性值設爲 full 或者 lite
* {@link ConfigurationClassUtils#checkConfigurationClassCandidate(org.springframework.beans.factory.config.BeanDefinition, org.springframework.core.type.classreading.MetadataReaderFactory)}
*/
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 註解配置類,加了則通過校驗,沒加再判斷是否加了以下註解
*
* candidateIndicators.add(Component.class.getName());
* candidateIndicators.add(ComponentScan.class.getName());
* candidateIndicators.add(Import.class.getName());
* candidateIndicators.add(ImportResource.class.getName());
*
* 如果加了 @Configuration 註解,會在後面再解析其他註解;如果沒加,只會單獨解析相應的註解
*
* 此時只有傳進來的配置類會執行
*/
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 有的話就添加到 BeanDefinitionHolder 集合中【此時傳入的配置類會添加進集合中】
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 沒有發現未處理的 @Configuration 類則返回
if (configCandidates.isEmpty()) {
return;
}
......
/**
* 實例化 ConfigurationClassParser 對象,用於解析 @Configuration 類
**/
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory,
this.problemReporter,
this.environment,
this.resourceLoader,
this.componentScanBeanNameGenerator,
registry
);
/**
* 定義兩個集合
* candidates 集合用於將之前加入的候選配置類進行去重,因爲可能有重複的
* alreadyParsed 用於存放已解析過的配置類
*/
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
// 因爲用 do-while 循環進行解析,所以初始容量爲 configCandidates.size()
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
/**
* 解析配置類【重要】
*
* 只註冊包掃描器掃描到的 BeanDefinition
*/
parser.parse(candidates);
/**
* 驗證配置類
*
* 主要驗證 @Configuration 的 @Bean 方法是否是靜態和可覆蓋的
* 靜態則跳過驗證
* @Configuration 類中的實例 @Bean 方法必須可以覆蓋才能容納 CGLIB
*/
parser.validate();
/**
* 去重
*
* 此時加了註解的普通類已經註冊完成,包括 @Configuration 配置類
* @Bean 方法定義的類不在裏面,
* @Import 引入的類在裏面
* 可以認爲註冊了所有加了 @Component 註解的組件
*/
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
// 移除所有已解析的
configClasses.removeAll(alreadyParsed);
/**
* 讀取模型並根據其內容創建 BeanDefinition
**/
if (this.reader == null) {
// 實例化 ConfigurationClassBeanDefinitionReader 讀取器,用於創建 BeanDefinitions
// 之前實例化的是 AnnotatedBeanDefinitionReader 讀取器
this.reader = new ConfigurationClassBeanDefinitionReader(
registry,
this.sourceExtractor,
this.resourceLoader,
this.environment,
this.importBeanNameGenerator,
parser.getImportRegistry()
);
}
/**
* 加載 BeanDefinitions 存入集合中【重要】
*
* 註冊 @Bean,ImportSelector,@ImportResource,ImportBeanDefinitionRegistrar 的 BeanDefinition
**/
this.reader.loadBeanDefinitions(configClasses);
// 全部標記爲已處理
alreadyParsed.addAll(configClasses);
// 清空候選者集合,後面保存經過校驗存在是配置類的候選者 並且 沒有處理過
candidates.clear();
/**
* 處理後工廠內的 BeanDefinition 數量大於處理前的數量
*
* 判斷是否已解析完,candidateNames.length 爲 6 或者 7
**/
if (registry.getBeanDefinitionCount() > candidateNames.length) {
// 處理後 BeanFactory 中 beanDefinitionNames 數據
String[] newCandidateNames = registry.getBeanDefinitionNames();
// 處理前 BeanFactory 中 beanDefinitionNames 數據
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
/**
* alreadyParsed + oldCandidateNames = newCandidateNames
*/
Set<String> alreadyParsedClasses = new HashSet<>();
// 已解析的 @Component 註解組件類添加到 alreadyParsedClasses 集合中
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
/**
* 循環遍歷處理後的 beanDefinitionNames
*/
for (String candidateName : newCandidateNames) {
/**
* 過濾出處理後的候選者中存在於處理前的候選者,即 alreadyParsed 中候選者
*
* 爲什麼不直接遍歷 alreadyParsed 集合,而是通過這種方式?
* 可能是 Spring 怕當前正在解析的時候,又手動添加了新的需要解析的類
**/
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
// 再次檢查 BeanDefinition 是否是配置類的候選者 並且 沒有處理過
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory)
&& !alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
// 標記所有候選者已處理完成
candidateNames = newCandidateNames;
}
}
// 全部解析完結束循環
while (!candidates.isEmpty());
......
}
又是一段又長又複雜的代碼塊,細分一下主要做了一下幾件事:
1.獲取容器中所有已註冊的BeanDefinitionName,遍歷獲取未處理過的配置類,將其封裝爲BeanDefinitionHolder並添加到集合中。
2.實例化ConfigurationClassParser對象,用於解析 @Configuration 配置類。
3.循環執行解析、驗證、加載等操作,直到所有的候選類都處理完成。
可以看到最重要的就是parser.parse()
方法。
ConfigurationClassParser
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
// 獲取 BeanDefinition
BeanDefinition bd = holder.getBeanDefinition();
try {
// 是 AnnotatedBeanDefinition 的子類
if (bd instanceof AnnotatedBeanDefinition) {
/**
* 解析註解對象,並存入 Map<ConfigurationClass, ConfigurationClass> 集合中
*/
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
// 是 AbstractBeanDefinition 的子類 並且 指定了 Bean 類
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);
}
}
// 執行延遲導入選擇器處理邏輯
this.deferredImportSelectorHandler.process();
}
protected final void parse(AnnotationMetadata metadata,
String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
// 判斷是否需要跳過
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
/**
* 先嚐試從緩存中獲取
*/
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
// 如果當前類通過別的類導入進來,則做如下處理
if (configClass.isImported()) {
if (existingClass.isImported()) {
// 合併
existingClass.mergeImportedBy(configClass);
}
// 否則忽略新導入的配置類; 現有的非導入類會覆蓋它
return;
}
else {
// 找到顯式 BeanDefinition,可能替換導入,則刪除舊的並使用新的
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
/**
* 遞歸處理配置類及其超類層次結構
*/
SourceClass sourceClass = asSourceClass(configClass);
do {
/**
* 真正的解析配置類
**/
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
} while (sourceClass != null);
// 存入緩存中
this.configurationClasses.put(configClass, configClass);
}
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass,
SourceClass sourceClass) throws IOException {
// 是否加了 @Component 註解,@Configuration 註解同樣適用
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
/**
* 首先遞歸處理任何成員(嵌套)類
*/
processMemberClasses(configClass, sourceClass);
}
/**
* 處理 @PropertySource 註解
*/
Set<AnnotationAttributes> annotationAttributes = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(),
PropertySources.class,
org.springframework.context.annotation.PropertySource.class
);
for (AnnotationAttributes propertySource : annotationAttributes) {
if (this.environment instanceof ConfigurableEnvironment) {
// 處理給定的 @PropertySource 註釋元數據
processPropertySource(propertySource);
}
}
/**
* 處理 @ComponentScan 註解
* 掃描路徑下加了 @Component 註解的類,並存入 BeanDefinitionMap 中
*/
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(),
ComponentScans.class,
ComponentScan.class
);
// 不爲空 且 需要處理
if (!componentScans.isEmpty()
&& !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
// 是個集合,循環遍歷
for (AnnotationAttributes componentScan : componentScans) {
/**
* 配置類加了 @ComponentScan 註解,則立即執行掃描操作
*
* 掃描 @ComponentScan 路徑下符合過濾器和候選者條件的類
* 轉換爲 BeanDefinitionHolder,並註冊到 BeanFactory 中
*
* 可以理解爲掃描 @ComponentScan 路徑下加了 @Component 註解的類
*/
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
// 獲取原始 BeanDefinition
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 檢查配置類候選者
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 解析配置類
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
/**
* 處理 @Import 註解
* 可以引入 @Configuration 類,ImportSelector 類,ImportBeanDefinitionRegistrar 類
*
* 解析 @Import 註解引入的類,ImportSelector 類、ImportBeanDefinitionRegistrar 類和 @Configuration 類作相應的處理
* ImportSelector 類需要遞歸處理
* ImportBeanDefinitionRegistrar 類存入 Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars 集合中
* @Configuration 類存入 Map<ConfigurationClass, ConfigurationClass> configurationClasses 集合中
*
* ImportSelector 的實現類可以動態實例化一個 BeanDefinition 到 IOC 容器中
*
* SpringBoot 很多 EnableXXX 都是基於 @Import 註解來實現靈活配置的
*/
processImports(
configClass,
sourceClass,
// 獲取 @Import 註解的 value 值
getImports(sourceClass),
true
);
/**
* 處理 @ImportResource 註解
**/
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
/**
* 處理每個 @Bean 註解方法
*
* 獲取所有 @Bean 方法的元數據
**/
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
// 封裝成 BeanMethod,添加到其配置類中
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
/**
* 處理接口上的默認方法
**/
processInterfaces(configClass, sourceClass);
/**
* 如果有父類則處理
**/
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
// 父類排除 java.lang.Object 且不存在於 knownSuperclasses 集合中
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// 找到超類,返回其註釋元數據並遞歸
return sourceClass.getSuperClass();
}
}
// 沒有父類,處理完成
return null;
}
又是一段複雜的代碼,源碼虐我千百遍,我待源碼如初戀。
這段代碼主要做了這麼幾件事:
1.首先處理成員或嵌套類,比如加了@Import註解引入的類,會作爲配置類進行解析。
2.處理@PropertySource註解
3.處理@ComponentScan註解,掃描 @ComponentScan路徑下符合過濾器和候選者條件的類,轉換爲BeanDefinitionHolder,並註冊到 BeanFactory中。然後校驗配置候選者是否引入了其他配置類,有的話將其作爲配置類進行解析。
Spring用了configurationClass
這個屬性值來標記,加了@Configuration(@Component註解加@Pointcut註解也有,注意這個現象)的候選類有 configurationClass
屬性值,且值爲full
;不是接口且加了@Component,@ComponentScan,@Import ,@ImportResource註解或是被@Bean註解標註的方法的候選類也有configurationClass
屬性值,但值爲lite
。
掃描註冊完後,Spring會對configurationClass
爲full
的配置類進行CGLIB
代理增強,即加了@Configuration註解的對象會變成一個CGLIB
代理對象,保證其包含的@Bean方法產生的對象只實例化一次,不會因爲互相調用而實例化多次。
4.解析@Import註解。這裏又做了這麼幾件事:
判斷引入的是判斷是 ImportSelector,ImportBeanDefinitionRegistrar還是其他的普通類
- 如果是ImportSelector類型,則將其實例化,如果是DeferredImportSelector延遲導入選擇器則保存,否則調用
selectImports()
方法,獲取導入的類全限定名數組,遞歸解析。 - 如果是ImportBeanDefinitionRegistrar類型,則實例化後放入集合保存,因爲可能會有多個ImportBeanDefinitionRegistrar且不需要遞歸處理,只需要執行一下委託其註冊BeanDefinition即可。
- 普通類則作爲配置類進行解析。
parser.parse()
方法執行完畢,所有的組件都解析出來了,接着進行驗證,然後執行ConfigurationClassBeanDefinitionReader的loadBeanDefinitions()
對解析出來的組件進行BeanDefinition的註冊,代碼下面有,註釋也很清晰,就不贅述了。
那麼第一個重要的方法就解析完畢了,後面接着解析第二個重要的finishBeanFactoryInitialization()
方法。
ComponentScanAnnotationParser
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan,
final String declaringClass) {
/**
* 此時又實例化了一個 ClassPathBeanDefinitionScanner
* 並沒有使用 AnnotationConfigApplicationContext 構造方法中實例化的 ClassPathBeanDefinitionScanner
*
* 爲什麼不用構造方法實例化的 ClassPathBeanDefinitionScanner 呢?
* 可能是因爲那個只是爲了讓外部能夠調用 API 所提供的,外部不能夠進行配置修改
* Spring 內部的可以進行修改
*
* @ComponentScan 提供了 useDefaultFilters、includeFilters 和 excludeFilters 等配置
*/
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(
this.registry,
componentScan.getBoolean("useDefaultFilters"),
this.environment,
this.resourceLoader
);
// 獲取 BeanNameGenerator
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ?
this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass));
// 處理代理模型
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
/**
* 遍歷 @ComponentScan 中的 includeFilters
* 獲取符合組件掃描的條件的類型
* Filter[] includeFilters() default {};
*/
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
// 添加包含過濾器
scanner.addIncludeFilter(typeFilter);
}
}
/**
* 遍歷 @ComponentScan 中的 excludeFilters
* 獲取不符合組件掃描的條件的類型
* Filter[] excludeFilters() default {};
*/
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
// 添加排除過濾器
scanner.addExcludeFilter(typeFilter);
}
}
/**
* 獲取 @ComponentScan 中的 lazyInit
* 默認不是懶加載
* 如果是懶加載,則修改 BeanDefinitionDefaults 的懶加載屬性值爲 True,而不是修改 BeanDefinition 的懶加載屬性值爲 True
* 爲後面應用默認值提供便利
* boolean lazyInit() default false;
*/
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
// 去重存儲掃描的包路徑
Set<String> basePackages = new LinkedHashSet<>();
/**
* 獲取 @ComponentScan 中的 basePackages()
* String[] basePackages() default {};
*/
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
// 處理逗號、分號、回車和換行符
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
/**
* 獲取 @ComponentScan 中的 basePackageClasses
* Class<?>[] basePackageClasses() default {};
*/
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
// 如果沒有註明掃描路徑,則默認掃描 @Configuration 類所在包及其子包
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
// 上面都是設置掃描器的屬性值,這一步纔是真正的掃描
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
// 循環掃描 basePackage 路徑下的文件,即 @ComponentScan 註解的 value 或 basePackages 值
for (String basePackage : basePackages) {
/**
* 掃描類路徑查找候選組件
*
* AnnotatedGenericBeanDefinition 或 ScannedGenericBeanDefinition
* AnnotatedGenericBeanDefinition 和 ScannedGenericBeanDefinition 都是 AbstractBeanDefinition 的子類
* 這裏都轉換成了 ScannedGenericBeanDefinition
*/
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 解析 Scope 屬性
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
/**
* 使用之前初始化的 BeanName 生成器爲候選者生成一個 BeanName
**/
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
/**
* 如果這個類是 AbstractBeanDefinition 的子類
*
* 此時會進入這個判斷
*
* 而被 @ComponentScan 註解掃描後的類都變成了 ScannedGenericBeanDefinition 或 AnnotatedGenericBeanDefinition
*
* 基本上都是 AbstractBeanDefinition 的子類
* 即先將 BeanDefinitionDefaults 的值賦給候選 BeanDefinition
*/
if (candidate instanceof AbstractBeanDefinition) {
/**
* 應用如下默認值:
* setLazyInit(lazyInit);
* setAutowireMode(defaults.getAutowireMode());
* setDependencyCheck(defaults.getDependencyCheck());
* setInitMethodName(defaults.getInitMethodName());
* setEnforceInitMethod(false);
* setDestroyMethodName(defaults.getDestroyMethodName());
* setEnforceDestroyMethod(false);
*/
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
/**
* 如果這個類是 AnnotatedBeanDefinition 的子類
*
* ScannedGenericBeanDefinition 或 AnnotatedGenericBeanDefinition 也是 AnnotatedBeanDefinition 的子類
*
* 這個判斷也會進,即跑完上一步時已經具有了默認值,但是用戶可能單獨爲這個類配置了註解值
* 再將掃描到的註解值賦給候選 BeanDefinition
*/
if (candidate instanceof AnnotatedBeanDefinition) {
/**
* 處理自定義註解的值
* 包含的註解有 @Lazy,@Primary,@DependsOn,@Role,@Description
*/
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
/**
* 檢查給定候選者的 beanName
*
* 1、是否存在於 BeanFactory 中,如果不存在則直接返回爲 True
* 2、校驗存在的和現有的 BeanDefinition 是否兼容,兼容則返回 False
* 3、拋異常
*
* 此時剛進行掃描,並沒有註冊到 BeanFactory 中,所以一般會進
*/
if (checkCandidate(beanName, candidate)) {
// 轉換爲 BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 應用代理模式
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
/**
* 由 Bean 的主要名稱和別名註冊 BeanDefinition
*
* 將 BeanDefinition 加入 Map<String, BeanDefinition>【主名】 和 Map<String, String>【別名】 集合中
*/
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
ConfigurationClassBeanDefinitionReader
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
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 和 ImportSelector 導入的
if (configClass.isImported()) {
// 爲導入的配置類註冊 BeanDefinition
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 包含 @Bean 方法
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
// 爲 BeanMethod 註冊 BeanDefinition
loadBeanDefinitionsForBeanMethod(beanMethod);
}
/**
* 爲 @ImportResource 導入資源註冊 BeanDefinition
**/
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
/**
* 委託 ImportBeanDefinitionRegistrar 進行註冊
**/
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
ConfigurationClassUtils
abstract class ConfigurationClassUtils {
public static final String CONFIGURATION_CLASS_FULL = "full";
public static final String CONFIGURATION_CLASS_LITE = "lite";
public static final String CONFIGURATION_CLASS_ATTRIBUTE =
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
private static final Set<String> candidateIndicators = new HashSet<>(8);
static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}
}
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef,
MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
// 獲取 BeanDefinition 的註解元數據
AnnotationMetadata metadata;
/**
* 是 AnnotatedBeanDefinition 的子類並且類的全類名一致
* 即不能是內部類或者導入的類
*
* AnnotatedGenericBeanDefinition 和 ScannedGenericBeanDefinition 都是 AnnotatedBeanDefinition 的子類
* 這意味着被註解標註的和被掃描到的都可能是一個候選配置類
**/
if (beanDef instanceof AnnotatedBeanDefinition
&& className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// 複用來自給定 BeanDefinition 的預先解析的元數據
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
/**
* 是 AbstractBeanDefinition 的子類並且指定 Bean 類
**/
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
BeanPostProcessor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
metadata = AnnotationMetadata.introspect(beanClass);
}
/**
* 既不是 AnnotatedBeanDefinition 的子類也不是 AbstractBeanDefinition 的子類
**/
else {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
return false;
}
}
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
/**
* 校驗 proxyBeanMethods 屬性值是否滿足
**/
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
/**
* 設置 configurationClass 屬性值爲 full【重要】
**/
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
/**
* 校驗配置應該具有的特徵
*
* 不是接口
* 加了 @Component @ComponentScan @Import @ImportResource 註解
* 有被 @Bean 註解標註的方法
**/
else if (config != null || isConfigurationCandidate(metadata)) {
/**
* 設置 configurationClass 屬性值爲 lite【重要】
**/
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
// 獲取 @Order 註解值
Integer order = getOrder(metadata);
if (order != null) {
// 設置 order 屬性值爲註解值
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
}
DefaultListableBeanFactory
public void preInstantiateSingletons() throws BeansException {
......
// 所有已註冊的 BeanName 集合
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
// 獲取合併的本地 BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象的 且 是單例 且 不是懶加載的 Bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判斷該 Bean 是否是一個 FactoryBean
if (isFactoryBean(beanName)) {
/**
* 獲取該 FactoryBean 實例
*
* 如果是 FactoryBean 則需要加上 '&' 符號才能實例化該 Bean
* 否則實例化的是該 FactoryBean 產生的對象
*/
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// 再次確認是 FactoryBean 的子類
if (bean instanceof FactoryBean) {
// 轉換爲 FactoryBean
final FactoryBean<?> factory = (FactoryBean<?>) bean;
// 標記是否迫切需要初始化
boolean isEagerInit;
/**
* SecurityManager 不爲空 且 是 SmartFactoryBean 的子類
*
* SmartFactoryBean 的子類有 EagerInitFactory 和 NonPrivilegedFactoryBean
*/
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext()
);
}
else {
// 是 SmartFactoryBean 的子類並且是迫切需要被初始化的
isEagerInit = (factory instanceof SmartFactoryBean
&& ((SmartFactoryBean<?>) factory).isEagerInit());
}
// 如果是迫切需要被初始化的類,則初始化
if (isEagerInit) {
getBean(beanName);
}
}
}
// 不是 FactoryBean 則直接實例化
else {
getBean(beanName);
}
}
}
......
}
開始解析第二個重要且複雜的方法,不跟進去其實還不算複雜。
這是初始化單例對象前的預處理,主要是遍歷所有已註冊的BeanDefinitionName集合,先獲取合併的本地BeanDefinition,判斷不是抽象的且是單例且不是懶加載的:
- 是一個FactoryBean,則在BeanName前加上
&
號獲取該FactoryBean實例- 再次確認該FactoryBean實例是FactoryBean類型,因爲我們可以給Bean起名字,完全可以加上
&
符號- 邏輯判斷是否迫切需要被初始化,是則初始化,不是則什麼也不做
- 再次確認該FactoryBean實例是FactoryBean類型,因爲我們可以給Bean起名字,完全可以加上
- 不是則直接初始化
終於來到了極其重要但是極其複雜的getBean()
方法了。
AbstractBeanFactory
protected <T> T doGetBean(final String name,
@Nullable final Class<T> requiredType,
@Nullable final Object[] args,
boolean typeCheckOnly) throws BeansException {
/**
* 獲取規範的 BeanName
*
* 這裏不使用 name 直接作爲 BeanName 有兩個原因:
* 1.name 可能會以 & 字符開頭,表明調用者想獲取 FactoryBean 對象本身的實例,
* 而非 FactoryBean 實現類所創建的 Bean 對象實例。
* 在 BeanFactory 中,FactoryBean 的實現類和其他的 Bean 存儲方式是一致的,
* 即<BeanName, BeanInstance>,BeanName中是沒有 & 這個字符的,
* 所以需要將 name 的首字符 & 移除,這樣才能從緩存裏取到 FactoryBean 創建的實例
* 2.該 Bean 對象可能存在別名
*/
final String beanName = transformedBeanName(name);
Object bean;
/**
* 解決循環依賴問題【通過兩次重載的 getSingleton() 方法和一次後置處理器方法的調用來解決循環依賴】
*/
/**
* 第一次調用 getSingleton() 方法,檢查單個緩存以手動註冊單例
*
* 獲取在給定名稱下注冊的(原始)單例對象
**/
Object sharedInstance = getSingleton(beanName);
// 已經創建過該實例對象
if (sharedInstance != null && args == null) {
// 獲取給定 Bean 實例的對象,如果是 FactoryBean,則爲 Bean 實例本身或其創建的對象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 沒有創建過該實例對象
else {
/**
* 如果已經創建了這個 Bean 實例,則會失敗:我們可以在循環引用中完成
*
* 原型對象循環依賴則拋異常
* 原型爲什麼不能循環依賴?
* Spring 解決循環依賴藉助了三級緩存,原型對象不會存入緩存,所以 Spring 無法解析
**/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 獲取父工廠,如果有就去父工廠中找
BeanFactory parentBeanFactory = getParentBeanFactory();
// 父工廠存在 且 當前容器【DefaultListableBeanFactory】沒有註冊該 beanName
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 走AbstractBeanFactory父工廠的創建流程
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly
);
}
else if (args != null) {
// 使用顯式 args 委託父級
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 沒有參數,委託標準的 getBean() 方法
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 其他情況
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
// 將 Bean 標記爲已創建
markBeanAsCreated(beanName);
}
try {
/**
* 合併 BeanDefinition
*
* XML 中可以配置一個抽象的模板 Bean,可以供子類進行屬性複用
**/
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 校驗是否是抽象的
checkMergedBeanDefinition(mbd, beanName, args);
/**
* 初始化當前 Bean 依賴的 Bean【被 @DependsOn 註解指明需要依賴的 Bean】
**/
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 校驗是否是相互依賴項【這裏不是循環依賴】
if (isDependent(beanName, dep)) {
// 拋出相互依賴異常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 爲給定 Bean 註冊依賴 Bean
registerDependentBean(dep, beanName);
try {
// 獲取給定的 Bean 實例
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
// 拋出依賴項缺失異常
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 單例則進行創建
if (mbd.isSingleton()) {
// 第二次調用 getSingleton() 方法,解決循環依賴問題
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型則創建新的實例
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 其他
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
......
return (T) bean;
}
梳理一下主要邏輯:
獲取規範的BeanName後,先調用getSingleton()
方法嘗試從緩存中獲取實例對象
- 獲取到了,如果調用者想要的是FactoryBean生產的對象,則去創建,否則返回
- 沒有獲取到,如果有父工廠並且當前容器沒有註冊要獲取的對象爲BeanDefinition,則走父工廠的創建流程
- 否則合併BeanDefinition,先檢查相互依賴項是否有缺失
- 根據其是單例、原型還是其他類型開始創建該實例
這裏有一個解循環依賴的過程,有空單獨寫一篇博客來說明,這裏就不細說了。
主要說一下單例的情況,兩個getSingleton()
方法代碼和註釋在下面,很容易理解,直接看AbstractAutowireCapableBeanFactory的createBean()
方法。
DefaultSingletonBeanRegistry
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先從 Map<String, Object> singletonObjects 單例緩存池【一級緩存】中獲取
Object singletonObject = this.singletonObjects.get(beanName);
/**
* 單例緩存池中不存在 且 當前正在被創建
*
* 當存在循環依賴時
* 解析 A 類時,將 A 類標記爲當前正在創建
* 填充 A 類的屬性值時去獲取並創建 B 類,此時將 B 類標記爲當前正在創建
* 填充 B 類的屬性值時去獲取並創建 A 類,此時 A 類獲取不到,但是被標記爲正在創建
* 此時這個判斷成立
**/
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 再從早期單例池中獲取
singletonObject = this.earlySingletonObjects.get(beanName);
/**
* 如果支持循環依賴,Spring 對 beanName 的操作如下:
*
* synchronized (this.singletonObjects) {
* // 如果不在單例池中
* if (!this.singletonObjects.containsKey(beanName)) {
* this.singletonFactories.put(beanName, singletonFactory);
* this.earlySingletonObjects.remove(beanName);
* this.registeredSingletons.add(beanName);
* }
* }
*
* beanName 不存在也沒有存到 singletonObjects 當中
* 所以第一步獲取不到,加鎖之後再獲取也獲取不到
**/
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 執行工廠方法,獲取這個對象
singletonObject = singletonFactory.getObject();
// 存入三級緩存,以後就直接從三級緩存中獲取,不用再執行對象工廠方法
this.earlySingletonObjects.put(beanName, singletonObject);
// 已經執行過工廠方法,獲取到對象了,從二級緩存中移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 從 Map<String, Object> singletonObjects 單例池中獲取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 當前正在銷燬中,不允許創建,拋異常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException();
}
// 如果不在創建檢查排除 BeanName 集合中,則添加到當前正在創建的單例 BeanName 集合中
beforeSingletonCreation(beanName);
// 新單例對象
boolean newSingleton = false;
// 初始化異常列表
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 如果不在創建檢查排除 BeanName 集合中,則從當前正在創建的單例 BeanName 集合中移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 創建完後存入一級緩存,並從二三級緩存中移除
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName,
RootBeanDefinition mbd,
@Nullable Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
......
try {
/**
* 給 BeanPostProcessors 一個返回代理而不是目標 Bean 實例的機會【重要】
* 但此時還沒有創建代理對象,此時沒有對象,只有 BeanDefinition
*
* 第一次調用後置處理器【跟 AOP 有關】
* @see org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(java.lang.Object, java.lang.String)
*
* InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
* Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
*
* 此時對象還沒有實例化,只有 BeanDefinition
* 無法進行代理,只是將切面找出來進行緩存
*/
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
/**
* 真正實例化 Bean
**/
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
protected Object doCreateBean(final String beanName,
final RootBeanDefinition mbd,
final @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/**
* 第二次調用後置處理器【推斷構造方法來實例化 Bean】
*
* SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
* Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
......
// 允許後置處理器修改合併的 BeanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
/**
* 第三次調用後置處理器
*/
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
/**
* 急於緩存單例,以便即使在諸如 BeanFactoryAware 之類的生命週期接口觸發時也能夠解析循環引用
*
* 是單例 且 允許循環依賴 且 當前正在創建
**/
boolean earlySingletonExposure = (mbd.isSingleton()
// 默認爲 True,除非修改了這個屬性
&& this.allowCircularReferences
&& isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
/**
* 第四次調用後置處理器【Spring 藉助了這一次後置處理器的調用外加兩次重載的 getSingleton() 方法來解決循環依賴】
*
* 存入二級緩存,並添加到已經註冊的單例集合中
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化 Bean 實例
Object exposedObject = bean;
try {
/**
* 通過調用兩個後置處理器的方法,完成 Bean 屬性的填充【或者說自動注入】【非常重要】
*
* 第五次調用後置處理器【返回 True 纔會進行屬性填充,可以干預某個 Bean 的裝配填充】
*
* 第六次調用後置處理器【完成屬性填充】
*/
populateBean(beanName, mbd, instanceWrapper);
/**
* 通過調用兩次後置處理器,完成 Bean 的初始化
*
* 第七次調用後置處理器【BeanPostProcessor 的直接實現類調用】
*
* Object current = processor.postProcessBeforeInitialization(result, beanName);
*
* 第八次調用後置處理器【BeanPostProcessor 的直接實現類調用】
*
* Object current = processor.postProcessAfterInitialization(result, beanName);
*/
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException
&& beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
......
try {
/**
* 第九次調用後置處理器【銷燬】
*/
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException();
}
return exposedObject;
}
這裏只看populateBean()
方法和initializeBean()
方法,一些還未完全確定的代碼,等後續更新。
protected void populateBean(String beanName,
RootBeanDefinition mbd,
@Nullable BeanWrapper bw) {
......
/**
* 在設置屬性之前,讓任何 InstantiationAwareBeanPostProcessors 都有機會修改 Bean 的狀態
* 這可以用來,例如,支持樣式屬性注入。
**/
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
/**
* 第五次調用後置處理器
*
* 校驗是否需要屬性填充
**/
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
/**
* 如果是四種自動裝配模型中的 byName 或者是 byType
*
* @Autowired 和 @Resource 是裝配技術,這裏不會執行
**/
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
/**
* 如果適用,根據名稱添加基於自動裝配的屬性值
**/
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
/**
* 如果適用,根據類型添加基於自動裝配的屬性值
**/
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
/**
* 獲取所有的 BeanPostProcessor
*
* 1、ApplicationContextAwareProcessor
*
* 2、ImportAwareBeanPostProcessor
*
* 3、BeanPostProcessorChecker
*
* 4、CommonAnnotationBeanPostProcessor
* 處理被 @Resource 註解標註的屬性
*
* 5、AutowiredAnnotationBeanPostProcessor
* 處理被 @Autowired 註解標註的屬性
*
* 6、ApplicationListenerDetector
**/
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
/**
* 第六次調用後置處理器
*
* 完成屬性填充
**/
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
/**
* 應用給定的屬性值
*
* 對應 XML 配置文件中這個標籤:
* <property name="XXX" value="XXX" ref="XXX"/>
**/
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
protected Object initializeBean(final String beanName,
final Object bean,
@Nullable RootBeanDefinition mbd) {
// 回調 Aware 及其實現類的方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
},
getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
/**
* 關鍵字:執行
* 執行 BeanPostProcessor 直接實現類的 postProcessBeforeInitialization() 方法
*
* @PostConstruct 註解是在這裏面進行處理的
*/
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
/**
* 執行 Bean 生命週期回調中的 init 方法
*
* 實現 InitializingBean 接口並重寫 afterPropertiesSet() 方法是在這裏面進行處理的
*/
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
/**
* 關鍵字:改變
* 執行 BeanPostProcessor 直接實現類的 postProcessAfterInitialization() 方法
*
* 產生 AOP 代理,事務的代理等
*/
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
這裏不得不說一下Bean生命週期涉及到的後置處理器,分別是InstantiationAwareBeanPostProcessor,SmartInstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor,DestructionAwareBeanPostProcessor,和BeanPostProcessor的實現類。要想弄明白Bean的生命週期,那麼這幾個後置處理器,和九個方法調用時逃不過的坎。
寫到這裏,發現離開應用談源碼,太寬泛,沒有針對性,很多想說的,展開的話就太多了,不說又感覺漏了,銜接不上,以後針對一些例子再具體解析一下,理清思路的同時,也驗證自己的理解。
貼一張看書的時候看到的學習金字塔圖,自己平時會花很多時間學習,但是都是被動的,忘的很快,通過寫博客,進行文檔輸出,真的能加深理解。
IOC源碼解析就到這裏了,如果有表述不準確或者錯誤的地方,還請大佬不吝指正,下一篇再見。