Spring原始碼解析系列二:Spring初始化準備處理器過程
今天是Spring系列的第二篇文章,加油!
1.建立一個測試類
public class Test01 {
public static void main(String[] args) {
//這個構造方法會把Spring所有的環境都準備好
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
}
}
複製程式碼
2.點選 AnnotationConfigApplicationContext
public AnnotationConfigApplicationContext (Class<?>... annotatedClasses) {
//這個類有父類,所以會先初始化父類的構造方法,接著初始化自己的構造方法
//呼叫無參構造方法進行初始化一個讀取器和掃描器
this();
//把配置類載入進 DefaultListableBeanFactory 的map集合中
//配置類可以一次性傳多個,這個方法執行後,只是把配置類載入進了 DefaultListAbleBeanFactory的map集合中
//還沒有掃描其他的的加了元件的類
register(annotatedClasses);
//例項化所有被加了元件的物件
refresh();
}
複製程式碼
初始化 AnnotationConfigApplicationContext
這個類之前會首先初始化話其父類,
AnnotationConfigApplicationContext
` 的父類為 GenericApplicationContext
3.檢視 GenericApplicationContext
public GenericApplicationContext() {
//例項化工廠
this.beanFactory = new DefaultListableBeanFactory();
}
複製程式碼
DefaultListableBeanFactory
就是我們的 Bean工廠類
通過檢視 GenericApplicationContext
的預設構造方法發現,我們的神奇的Bean工廠是在這裡被初始化的
4.回到 AnnotationConfigApplicationContext
public AnnotationConfigApplicationContext() {
//建立一個讀取被加了註解的bean讀取器,當前物件傳過去
this.reader = new AnnotatedBeanDefinitionReader(this);
/**
* 可以用來掃描包來轉換成beanDefinition
* 但是Spring掃描包不是使用這個物件,而是使用ClassPathBeanDefinitionScanner
* 這裡的scanner僅僅是為了使用者之間能夠使用 AnnotationConfigApplicationContext物件的scan()方法
* 如果使用者沒有自己手動呼叫的話,其實是沒有掃描作用的
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
複製程式碼
檢視 AnnotationConfigApplicationContext
預設的構造方法,初始化了讀取器 AnnotatedBeanDefinitionReader
,準備處理器的功能就在這個類中,至於 ClassPathBeanDefinitionScanner
對於註解開發來說,似乎沒有什麼作用.
5.點選 AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry,getOrCreateEnvironment(registry));
}
複製程式碼
這裡沒有做什麼,呼叫另一個構造方法
通過引數BeanDefinitionRegistry
,我們可以發現 AnnotationConfigApplicationContext
物件,其實就是一個註冊器
此時的registry
實質就是AnnotationConfigApplicationContext
物件
6.點選 this
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry,Environment environment) {
Assert.notNull(registry,"BeanDefinitionRegistry must not be null");
Assert.notNull(environment,"Environment must not be null");
//把AnnotationConfigApplicationContext物件賦值給當前類的 registry
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry,environment,null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
複製程式碼
7.點選 registerAnnotationConfigProcessors
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
//同樣的構造方法名,引數列表不一樣
registerAnnotationConfigProcessors(registry,null);
}
複製程式碼
8.點選 registerAnnotationConfigProcessors
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry,@Nullable Object source) {
//通過registry,獲取beanFactory工廠物件
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
//新增排序物件 AnnotationAwareOrderComparator
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
//提供延遲載入的功能ContextAnnotationAutowireCandidateResolver
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
//BeanDefinitionHolder 裡面有一個beanName 和 beanDefinition 屬性方便傳引數
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/**
* 問個問題?為啥要註冊這個ConfigurationClassPostProcessor類到工廠的map集合中呢?
* 以後文章解析!
*/
//判斷整個環境中時候存在了這個常量
//org.springframework.context.annotation.internalConfigurationAnnotationProcessor
//CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME 會被作為beanName
//(1)把處理 ConfigurationClassPostProcessor的描述類 新增進 工廠
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));
}
//(2)把處理 AutowiredAnnotationBeanPostProcessor 的描述類 新增進 工廠
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry,AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry,COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//(3)把處理 CommonAnnotationBeanPostProcessor 的描述類 新增進 工廠
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,PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//(4)把處理 EventListenerMethodProcessor 的描述類 新增進 工廠
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry,EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
//(5)把處理 DefaultEventListenerFactory 的描述類 新增進 工廠
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry,EVENT_LISTENER_FACTORY_BEAN_NAME));
}
//在reader這個過程當中,這個返回值不會起任何作用
return beanDefs;
}
複製程式碼
9.點選 registerPostProcessor
方法
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry,RootBeanDefinition definition,String beanName) {
//ROLE_INFRASTRUCTURE=2 代表是Spring內部的類,ROLE_SUPPORT = 1;代表的是使用者的類
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//此時的beanName為就是Spring自己定義的常量字串
//這個方法就是把 內部類definition儲存到 beanDefinitionMap中
registry.registerBeanDefinition(beanName,definition);
return new BeanDefinitionHolder(definition,beanName);
}
複製程式碼
10.Ctrl+Alt+B 點選 registerBeanDefinition
我們選擇 DefaultListableBeanFactory
這個類,注意類就是開篇所說的 工廠類
@Override
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);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName,beanDefinition,existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
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()) {
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 {
//在這個方法中就把 beanDefinition 儲存在 DefaultListableBeanFactory的map集合中
//顧名思義,beanDefinitionMap就是一個儲存beanDefinition的map集合
//在這個集合當中還有Spring當中本身已經初始好的物件
this.beanDefinitionMap.put(beanName,beanDefinition);
//把beanName儲存在這個list集合中
this.beanDefinitionNames.add(beanName);
//這個是去重的,不是重點
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
複製程式碼
在 this.beanDefinitionMap.put(beanName,beanDefinition);
中把 處理器的描述類新增進 beanDefinitionMap
集合中
到了這裡Spring 就把需要的處理器新增進Spring工廠啦
視訊講解:
視訊為自己學習的時候錄製的,也方便自己以後看
Spring5原始碼地址:
github.com/zouchangfu/… gitee.com/zouchangfu/…
Spring5原始碼都是已經構建好的了,無需再使用gradle進行構建了,直接開啟就可以跑起來