IOC源碼這一塊太多只能講個大概吧,建議還是去買本Spring IOC源碼解析的書來看比較好,我也是自己看源代碼以及視頻整理的筆記
Bean的生命周期大概可以分為四個階段,具體的等會再說,先看看IOC的源碼吧
1、bean的創建
2、bean的屬性賦值
3、bean的初始化
4、bean的銷毀
IOC容器源碼解析
我們創建容器以new?AnnotationConfigApplicationContext(Config.class)為示例,我們點開源代碼,看一下
其實做了挺多事的,在父類的的無參構造函數當中,就創建了一個BeanFactory的實例,其實可以去看一下這個類的無參構造函數,其實加載了很多必備的Bean到容器當中,例如之前提到過的一些常用的BeanPostProcessor,這里就不多說了,不然博客會太長了
接下來就是第一個方法register(componentClasses)解析配置類的注解,并且創建了BeanFactory的實例(org.springframework.beans.factory.support.DefaultListableBeanFactory的實例)并且將配置類注入到容器中
方法點進去之后能看到
?我們進到注冊Bean的方法(BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);)里面
我們看一下是怎么注入的
其實就是將對象包裝成BeanDefinition對象,然后添加到ConcurrentHashMap當中。
第二部,進入到refresh()方法,但是該方法位于父類的org.springframework.context.support.AbstractApplicationContext.class的515行,這個是一個刷新方法,將我們的業務Bean注入進去
無論是通過哪種創建Spring?的ioc容器都會執行這個refresh方法。大致的主要方法如下,不過有些方法的細節就不講了,IOC過于龐大,懂個大概就差不多了,但是方法具體是干嘛的會一個一個講
prepareRefresh()
1)、initPropertySources()初始化一些屬性設置;子類自定義個性化的屬性設置方法;
2)、getEnvironment().validateRequiredProperties();檢驗屬性的合法等
3)、earlyApplicationEvents= new LinkedHashSet<ApplicationEvent>();保存容器中的一些早期的事件;
obtainFreshBeanFactory()
獲取到BeanFactory對象
prepareBeanFactory(beanFactory)
設置一下BeanFactory對象一些屬性
???????? 1)、設置BeanFactory的類加載器、支持表達式解析器...
???????? 2)、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
???????? 3)、設置忽略的自動裝配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
???????? 4)、注冊可以解析的自動裝配;我們能直接在任何組件中自動注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
???????? 5)、添加BeanPostProcessor【ApplicationListenerDetector】
???????? 6)、添加一些loadTimeWeaver;
???????? 7)、給BeanFactory中注冊一些能用的組件;
?????????????????? environment【ConfigurableEnvironment】、
?????????????????? systemProperties【Map<String, Object>】、
?????????????????? systemEnvironment【Map<String, Object>】
postProcessBeanFactory(beanFactory)
BeanFactory完成的后置工作,當前為空,但是可以繼承當前類,在子類中可以實現這個方法
invokeBeanFactoryPostProcessors(beanFactory)
加載并執行BeanFactoryPostProcessor以及BeanDefinitionRegistryPostProcessor這兩個接口的兩個實現方法
1、postProcessBeanFactory()
2、postProcessBeanDefinitionRegistry():
這個方法里面做了很多加載,這里就不展示,自行去看源碼吧
initMessageSource()
注冊一個MessageSource的對象,但是這個Bean并沒有加載到之前的那個Map當中,而是加載到一個緩存的Map當中,用于解決循環依賴
initApplicationEventMulticaster()
初始化一個派發器,跟上面那個差不多,只是對象不一樣
onRefresh()
跟之前的那個postProcessorBeanFactory方法差不多,留給子類實現
registerListeners()
注冊監聽器,實現ApplicationListener<?>接口,并指定時在什么時候加載即指定ContextEvent
finishBeanFactoryInitialization(beanFactory)
這個就是加載所有業務單實例Bean的方法,并且生命周期都會在這里執行,首先會配置一些BeanFactory的一些屬性,然后在加載業務Bean
第一部分優先獲取Bean名稱的一些定義信息getMergedLocalBeanDefinition(beanName),然后先處理實現FactoryBean的Bean
點進去getBean(beanName)之后,調用方法?doGetBean(name, null, null, false),這個方法就不貼截圖了,代碼太多不好截圖,可以自己去對照這源碼看,就講調用了哪個方法就好了。
Object sharedInstance = getSingleton(beanName)?從緩存的Bean中去獲取看看在不在,如果存在的話就直接獲取(會去校驗FactoryBean緩存中是否存在),不存在就執行else方法
如果緩存中不存在的話,就是一個新的Bean等待創建
運行到了markBeanAsCreated(String beanName),這個是用來標記當前beanName已經存在了,將beanName添加到alreadyCreated集合當中,然后運行到了下面
然后繼續執行
進入到createBean()方法后,有個獲取代理的方法,這個方法就得講一下,跟Spring的AOP以及事務有關
Object bean = resolveBeforeInstantiation(beanName, mbdToUse)講解:
我們點開查看一下這個方法,有個createProxy()創建代理方法
進入到創建代理的方法里面,我們看一下
我們點開getProxy方法,會返回一個createAopProxy().getProxy(classLoader);對象,我們依次點開后,在使用AOP到底是JDK動態代理還是CGLIB代理的關鍵所在
好了,代理的那個方法差不多了,我們改回到正題了
我們進入到Object beanInstance = doCreateBean(beanName, mbdToUse, args);
有個BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);這個是創建BeanWrapper的包裝類,在createBeanInstance方法中最后會執行instantiateBean()
我們進入到這個instantiate(),最后有個BeanUtils.instantiateClass(constructorToUse)方法用來創建對象,這就不深入的討論了,大家可以自己去看
然后包裝一個BeanWrapperImpl對象,最后返回出去;創建好后,進行屬性賦值以及Bean的初始化,在屬性賦值的方法里面有個InstantiationAwareBeanPostProcessors方法執行
我們看下初始化方法
Bean的初始化,會先加載Aware,然后調用BeanPostProcessor的前置方法,然后加載初始化方法,再加載BeanPostProcessor的后置方法
這個方法基本就加載完了
finishRefresh()
加載完業務Bean的一些工作
resetCommonCaches()
這個是處于finally代碼塊的方法用來清除創建時臨時緩存數據
Bean生命周期
在上面IOC分析里面已經提到了Bean的創建以及屬性賦值了
接下來就是初始化以及銷毀
初始化
初始化使用的方法有三種
1、@Bean(initMethod = "")調用指定初始化方法
2、在類中設置@PostConstruct注解
3、實現InitializingBean接口,實現afterPropertiesSet()方法
銷毀
對應的銷毀也有三種
1、@Bean(destroyMethod= "")調用指定銷毀方法
2、在類中設置@PreDestroy注解
3、實現DisposableBean接口,實現destroy()方法
銷毀在容器關閉是時候執行