最近工作之餘有時間和精力,加上平時對源碼比較感興趣,就開始啃起了Spring源碼。爲加深印象寫了這篇博客,如有錯誤,望各位大佬不吝指正。
我看的是Spring5的源碼,從同性社區download下來後編譯,然後看源碼、寫註釋、一步一步debug,理論指導實踐,實踐再反作用於理論。
因爲基於註解的開發是現在比較主流的開發模式,所以就從 AnnotationConfigApplicationContext 開始啃了。
因爲代碼過多,執行流程過於複雜,就拆成了三篇來解析。
下面就從這個類開始探究Spring上下文的初始化。
這裏需要留意 AnnotationConfigApplicationContext 繼承了 GenericApplicationContext
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
/**
* 注意這個無參構造函數
*
* 這個初始化的DefaultListableBeanFactory就是Spring的Bean工廠
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
}
再來看看 AnnotationConfigApplicationContext 這個類
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
/**
* 定義一個讀取註解的 BeanDefinition 讀取器
* 這個類在構造方法中被實例化
*/
private final AnnotatedBeanDefinitionReader reader;
/**
* 定義一個掃描類路徑下加了註解的 BeanDefinition 掃描器
* 這個類在構造方法中被實例化
*/
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
// 實例化 BeanDefinition 讀取器
/**
* 註冊所有註解相關的後置處理器
* 最重要的一個後置處理器 ConfigurationClassPostProcessor
* BeanName 是 internalConfigurationAnnotationProcessor
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
// 實例化 BeanDefinition 掃描器
// 但是實際上掃描包的工作並不是 scanner 這個對象來完成的,是 Spring 自己創建的一個新的 ClassPathBeanDefinitionScanner
// 這裏的 scanner 僅僅是爲了程序員能夠在外部調用 AnnotationConfigApplicationContext 對象的 scanner 方法
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
// 調用父類的構造方法,初始化 DefaultListableBeanFactory 的 Bean 工廠
super(beanFactory);
// 實例化該讀取器
this.reader = new AnnotatedBeanDefinitionReader(this);
// 實例化該掃描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* 這個構造方法需要傳入一個 @Configuration 註解配置類
* 通過註解讀取器讀取並解析
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
/**
* 由於繼承了父類,這裏會先去調用父類的構造方法,然後調用自身的構造方法
*
* this.beanFactory = new DefaultListableBeanFactory();
*
* 其實就是初始化一個 DefaultListableBeanFactory
*/
this();
/**
* 將傳入的 @Configuration 配置類轉換爲 BeanDefinition
* 並添加到 DefaultListableBeanFactory 工廠的 BeanDefinitionMap 中
*/
register(annotatedClasses);
/**
* 1、準備刷新山下文
* 2、通知子類刷新內部的 bean 工廠,得到創建的 DefaultListableBeanFactory 工廠
* 3、配置工廠的標準上下文特徵
* 4、允許在上下文子類中對 bean 工廠進行後置處理
* 5、在上下文中調用工廠處理器方法,註冊爲 bean
* 6、註冊 BeanPostProcessor
* 7、初始化此上下文的消息源
* 8、初始化應用事件廣播器【SpringBoot 的啓動源碼中與該方法有很大關係】
* 9、在特定的上下文子類中初始化其他特殊 bean
* 10、檢查監聽器 bean 並註冊它們
* 11、實例化所有剩餘(非延遲初始化)單例
* 12、發佈相應的事件
*/
refresh();
}
public AnnotationConfigApplicationContext(String... basePackages) {
/**
* 由於繼承了父類,這裏會先去調用父類的構造方法,然後調用自身的構造方法
*
* this.beanFactory = new DefaultListableBeanFactory();
*
* 其實就是初始化一個 DefaultListableBeanFactory
*/
this();
scan(basePackages);
refresh();
}
}
這裏還要注意一下AnnotatedBeanDefinitionReader的實例化,代碼跟進去發現調用了 AnnotationConfigUtils 的 registerAnnotationConfigProcessors 方法,Spring在初始化上下文時,在Bean工廠中添加了很多輔助其初始化的類
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 獲取 Bean 工廠
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());
}
}
/**
* 存放所有輔助類的信息
*/
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/**
* BeanDefinition 的註冊,很重要,需要理解註冊的每個 Bean 的類型和作用
*
* Spring 在初始化 ApplicationContext 和 Bean 工廠時,在 Bean 工廠中添加了很多輔助初始化 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
*/
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));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
/**
* BeanName 是否包含 org.springframework.context.annotation.internalCommonAnnotationProcessor
* BeanClass 是 CommonAnnotationBeanPostProcessor,類型是 BeanPostProcessor
*/
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));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
/**
* 檢查 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;
}
這個方法執行完後,可以看到 DefaultListableBeanFactory 中的 beanDefinitionMap 中已經有數據了,如果支持 JPA 則有6個元素,沒有則有5個。分別是 ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、EventListenerMethodProcessor、DefaultEventListenerFactory,支持 JPA 的是 PersistenceAnnotationBeanPostProcessor。
這裏實例化的 ClassPathBeanDefinitionScanner 僅僅是爲了讓程序員能夠在外部調用 AnnotationConfigApplicationContext 對象的 scanner 方法。Spring 在後面又重新初始化了一個 ClassPathBeanDefinitionScanner,用新的 ClassPathBeanDefinitionScanner 進行掃描。
回到一開始,我這裏是傳了一個@Configuration的配置類,所以從register方法往下跟,最後調用的是 AnnotatedBeanDefinitionReader 的 doRegisterBean 方法
/**
* 將給定的 bean 類註冊爲 bean,從類聲明的註釋中派生其元數據
*/
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);
// 若這個類是需要跳過解析的類,則返回
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 指定創建 bean 實例的回調方法,此時爲 null
abd.setInstanceSupplier(supplier);
// 解析類的作用域元數據
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
// 添加類的作用域元數據
abd.setScope(scopeMetadata.getScopeName());
/**
* 生成 BeanName
* 調用 AnnotationBeanNameGenerator.generateBeanName()
*/
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
/**
* 處理類當中的通用註解
* 主要處理 @Lazy @DependsOn @Primary @Role @Description 等註解
* 處理完成之後將值賦給到 AnnotatedGenericBeanDefinition 對應的屬性中
*/
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
/**
* 如果在向容器註冊註解 BeanDefinition 時,使用了額外的限定符註解則解析
* byName 和 qualifiers 變量是 Annotation 類型的數組,裏面不僅存了 @Qualifier 註解
* 所以 Spring 遍歷這個數組判斷是否加了指定註解
*
* 此時 qualifiers 爲 null,if 語句不執行
*/
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 添加一個根據名字自動裝配的限定符
*/
// 向 Map<String, AutowireCandidateQualifier> qualifiers 集合中添加值
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
/**
* 如果存在一個或多個用於自定義工廠的回調
*
* 此時 customizers 爲 null,if 語句不執行
*/
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
/**
* 獲取 BeanDefinitionHolder 持有者容器
* 裏面包含的屬性值有 String beanName,BeanDefinition beanDefinition 和 String[] 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);
}
這裏比較重要的是最後一行代碼,進行註冊操作,代碼如下:
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
// 用類的主要名稱註冊 BeanDefinition
String beanName = definitionHolder.getBeanName();
/**
* 將 beanName 註冊到 DefaultListableBeanFactory 工廠中
*/
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
// 如果有別名則爲 BeanName 註冊別名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
/**
* 註冊別名
*/
registry.registerAlias(beanName, alias);
}
}
}
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// 先從 Map<String, BeanDefinition> beanDefinitionMap 中獲取一次
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
// 已註冊過則進行邏輯校驗
if (existingDefinition != null) {
// 是否允許 BeanDefinition 覆蓋
if (!isAllowBeanDefinitionOverriding()) {
// 不允許則拋異常
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
// 已存在的角色是否小於傳入的 beanDefinition 角色
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
// 如果傳入的 beanDefinition 和已存在的不相等
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
} else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 重新存入 Map<String, BeanDefinition> beanDefinitionMap 中
this.beanDefinitionMap.put(beanName, beanDefinition);
}
// 不存在
else {
// 是否已經啓動 bean 創建
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
// 註冊到 Map<String, BeanDefinition> beanDefinitionMap 集合中
this.beanDefinitionMap.put(beanName, beanDefinition);
// 用新的 beanDefinitionNames 替換舊的
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// 從集合中移除該 bean 名稱
removeManualSingletonName(beanName);
}
}
// 還未啓動 bean 創建,即仍在啓動註冊階段
else {
// 註冊到 Map<String, BeanDefinition> beanDefinitionMap 集合中
this.beanDefinitionMap.put(beanName, beanDefinition);
// 添加 bean 名稱到 beanDefinitionNames 數據集合中
this.beanDefinitionNames.add(beanName);
// 從集合中移除該 bean 名稱
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
register 方法執行完成,此時傳入的 @Configuration 配置類已經註冊到 DefaultListableBeanFactory 工廠中
那這一篇就先到這裏,有問題或者錯誤歡迎大家溝通交流
下一篇從 refresh 方法開始往下跟代碼