Spring的ApplicationContext實例化源碼解析

Spring的ApplicationContext來獲得Bean的操作,通過ApplicationContext context = new ClassPathXmlApplicationContext("spring/test-bean.xml");這個代碼進行了調試,於是把整個流程做了整理

在看下面的流程前可以看看下面的類圖:


整個流程中,Spring留了很多可以覆蓋的方法和需要實現的接口,可以方便我們在整個流程中的適當地方個性化自己的功能。

1.AbstractApplicationContext.java中的protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException

/**
* Subclasses must implement this method to perform the actual configuration load.
* The method is invoked by {@link #refresh()} before any other initialization work.
* <p>A subclass will either create a new bean factory and hold a reference to it,
* or return a single BeanFactory instance that it holds. In the latter case, it will
* usually throw an IllegalStateException if refreshing the context more than once.
* @throws BeansException if initialization of the bean factory failed
* @throws IllegalStateException if already initialized and multiple refresh
* attempts are not supported
*/

       繼承AbstractApplicationContext,實現這個方法,在這個方法中構造出自己特有的BeanFactory,可以參照AbstractRefreshableApplicationContext.java對於這個的實現 

       refreshBeanFactory會調用在AbstractRefreshableApplicationContext.java中的loadBeanDefinitions方法,這個方法是抽象的,可以交給具體的實現,比如支持從XML文件獲取Bean的配置信息,也可以實現這個方法,在這個方法中從數據庫,從遠程服務上獲取Bean

2.AbstractApplicationContext.java中的public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException

/**
* Subclasses must return their internal bean factory here. They should implement the
* lookup efficiently, so that it can be called repeatedly without a performance penalty.
* <p>Note: Subclasses should check whether the context is still active before
* returning the internal bean factory. The internal factory should generally be
* considered unavailable once the context has been closed.
* @return this application context's internal bean factory (never <code>null</code>)
* @throws IllegalStateException if the context does not hold an internal bean factory yet
* (usually if {@link #refresh()} has never been called) or if the context has been
* closed already
* @see #refreshBeanFactory()
* @see #closeBeanFactory()
*/

        繼承AbstractApplicationContext,實現這個方法,在這個方法中返回上面refreshBeanFactory中構造出來的BeanFactory,可以參照AbstractRefreshableApplicationContext.java對於這個的實現


3.AbstractApplicationContext.java中的protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)

/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
* @param beanFactory the bean factory used by the application context
*/

        繼承AbstractApplicationContext,實現這個方法,在這個方法中可以添加自己的BeanPostProcessors,當然通過Spring文件配置也是可以的,因爲後面registerBeanPostProcessors會從Spring配置文件中查找實現BeanPostProcessor的類,當然也可以註冊自己的BeanFactoryPostProcessors


4.BeanFactoryPostProcessor.java中的void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException

/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/

         這裏可以做和上面3同樣的事情


5.BeanPostProcessor.java中的Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException

/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's <code>afterPropertiesSet</code>
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/

       這個方法會在類的實例化之前執行,所以說執行順序是postProcessBeforeInitialization->afterPropertiesSet->init-method

==================================上面5個方法都是Bean還沒有實例化之前執行的=============================================

6.BeanPostProcessor.java中的Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException

       /**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's <code>afterPropertiesSet</code>
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding <code>bean instanceof FactoryBean</code> checks.
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/

       這個方法會在類的實例化之後執行,所以說執行順序是postProcessBeforeInitialization->afterPropertiesSet->init-method->postProcessAfterInitialization


下面是詳細的時序圖:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章