接上回已經講完了this()方法,現在來看register(annotatedClasses);方法。
// new AnnotationConfigApplicationContext(AppConfig.class); 源碼
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//調用默認無參構造器,里面有一大堆初始化邏輯
this();
//把傳入的Class進行注冊,Class既可以有@Configuration注解,也可以沒有@Configuration注解
//怎么注冊? 委托給了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法進行注冊
// 傳入Class 生成 BeanDefinition , 然后通過 注冊到 BeanDefinitionRegistry
register(annotatedClasses);
//刷新容器上下文
refresh();
}
register(annotatedClasses) 方法
register(annotatedClasses);方法最后其實是調用了reader的doRegisterBean(annotatedClass, null, null, null);方法。
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//根據傳入的Class對象生成 AnnotatedGenericBeanDefinition ,
// AnnotatedGenericBeanDefinition 是 BeanDefinition 的 一個實現類
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
//根據 @Conditional 注解,判斷是否需要跳過解析
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析 Class<T> annotatedClass 是否有通用注解: @Lazy,@Primary,@DependsOn,@Role,@Description
// 並把解決結果放入 AnnotatedBeanDefinition 中
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//Class<? extends Annotation>[] qualifiers 是通過方法調用傳入的
// 上一步是解析Class中是否有注解,這一步是調用方作為參數傳入的
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
//org.springframework.beans.factory.support.AbstractBeanDefinition.qualifiers
//Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();
//直接放入map中
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//將該Class<T> annotatedClass 轉為 BeanDefinition 后, 通過再封裝為 BeanDefinitionHolder 對象,進行 registerBeanDefinition
//AnnotatedBeanDefinitionReader 中有一個 BeanDefinitionRegistry registry 是通過構造方法傳入的
//new AnnotationConfigApplicationContext(AppConfig.class); AnnotationConfigApplicationContext extends GenericApplicationContext
// GenericApplicationContext 類 實現了 BeanDefinitionRegistry ,registry 即為 AnnotationConfigApplicationContext
// GenericApplicationContext 類 內部 是 通過 DefaultListableBeanFactory 來實現 BeanDefinitionRegistry 接口的
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
- 根據傳入的
class對象創建AnnotatedGenericBeanDefinition,AnnotatedGenericBeanDefinition是BeanDefinition的一個實現類。 - 根據
@Conditional注解,判斷是否需要跳過解析,很明顯這里不需要,返回false,代碼繼續向下執行。 - 根據傳入的參數,設置
BeanDefinition的屬性 - 解析傳入的
class對象是否有通用注解(@Lazy、@Primary、@DependsOn、@Role、@Description),並把解析結果放入AnnotatedBeanDefinition中。 - 判斷是否有傳入
Class<? extends Annotation>[] qualifiers參數,如果不為null,則將傳入的qualifiers參數設置到BeanDefinition中。注意,第4步解析的是class中是否帶有通用注解。而這步判斷的注解是調用方手動傳入的。 - 將傳入的
class對象轉化為BeanDefinition后,再將BeanDefinition封裝到BeanDefinitionHolder中(為了方便傳參),然后調用BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);注冊該BeanDefinition。 - 調用
registerBeanDefinition方法時傳入的this.registry對象是AnnotatedBeanDefinitionReader的一個屬性,它是在構造方法中被初始化的。這個this.registry對象其實就是AnnotationConfigApplicationContext對象。AnnotationConfigApplicationContext繼承了GenericApplicationContext,GenericApplicationContext類實現了BeanDefinitionRegistry接口。而在GenericApplicationContext類中其實是委托給成員變量beanFactory來實現BeanDefinitionRegistry接口的。
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
- 再來看
registerBeanDefinition方法。主要是通過registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());方法將BeanDefinition注冊到DefaultListableBeanFactory中,也就是spring容器中。
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
而所謂的注冊BeanDefinition,簡單理解就是將BeanDefinition放到DefaultListableBeanFactory對象的beanDefinitionMap中。
//org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition方法源碼
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
//第一次進來existingDefinition肯定為null
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
} 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 + "]");
}
} 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 + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
} else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
運行完register(annotatedClasses);方法之后,spring容器中還沒有實例化bean,而只是注冊了一些BeanDefinition。(注冊的是Spring內部一些postProcessor和我們代碼傳入的AppConfig類)。

源碼學習筆記GITHUB倉庫地址:https://github.com/shenjianeng/spring-code-study
歡迎各位關注公眾號:

