Spring IOC 源碼簡單分析 04 - bean的初始化
阿新 • • 發佈:2017-08-15
-s 示例 classpath 設置 isp 開始 follow spl abs
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()...
### 準備
## 目標
了解 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()..."); } } }<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
### 分析
## 文檔描述
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:- BeanNameAware‘s setBeanName
- BeanClassLoaderAware‘s setBeanClassLoader
- BeanFactoryAware‘s setBeanFactory
- EnvironmentAware‘s setEnvironment
- EmbeddedValueResolverAware‘s setEmbeddedValueResolver
- ResourceLoaderAware‘s setResourceLoader (only applicable when running in an application context)
- ApplicationEventPublisherAware‘s setApplicationEventPublisher (only applicable when running in an application context)
- MessageSourceAware‘s setMessageSource (only applicable when running in an application context)
- ApplicationContextAware‘s setApplicationContext (only applicable when running in an application context)
- ServletContextAware‘s setServletContext (only applicable when running in a web application context)
- postProcessBeforeInitialization methods of BeanPostProcessors
- InitializingBean‘s afterPropertiesSet
- a custom init-method definition
- postProcessAfterInitialization methods of BeanPostProcessors
- postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
- DisposableBean‘s destroy
- 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,調用每個 BeanPostProcessor的 postProcessAfterInitialization方法。Spring IOC 源碼簡單分析 04 - bean的初始化