spring通過配置文件描述bean與bean之間的依賴關係,利用java的反射機制來實例化bean並建立bean之間的依賴關係。
其中BeanFactory是spring框架最核心的接口,管理不同類型的java對象,面對spring本身。
ApplicationContext建立在BeanFactory的基礎之上,提供面向應用的功能,稱爲應用上下文,面向使用spring框架的開發者。
注:兩者有一個很大的不同,後者會利用java反射機制自動識別配置文件定義的BeanPostProcessor、InstantiationAwareBeanPostProcessor,並自動註冊到應用上下文中;而前者則要在代碼中通過手動調用addBeanPostProcessor()方法進行註冊。正因爲如此,我們在應用開發時,普遍使用ApplicationContext.
反射會用到幾個重要的類,分別是ClassLoader,Class,Constructor,Method,Field,這些類協助就可以間接的調用目標類的各項功能了。
可參考文章:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html,裏面介紹反射各種案例,還是挺全面的
類裝載器由ClassLoader及其子類負責,是一個重要的java運行時系統組件,它負責在運行時查找和裝載Class字節碼文件。步驟:
1. 裝載:查找並導入字節碼文件
2. 鏈接
校驗:檢查字節碼文件的正確性
準備:爲靜態變量分配存儲空間
解析:將符號引用轉變成直接引用
3. 初始化:對靜態變量、靜態代碼塊執行初始化工作
其中類加載器有三種:根裝載器、ExtClassLoader(擴展類裝載器),AppClassLoader(系統類裝載器),其中根裝載器是用C++編寫的,其它兩個是java編寫的。根裝載器負責加載JRE核心類庫,ExtClassLoader負責加載ext目錄下的jar包;AppClassLoader負責加載Classpath路徑下的jar包。
例子:
public static void main(String[] args) {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
System.out.println("current loader:"+loader);
System.out.println("parent loader:"+loader.getParent());
System.out.println("grandparent loader:"+loader.getParent().getParent());
}
ApplicationContext類繼承體系類圖
ApplicationContext的主要實現類有兩個:ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者從類路徑加載配置文件,後者是從文件系統加載配置文件。
ApplicationEventPublish:讓容器發佈應用上下文事件功能,包括容器啓動事件,關閉事件等
MessageSource:爲應用提供i18n國際化消息訪問功能
ResourceLoader:裝載資源
LifeCycle:spring2.0引入的,有start和stop兩個方法,控制異步處理過程
HierarchicalBeanFactory:使用容器可以建立父子層級關聯容器,子容器可以訪問父容器中的Bean,而父容器不能訪問子容器的Bean。可以應用在Spring MVC,表現層的Bean存於子容器中,業務層和持久層的Bean存於父容器中。
Bean的生命週期:
涉及的關鍵點大致劃分爲三類:
1) Bean自身的方法:如調用Bean構造函數實例化Bean,調用setter屬性設置Bean屬性值及通過<bean>的init-method和destory-method所指定的方法
2) Bean級生命週期接口方法:如BeanNameAware,BeanFactoryAware,initializingBean以及DisposableBean,這些接口由直接實現
3) InstantiationAwareBeanPostProcessor和BeanPostProcessor這兩個接口,一般稱爲它們的實現類爲“後處理器”。後處理器一般不由bean本身實現,
它們獨立於Bean,實現類以附加形式註冊到Spring容器中,可以理解爲bean的過濾器。當Spring創建任何Bean的時候,這些後處理器就會發揮作
用,其影響範圍具有全局性。開發者可以通過編寫後處理器,對感興趣的Bean加工處理(instanceof 匹配類型)
注:通過init-method和destory-method屬性配置的方法爲Bean指定初始化和銷燬的方法,另一種通過實現initializingBean和DisposableBean接口,兩者的效果是一樣的。但是前者採用配置的方式,使用bean不需要和特定的spring框架接口綁定,達到和框架解耦的目地。
BeanPostProcessor的使用例子:
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import com.baobaotao.Car;
public class MyBeanPostProcessor implements BeanPostProcessor{
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("car")){
Car car = (Car)bean;
if(car.getMaxSpeed() >= 200){
System.out.println("調用MyBeanPostProcessor.postProcessAfterInitialization(),將maxSpeed調整爲200。");
car.setMaxSpeed(200);
}
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("car")){
Car car = (Car)bean;
if(car.getColor() == null){
System.out.println("調用MyBeanPostProcessor.postProcessBeforeInitialization(),color爲空,設置爲默認黑色。");
car.setColor("黑色");
}
}
return bean;
}
}