Spring的基本功能就是IoC和AOP,咱們的bean都是交給Spring管理的。那麼Spring IoC是怎麼生成這些bean、又怎麼爲指定的bean進行AOP代理加強呢?答案就在Spring的啓動流程中。ios
爲了方便,這裏使用註解版的寫法來啓動Spring IoC容器。以下圖。緩存
這裏先說總結再講解源碼,先理清脈絡再深刻細節纔不會迷失在細節當中。markdown
如上圖所示,Spring的啓動過程主要能夠分爲兩部分:oop
Bean的生命週期以下圖,先有個印象便可,到源碼部分再回過頭來看看Bean的生命週期。post
我如今用的是Spring 5.2.6的源碼,Spring全註解版開發。ui
第一步就是new一個容器了。this
點進去看一下,能夠看到主要有三個方法,請記牢這三個方法,this(); register(componentClasses); refresh();spa
點擊進入this,看到裏層註冊了6個RootBeanDefinition,即系統級別的BeanDefinition。設計
再進去,能夠看到註冊BeanDefinition其實就是放到BeanFactory的緩存中。3d
以ConfigurationClassPostProcessor類爲例,其實它是一個BeanFactoryPostProcessor攔截器。注意,這部分回調的代碼在refresh()中才會執行的。因此下面說的BeanFactoryPostProcessor還不會執行,而是在refresh()中執行。
ConfigurationClassPostProcessor他是攔截配置類並解析裏面的Bean定義的。其攔截方法會檢查該類是不是配置類。
接着解析配置類。
解析@Import和@Bean
這個方法主要就是來註冊new AnnotationConfigApplicationContext(xxxConfiguration.class);傳進來的配置類的。
這是Spring啓動中最重要的方法。點進去看一下。其中invokeBeanFactoryPostProcessor故名思意就是調用BeanFactory後置處理器。registerBeanPostProcessors(beanFactory)註冊bean後置處理器,Bean後置處理器在Spring中應用很普遍,他能Bean建立過程當中的攔截處理器,相似BeanFactoryPostProcessor也是攔截器。
點進這個方法,finishBeanFactoryInitialization(beanFactory)。他是初始化bean的重要方法。bean既能夠經過@Bean來定義,也能夠經過FactoryBean來初始化。
點擊getBean(beanName)看看一個bean是怎麼建立的,同時,這也是Bean的生命週期。
看到createBean(beanName, mbd, args)方法
bean建立過程能夠分爲兩步,實例化Instantiation和初始化Initialization。實例化指的是建立bean實例,初始化指的是爲填充bean實例屬性(爲屬性賦值)。resolveBeforeInstantiation()方法在bean還沒實例化以前執行。提供給Bean後置處理器一個返回代理的機會,當你調用被代理的bean時,其實是執行了加強了的代理對象。
點進去doCreateBean方法。這裏就是bean的生命週期了,如開篇放出的這張圖。
bean的生命週期,能夠看到第一步就建立了實例
點擊該方法createBeanInstance進去,能夠看到最終就是經過Java的反射來建立bean對象的。
點進去initializeBean方法查看,能夠看到和上面生命週期的圖吻合。先檢查Aware接口,再到Bean後置處理器的前置處理方法,接着調用初始化方法。
bean的生命週期
至此,bean的IoC容器功能啓動流程講解結束。
Spring代理加強方面,咱們在上面的IoC容器部分看到實例化bean以前,實際上是有先判斷bean是否須要加強,該方法爲resolveBeforeInstantiation(beanName, mdbToUse),注意該方法是在bean實例化以前的,即先判斷是否須要建立代理,若是不須要纔會建立bean,不然建立的是代理對象。
夜深了,待續。明天再寫寫AOP部分的內容。
我來更新啦。
那麼,Spring Aop是怎麼建立代理的呢,咱們來看下resolveBeforeInstantiation(beanName, bdbToUse)方法。
能夠看到它調用的是InstantiationAwareBeanPostProcessor這個Bean後置處理器的方法,從類名字上看他是攔截Bean實例化階段、而不是初始化階段的。點進去看一下,能夠發現他是經過調用InstantiationAwareBeanPostProcessor的回調方法來生成bean對象的。
調用postProcessBeforeInstantiation方法生成對象。
至此,暫且打住。咱們來看看咱們通常是怎麼使用Spring Aop的。
咱們會寫一個@Aspect註解的切面類,並使用@EnableAspectJAutoProxy註解啓用代理。
點進去能夠發現,它導入了一個類AspectJAutoProxyRegistrar到Spring容器中。
該類是一個ImportBeanDefinitionRegistrar類,搜索能夠發現,ImportBeanDefinitionRegistrar類會在解析配置類的時候調用registerBeanDefinitions方法。
該方法會向容器中注入一個AnnotationAwareAspectJAutoProxyCreator類的Bean定義。
AnnotationAwareAspectJAutoProxyCreator類是一個InstantiationAwareBeanPostProcessor。
講到這裏,就和上面吻合了,實例化bean時現執行InstantiationAwareBeanPostProcessor,若是有返回對象,則使用該對象,不然纔去建立實例。因此@EnableAspectJAutoProxy註解的做用就是向容器中添加一個InstantiationAwareBeanPostProcessor類,攔截bean的建立並生成代理對象。
該攔截處理器以下,建立了一個代理對象並返回。
點進來createProxy(beanClass, beanName, specificInterceptor, targetSource)方法並跟蹤下層代碼,能夠發現動態代理建立有兩種方式,若是該類是接口,則使用JDK動態代理,不然使用的是Cglib代理。
至此,Aop部分代碼講解結束。
其中,IoC的循環依賴問題和Aop的攔截器鏈設計有興趣的能夠推薦看一下源碼。