解讀 spring源碼

學習了好久的spring源碼,成果總結一下,不一定全對,都是自己研究的

//一、創建一個srping容器,並放置幾個核心的 Processor CommonAnnotationProcessor AutowiredAnnotationProcessor
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
//二、將入口類告知spring,你不說我怎麼知道哪個是入口,掃描包等都需要依賴註解類
annotationConfigApplicationContext.register(DemoApplication.class);
//三、核心類完成spring容器的初始化,一個bean的完整的生命週期都在這裏
annotationConfigApplicationContext.refresh();

一、創建spring容器,重要方法解讀  this.reader = new AnnotatedBeanDefinitionReader(this); 該方法會一直調用至如下方法:

這個方法其實就做了兩件事:

① 拿到了 GenericApplicationContext內的DefaultListableBeanFactory,其實這個GenericApplicationContext 就是一個BeanDefinitionRegistry

② 註冊了很多的Processor:說是註冊其實就是放到Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(4)裏面,其中這裏初始化的Beandefinition都是RootBeandefinition

    1、org.springframework.context.annotation.internalConfigurationAnnotationProcessor(非常重要完成了類------>beanDefinition的轉化)  對應:class org.springframework.context.annotation.ConfigurationClassPostProcessor

     2、org.springframework.context.annotation.internalAutowiredAnnotationProcessor

                 對應:class org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

     3、org.springframework.context.annotation.internalRequiredAnnotationProcessor

                對應: class org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor

     4、org.springframework.context.annotation.internalCommonAnnotationProcessor

                對應:class org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

     5、org.springframework.context.event.internalEventListenerProcessor

      6、org.springframework.context.event.internalEventListenerFactory

二、容器準備好了spring需要的BeanPostProcessor和BeanFactoryPostProcessor準備好了,下面需要把我們的入口類註冊給spring。

三、核心方法refresh

1、this.obtainFreshBeanFactory() 就是獲取 GenericApplicationContext中的 DefaultListableBeanFactory beanFactory。

2、prepareBeanFactory在beanFactory中添加一個需要的類,比如:ApplicationContextAware,ApplicationContext,還有兩個BeanPostProcessor:ApplicationContextAwareProcessor(重要)、ApplicationListenerDetector

3、invokeBeanFactoryPostProcessors 在bean初始化之前執行(beanFactory即DefaultListableBeanFactory 就是一個BeanDefinitionRegistry),調用beanFactoryPostProcessor(自定義的beanFactoryPostProcessor,程序員可以通過調用annotationConfigApplicationContext.addBeanFactoryPostProcessor(),向其中註冊beanFactoryPostProcessor)和BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry。

spring通過自己定義的 ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry

(非常重要) 完成對註解的掃描,把類封裝成了beanDefinition,其中遇到註解@Import 時,如果對應的類實現了ImportBeanDefinitionRegistrar 或者ImportSelector 遞歸遍歷所有的類,封裝成對應的beanDefinition,放入容器中。

這裏會把beanFactory傳進來,操作beanFactory完成一系列操作register就是beanFactory,此時beanDefinition只有7個,其中DemoApplication,是我們自己註冊進來的,如果beanDefinition被 @Configuration註解修飾,則是full的,後期會被生成一個代理類。

這裏的核心方法就是 ConfigurationClassParser.parse(Set<BeanDefinitionHolder> candidates), 轉化所有被註解修飾的類,變爲BeanDefinition,如果有@Import註解的話則循環掃描裏面所有的類,並封裝成beanDefinition。

4、registerBeanPostProcessors 註冊所有的BeanPostProcessors到beanFactory中

 ① ConfigurationPropertiesBindingPostProcessor

 ② CommonAnnotationBeanPostProcessor

 ③ AutowiredAnnotationBeanPostProcessor

 ④ RequiredAnnotationBeanPostProcessor

5、finishBeanFactoryInitialization 最核心的方法,完成了對象的創建,屬性填充,生命週期回調,aop。

 doGetBean內邏輯比較多 主要是:

 ① 調用 getSingleton,查看單例池中有沒有,或者是不是正在創建,多次調用getSingleton方法解決了循環依賴。

② 查看有沒有 parentBeanFactory,有沒有dependsOn註解等

③再次調用getSingleton,如果還沒有 則執行核心代碼 this.beforeSingletonCreation(beanName),

private final Set singletonsCurrentlyInCreation = Collections.synchronizedSet(new HashSet());

放入到一個set中,標識他正在創建中,如果有循環依賴則在調用 ①時 直接返回一個工廠 。

暴露工廠執行工廠的getObject()方法創建bean。

 ④這裏有個小插曲,描述如下:  

在spring createBean之前會調用 this.resolveBeforeInstantiation(beanName, mbdToUse) ,調用 如果bean 實現了InstantiationAwareBeanPostProcessor 並且 直接返回bean則spring不再創建,可能調用後置處理器:

 ⑤最重要的代碼

 1、創建bean對象,推斷構造方法+ 反射

 推斷構造方法:第 1  次後置處理器調用 ,會對所有的構造方法排序,public和方法參數多的在前,找到合適的構造方法,不過一般使用默認的,調用如下:

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors

反射:其實最後就是這一句話,使用默認的構造方法創建對象

ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);

2、第 2 次後置處理器調用: 調用applyMergedBeanDefinitionPostProcessors (mbd, beanType, beanName)方法進行bd的merge,合併會調用beanPostProcess的 MergedBeanDefinitionPostProcessor進行bd的合併。

3、第 3 次後置處理器調用:調用 AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean) 調用AbstractAutoProxyCreator 的 getEarlyBeanReference 提早完成 aop。

4、屬性填充: 

       ① 第4 次後置處理器調用: 如果某一個BeanDefinition 實現了 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation並且返回fasle,則可以自己完成屬性填充,後續spring不再填充屬性

        ② 會判斷注入模型 ,默認是0不自動注入。

       ③  第 5 次後置處理器調用: 最後調用所有的InstantiationAwareBeanPostProcessor類型的 beanPostProcess的 postProcessPropertyValues方法完成屬性注入,主要使用的是CommonAnnotationBeanPostProcesser和AutowiredAnnotationBeanPostProcesser兩個,這就是@Resource和@Autowired的區別。

5、initializeBean 初始化bean ,完成 生命週期回調,aop。

① 如果對應的類實現了Aware:BeanNameAware, BeanClassLoaderAware,BeanFactoryAware 則會提前執行這些方法。

②  第6次後置處理器調用: 執行所有的BeanPostProcess的 postProcessBeforeInitialization,如果使用 @PostConstruct 註解的方式聲明回調,則調用CommonAnnotationBeanPostProcess的 postProcessBeforeInitialization執行回調。

③  如果是實現了接口的 InitializingBean的afterPropertiesSet 方法,或者 是xml中配置的  init-method 則在 invokeInitMethods的時候通過方法反射完成回調。

第7 次後置處理器調用: 執行 BeanPostProcessor 的postProcessBeforeInitialization 。

 ④ 第8次後置處理器調用: 執行 所有的BeanPostProcessor 的applyBeanPostProcessorsAfterInitialization方法。

    spring 的aop就是在調用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 的              postProcessAfterInitialization 完成對象代理的,根據是否實現接口區分使用JdkDynamicAopProxy 動態代理還是Cglib代理。

如果循環依賴的話會提前完成aop,所以叫wrapIfNecessary。

調用代理DefaultAopProxyFactory的代理工廠,根據是否有接口選擇, jdk動態代理還是cglib代理

四、spring中使用的設計模式

  1、責任鏈模式:spring在bean實例化之前,需要對beanFactory進行一系列操作比如: 1、beanFactory的初始化 2、把bean解析成beanDefinition對象,3、執行beanFactoryPostProcessor把 實現ImportBeanDefinitionRegistrar接口的類生成的 BeanDefinition 加入到beanFactory的 Map<String, BeanDefinition> beanDefinitionMap中。4、把BeanPostProcess放入到beanFactory中,這一系列的操作中入參都只有beanFactory。

2、簡單工廠:application.getBean("a"),通過beanName生成對應的Bean。

3、工廠模式: factoryBean.getObject();返回的是一個bean,當然也可以是一個工廠類,這裏使用的就是工廠模式

4、單例模式,默認情況下bean都是單例的,因爲都放置到beanDefinitionMap 單例池中,初始化過的不會再初始化。

5、適配器模式:在springmvc中,controller的實現方式有兩種:1、使用註解@Controller 2、實現Controller接口 ,解析請求根據實現的方式對應不同的HandlerMapping,找到對應的 HandlerExecutionChain,再根據不同的HandlerExecutionChain生成不同的adapter,最後執行不同handler的方法,@controller是轉化成HandlerMethod執行 實現接口轉化成controller執行

6、代理模式: spring aop會生成一個代理對象執行對應的方法。

五、接口類圖整理

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章