Spring框架是一個開源的java平臺充易,基于Spring框架開發(fā)服務(wù)項目非常容易随抠,迅速和健壯裁着。框架簡單理解就是封裝一層拱她,而這一層可以稱為其原理二驰。如果不明其理,可能會處處入坑秉沼,漂浮不落地感覺桶雀,哈哈 扯了好多廢話,Spring工廠化 IOC 配置化氧猬,我們可以通過xml 配置 bean背犯,但這里想記錄的是bean的實例化過程。
首先一個疑惑是以前的tomcat去哪里了盅抚?他們是如何銜接的呢漠魏?tomcat中有一個ServletContextListener的概念,spring中有一個ContextLoaderListener概念(其實也是個ServletContextListener)妄均,截圖看下源碼怎說吧柱锹,spring一般是在contextLoaderListener這里listener里初始化的哪自。
前戲好了,進(jìn)入主題吧禁熏。spring的啟動過程我先人為的分成2個大階段
一壤巷,
1 容器啟動階段
2 ? 加載配置
3 ? 分析配置信息
4 ? 裝載在BeanDefinition (元數(shù)據(jù) 存放了一個bean 屬性 屬性值 等metadata信息)
5? BeanDefinitionRegistryPostProcessor 標(biāo)準(zhǔn)BeanFactoryPostProcessor的擴展,BeanFactoryPostProcessor的作用是用來進(jìn)一步定義注冊的BeanDefinition.
6? 容器擴展機制(BeanFactoryPostProcessor僅次于BeanDefinitionRegistryPostProcessor被實例化瞧毙。它們在同一個方法進(jìn)行實例化胧华,只是順序有先后)PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
。宙彪。矩动。。
二释漆,
1. 實例化;
2. 設(shè)置屬性值;
3. 如果實現(xiàn)了BeanNameAware接口,調(diào)用setBeanName設(shè)置Bean的ID或者Name;
4. 如果實現(xiàn)BeanFactoryAware接口,調(diào)用setBeanFactory 設(shè)置BeanFactory;
5. 如果實現(xiàn)ApplicationContextAware,調(diào)用setApplicationContext設(shè)置ApplicationContext
6. 調(diào)用BeanPostProcessor的預(yù)先初始化方法;
7. 調(diào)用InitializingBean的afterPropertiesSet()方法;
8. 調(diào)用定制init-method方法悲没;
9. 調(diào)用BeanPostProcessor的后初始化方法;
下面詳細(xì)說下過程
?這個過程著重根據(jù)xml配置bean的時候用的占位符被解析的過程來說。
spring中通過xml 定義bean 同時提供了xmlparser 去解析加載然后解析xml文件中的各種bean的定義男图,將xml文件中的每一個元素分別轉(zhuǎn)換成一個BeanDefinition對象示姿,其中保存了從配置文件中讀取到的該bean的各種信息,然后通過BeanDefinitionRegistry將這些bean注冊到beanFactory逊笆,BeanDefinition被注冊到了 DefaultListableBeanFactory
一個博客說明了beandefinition構(gòu)建過程:http://www.cnblogs.com/digdeep/p/4518571.html
上面這些一開始我是誤解為這里就實力化程實例了栈戳,現(xiàn)在來看是錯的
下面看下實用的例子 我們知道 xml中bean屬性的配置可以提供占位符,最終會從spring的properties文件中找到值替換览露,
那么這個過程發(fā)生在哪里荧琼,這個過程發(fā)生在容器擴展機制這里,BeanDefinition注冊到了beanFactory之后差牛,在這里Spring為我們提供了一個擴展的切口,允許我們通過實現(xiàn)接口BeanFactoryPostProcessor 其中PropertyResourceConfigurer為其實現(xiàn)堰乔,該類的作用就是為了替換Beandefinition中占位符偏化,
下面是PropertyResourceConfigurer類中 被postProcessBeanFactory調(diào)用到的方法,其中說明了要替換對應(yīng)beanFactory中beanDefinition的占位符镐侯。
/**
* Visit each bean definition in the given bean factory and attempt to replace ${...} property
* placeholders with values from the given properties.
*/
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)throws BeansException {
StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props);
doProcessProperties(beanFactoryToProcess, valueResolver);
}
至此 bean的元數(shù)據(jù)beandefinition 已經(jīng)完善侦讨,進(jìn)入第二階段
bean的實例化的階段,實例化階段主要是通過反射或者CGLIB對bean進(jìn)行實例化苟翻。
腦子是個好東西韵卤,可是我只有一個,容量也不大崇猫,還是即使落地吧沈条。不然會有故障的風(fēng)險,哈哈哈哈诅炉,有些東西之前在為知筆記記錄過蜡歹,現(xiàn)在感覺碎片太多了屋厘,需要重新申請一個大磁盤整理一下。稍后會陸續(xù)更新吧^_^月而。(整理篇)