1. 程式人生 > >Spring IOC 源碼簡單分析 04 - bean的初始化

Spring IOC 源碼簡單分析 04 - bean的初始化

-s 示例 classpath 設置 isp 開始 follow spl abs

### 準備

## 目標

了解 Spring 如何初始化 bean 實例

##測試代碼

gordon.study.spring.ioc.IOC04_Initialization.java public class IOC04_Initialization { public static void main(String[] args) { Resource resource = new ClassPathResource("ioc/ioc04.xml"); DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); BeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) factory); reader.loadBeanDefinitions(resource); factory.addBeanPostProcessor(new InnerBeanPostProcessor()); InnerClass inner = factory.getBean("inner", InnerClass.class); System.out.println("level: " + inner.level); factory.destroySingleton("inner"); } static class InnerBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("in postProcessBeforeInitialization()..."); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("in postProcessAfterInitialization()..."); if (bean instanceof InnerClass) { ((InnerClass) bean).level = 3; } return bean; } } static class InnerClass implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean { private int level; public InnerClass() { System.out.println("construct InnerClass..."); } @Override public void setBeanName(String name) { System.out.println("in setBeanName()..." + name); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("in setBeanClassLoader()..." + classLoader); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("in setBeanFactory()..." + beanFactory); } public void setLevel(int level) { System.out.println("in setLevel()..."); this.level = level; } @Override public void afterPropertiesSet() throws Exception { System.out.println("in afterPropertiesSet()..."); level = 2; } @Override public void destroy() throws Exception { System.out.println("in destroy()..."); } public void init() { System.out.println("in init()..."); } public void exit() { System.out.println("in exit()..."); } } }
ioc04.xml
<beans ...> <bean id="inner" class="gordon.study.spring.ioc.IOC04_Initialization$InnerClass" init-method="init" destroy-method="exit"> <property name="level" value="1" /> </bean> </beans> 執行結果 construct InnerClass... in setLevel()... in setBeanName()...inner
in setBeanClassLoader()...[email protected] in setBeanFactory()...org.springframework.beans.factory.support.DefaultListableBeanFact[email protected]: defining beans [inner]; root of factory hierarchy in postProcessBeforeInitialization()... in afterPropertiesSet()... in init()...
in postProcessAfterInitialization()... level: 3 in destroy()... in exit()...

### 分析

## 文檔描述

BeanFactory 類的文檔描述了 bean 生命周期中對外提供的擴展點。 Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:
  1. BeanNameAware‘s setBeanName
  2. BeanClassLoaderAware‘s setBeanClassLoader
  3. BeanFactoryAware‘s setBeanFactory
  4. EnvironmentAware‘s setEnvironment
  5. EmbeddedValueResolverAware‘s setEmbeddedValueResolver
  6. ResourceLoaderAware‘s setResourceLoader (only applicable when running in an application context)
  7. ApplicationEventPublisherAware‘s setApplicationEventPublisher (only applicable when running in an application context)
  8. MessageSourceAware‘s setMessageSource (only applicable when running in an application context)
  9. ApplicationContextAware‘s setApplicationContext (only applicable when running in an application context)
  10. ServletContextAware‘s setServletContext (only applicable when running in a web application context)
  11. postProcessBeforeInitialization methods of BeanPostProcessors
  12. InitializingBean‘s afterPropertiesSet
  13. a custom init-method definition
  14. postProcessAfterInitialization methods of BeanPostProcessors
On shutdown of a bean factory, the following lifecycle methods apply:
  1. postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
  2. DisposableBean‘s destroy
  3. a custom destroy-method definition

## 示例代碼分析

InnerClass 首先通過默認構造函數被實例化,輸出 construct InnerClass... 接著裝配屬性,調用 setLevel 方法設置 level 屬性,輸出 in setLevel()... 然後就開始初始化 bean。通過 AbstractAutowireCapableBeanFactory initializeBean 方法。 技術分享 接著,第1620行代碼處理 BeanPostProcessors 的 beforeInitialization 擴展點(11)。遍歷 List<BeanPostProcessor> beanPostProcessors,調用每個 BeanPostProcessor postProcessBeforeInitialization 方法。 然後,第1624行代碼調用初始化方法:如果 bean 是 InitializingBean 實例,則調用 afterPropertiesSet 方法(12);如果 XML 文件中還定義了 init-method,則通過反射調用 init-method(13)。此外,Spring 框架盡力保證同一個初始化方法不會執行多次(可以嘗試將 init-method 修改為 "afterPropertiesSet",看看執行結果)。 最後,第1633行代碼處理BeanPostProcessors 的 afterInitialization 擴展點(14)。遍歷 List<BeanPostProcessor> beanPostProcessors,調用每個 BeanPostProcessorpostProcessAfterInitialization方法。

Spring IOC 源碼簡單分析 04 - bean的初始化