spring bean 創建


原地址 : http://www.cnblogs.com/fyx158497308/p/3977391.html


一、首先我們來看ClassPathXmlApplicationContext類體系結構


從該繼承體系可以看出:

1.       BeanFactory 是一個 bean 工廠的最基本定義,裏面包含了一個 bean 工廠的幾個最基本的方 法,getBean(…) 、 containsBean(…) 等 ,是一個很純粹的bean工廠,不關注資源、資源位置、事件等。 ApplicationContext 是一個容器的最基本接口定義,它繼承了 BeanFactory, 擁有工廠的基本方法。同時繼承了 ApplicationEventPublisher 、 MessageSource 、 ResourcePatternResolver 等接口, 使其 定義了一些額外的功能,如資源、事件等這些額外的功能。

2.      AbstractBeanFactory 和 AbstractAutowireCapableBeanFactory 是兩個模 板抽象工廠類。AbstractBeanFactory 提供了 bean 工廠的抽象基類,同時提供 了 ConfigurableBeanFactory 的完整實現。AbstractAutowireCapableBeanFactory 是繼承 了 AbstractBeanFactory 的抽象工廠,裏面提供了 bean 創建的支持,包括 bean 的創建、依賴注入、檢查等等功能,是一個 核心的 bean 工廠基類。

3.       ClassPathXmlApplicationContext之 所以擁有 bean 工廠的功能是通過持有一個真正的 bean 工廠DefaultListableBeanFactory 的實例,並通過 代理 該工廠完成。

4.       ClassPathXmlApplicationContext 的初始化過程是對本身容器的初始化同時也是對其持有的DefaultListableBeanFactory 的初始化。

二、容器的初始化過程

我們知道在spring中BeanDefinition很重要。因爲Bean的創建是基於它的。容器AbstractApplicationContext中有個方法是refresh()這個裏面包含了整個Bean的初始化流程實現過程,如果我們需要自己寫一個ClassPathXmlApplicationContext類的話我們可以繼承這個類,下面貼段這個方法的代碼:

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) {
                // Destroy already created singletons to avoid dangling resources.
                beanFactory.destroySingletons();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }
        }
    }



 如上代碼加上圖片就是整個Bean的初始化過程。我們知道Bean有可以配置單列以及懶加載形式。在初始化的過程中,我們也能很好的觀察到這個過程的實現。

在AbstractBeanFactory中定義了getBean()方法,而它又調用doGetBean().

 

GetBean 的大概過程:

1.       先試着從單例緩存對象裏獲取。

2.       從父容器裏取定義,有則由父容器創建。

3.       如果是單例,則走單例對象的創建過程:在 spring 容器裏單例對象和非單例對象的創建過程是一樣的。都會調用父 類 AbstractAutowireCapableBeanFactory 的 createBean 方法。 不同的是單例對象只創建一次並且需要緩 存起來。 DefaultListableBeanFactory 的父類 DefaultSingletonBeanRegistry 提供了對單例對 象緩存等支持工作。所以是單例對象的話會調用 DefaultSingletonBeanRegistry 的 getSingleton 方法,它會間 接調用AbstractAutowireCapableBeanFactory 的 createBean 方法。

如果是 Prototype 多例則直接調用父類 AbstractAutowireCapableBeanFactory 的 createBean 方法。


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