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"/>