spring載入bean原理。
阿新 • • 發佈:2019-01-22
Spring管理bean:
1.從web.xml裡面配置的ContextLoaderListener開始。
2.ContextLoaderListener繼承ContextLoader
3.執行ContextLoaderListener的contextInitialized方法,獲得servletContext.
4.把servletContext傳入ContextLoader的initWebApplicationContext(ServletContext servletContext)方法並執行。
5.通過ContextLoader.createWebApplicationContext(servletContext)獲得this.context( WebApplicationContext)例項。
預設情況下這個context就是XmlWebApplicationContext。
這個XmlWebApplicationContext繼承一個AbstractApplicationContext類。
再執行ContextLoader.configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc)方法,
執行AbstractApplicationContext的.refresh();方法
這個方法完成了WebApplicationContext裡面的beanfactory的初始化和bean載入,beanfactorypostprocessor的呼叫,beanpostprocessor的註冊,ApplicationEvent的監聽和註冊,non-lazy-init的bean的初始化。@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex); // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } }
換言之,已經把該準備的都準備好了,只需要有請求來獲取bean,就根據情況或返回已經初始化的bean或進行bean的Instantiation 和 Initialization。