spring系列:三、Bean的實例化和獲取

ApplicationContext與BeanFactory的關係

在這裏插入圖片描述

  • BeanFactory就是一個ioc容器,它採用的是延遲加載的策略,也就是只有在getBean的時候纔會實例化bean
  • ApplicationContext是BeanFactory的擴展接口,它採用的是立即加載的策略,也就是在配置文件加載的時候就會實例化bean。它提供了不同應用層的context的實現,例如在web開發中可以使用的WebApplicationContext
  • FileSystemXmlAppliCationContext,ApplicationContext的實現類,根據文件路徑獲取獲取配置文件
  • ClassPathXmlApplicationContext,ApplicationContext的實現類,根據文件名稱在classpath路徑下查找

Bean的實例化

  • 方式一:無參數構造

    <!-- 此種方式創建的bean必須提供無參構造 -->
    <bean name="bean1" class="cn.ade.domain.Bean1"/>
    
  • 方式二:靜態工廠方法

    public class Bean3Factory {
    
        /**
         * 使用靜態方法獲取對象
         *
         * @return
         */
        public static Bean3 createBean3() {
            return new Bean3();
        }
    
    }
    
    <!-- 使用靜態工廠的方法實例化對象 -->
    <bean name="bean3" class="cn.ade.utils.Bean3Factory" factory-method="createBean3"/>
    
  • 方式三:實例工廠方式

    public class Bean4Factory {
    
        /**
         * 使用非靜態方法獲取對象
         *
         * @return
         */
        public Bean4 getBean4() {
            return new Bean4();
        }
    
    }
    
    <!-- 使用實例工廠的方法實例化對象 -->
    <bean name="bean4Factory" class="cn.ade.utils.Bean4Factory"/>
    <bean name="bean4" factory-bean="bean4Factory" factory-method="getBean4"/>
    

bean的作用域

在創建bean的時候,有一個scope屬性,可取的值:

  • singleton,默認,單例模式,ioc容器中只有一個bean的實例
  • prototype,多例模式,每次從ioc容器中獲取bean的時候,都會實例化一個新的bean
  • request,用在web開發中,將bean存儲在request域中。簡單來講,request可以看做prototype的一種特例,除了場景更加具體之外,語意上差不多。
  • session,用在web開發中,將bean存儲在session域中。
  • global session,只有應用在基於porlet的web應用程序中才有意義,它映射到porlet的global範圍的session,如果普通的servlet的web 應用中使用了這個scope,容器會把它作爲普通的session的scope對待。

bean的生命週期

  • 第一步,instantiate bean,對象實例化 - 構造函數
  • 第二步,populate properties,封裝屬性 - set方法
  • 第三步,如果實現了BeanNameAware接口,執行方法setBeanName
  • 第四步,如果實現了 BeanFactoryAwar 或 ApplicationContextAwar 接口,在這裏設置工廠 setBeanFactory 或上下文對象 setApplicationContext
  • 第五步,如果存在類實現 BeanPostProcess(後處理 Bean),執行 postProcessBeforeInitialization
  • 第六步,如果實現了InitializingBean接口,執行 afterPropertiesSet - 增強
  • 第七步,調用自定義的 init-method 方法
  • 第八步,如果存在類實現 BeanPostProcessor(處理 Bean),執行 postProcessAfterInitialization - 增強
  • 第九步,執行業務方法
  • 第十步,如果實現了 DisposableBean 執行 destroy
  • 第十一步,調用自定義的 destroy-method,destroy-method 只對 scope=singleTon 有效果
    在這裏插入圖片描述
public class Bean5 implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {

    /**
     * 成員變量
     */
    private String info;

    /**
     * 空參構造
     * 在加載配置文件的時候,或者getBean的時候
     */
    public Bean5() {
        System.out.println("第一步:Bean5的實例化");
    }

    /**
     * 對成員變量info進行賦值
     *
     * @param info
     */
    public void setInfo(String info) {
        System.out.println("第二步:Bean5的屬性注入");
        this.info = info;
    }

    /**
     * 如果 Bean 實現 BeanNameAware 執行 setBeanName
     *
     * @param s
     */
    @Override
    public void setBeanName(String s) {
        System.out.println("第三步:獲取bean的id或name值:"+s);
    }

    /**
     * 如果 Bean 實現 BeanFactoryAwar 或 ApplicationContextAwar 設置工廠 setBeanFactory 或上下文對象 setApplicationContext
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("第四步:得到ApplicationContext對象:"+applicationContext);
    }

    /**
     * 如果 Bean 實現 InitializingBean 執行 afterPropertiesSet
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第六步:屬性注入完成後···");
    }

    /**
     * 調用自定義的 init-method 方法
     */
    public void MyInitMethod() {
        System.out.println("第七步:自定義的初始化方法");
    }

    /**
     * 測試方法
     */
    public void show() {
        System.out.println("第九步:執行業務操作");
    }

    /**
     * 如果 Bean 實現 DisposableBean 執行 destroy
     *
     * @throws Exception
     */
    @Override
    public void destroy() throws Exception {
        System.out.println("第十步:銷燬");
    }

    /**
     * 調用自定義的 destroy-method,destroy-method 只對 scope=singleTon 有效果
     */
    public void MyDestroyMethod() {
        System.out.println("第十一步:自定義的銷燬方法");
    }

}

public class MyBeanPostProcess implements BeanPostProcessor {

    /**
     * 如果存在類實現 BeanPostProcess(後處理 Bean),執行 postProcessBeforeInitialization
     *
     * @param o
     * @param s
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("第五步:存在類實現 BeanPostProcess(後處理 Bean),執行 postProcessBeforeInitialization");
        return o;
    }

    /**
     * 如果存在類實現 BeanPostProcessor(處理 Bean),執行 postProcessAfterInitialization
     *
     * @param o
     * @param s
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("第八步:存在類實現 BeanPostProcessor(處理 Bean),執行 postProcessAfterInitialization");
        return o;
    }

}
<!-- Bean的聲明週期 -->
<bean name="bean5" class="cn.ade.domain.Bean5" init-method="MyInitMethod" destroy-method="MyDestroyMethod" scope="singleton">
	<property name="info" value="Bean5"/>
</bean>
<bean class="cn.ade.utils.MyBeanPostProcess"/>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章