白話Spring原始碼(四):BeanFactory
一、什麼是BeanFactory
我們先學習Spring最核心的功能:IoC,控制反轉又叫依賴注入,這概念是不是很難理解,這是出於商業的目的才起這麼個高大上的概念,其實我們閱讀原始碼後發現其實很簡單:就是物件通過xml定義好,然後通過java的反射機制new出物件,最後放在一個map裡,想用就就從map裡get出來。我們很多時候是被概念嚇住了。但是我們要開發出很穩定的,擴充套件性好的還是很不容易。
好了,我們先從最基礎的BeanFactory開始吧!
BeanFactory是什麼?這是個工廠模式,工廠模式就是我們不直接new一個物件,而是從工廠裡取,工廠會建立給我們。
那BeanFactory就是我們不直接new一個bean,而是BeanFactory建立好返回給我們。
可能有人會問什麼是bean啊?可能很多人一直在用,但不一定能回答上來
bean英文豆子的意思,我們知道java一種咖啡,那javabean就是咖啡豆,所以javabean就java中很基礎的一個元件,注意這不是spring發明的,是jre自帶的。
它通常具有如下特點:
- 這個Java類必須具有一個無參的建構函式
- 屬性必須私有化。
- 私有化的屬性必須通過public型別的方法暴露給其它程式,並且方法的命名也必須遵守一定的命名規範。
為什麼要這些規範呢?我們得要了解元件,國外的程式設計師喜歡用影象化的方式來做業務的開發,就是類似vb,.net的拖拖放放,然後修改屬性和新增事件,這些可以拖拽的圖形就是元件啦!現在國外還是有很多用圖形化來生成java物件,開發業務的功能的。所以這些規範就方便建立物件,設定屬性值,設定物件的依賴的。
javabean的demo
public class StudentsBean implements java.io.Serializable { private String firstName = null; private String lastName = null; private int age = 0; public StudentsBean() { } public String getFirstName(){ return firstName; } public String getLastName(){ return lastName; } public int getAge(){ return age; } public void setFirstName(String firstName){ this.firstName = firstName; } public void setLastName(String lastName){ this.lastName = lastName; } public void setAge(int age) { this.age = age; } }
二、BeanFactory的結構
beanFactory及子介面的結構圖:
看到這邊,我們是不是想起了設計模式原則裡的介面隔離原則
Interface Segregation Principle(ISP):客戶端不應該依賴它不需要的介面;類間的依賴關係應該建立在最小的介面上
這邊清晰地定義瞭如下的體系:
根介面BeanFactory(基礎容器)
第二層: 第三方整合,繼承體系,遍歷bean
第三層: 配置功能
第四層: 配置+迭代
具體原始碼如下:
1.BeanFactory原始碼,主要就是獲取bean物件
public interface BeanFactory {
/**
* 通過名稱獲取bean物件
*/
Object getBean(String name) throws BeansException;
/**
* 通過名稱獲取bean物件,並驗證bean的型別
*/
Object getBean(String name, Class requiredType) throws BeansException;
/**
* 是否包含改名稱的bean
*/
boolean containsBean(String name);
/**
* 判斷是否是單列
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
/**
* 獲取別名陣列
*/
String[] getAliases(String name) throws NoSuchBeanDefinitionException;
}
2.HierarchicalBeanFactory :工廠可以分層,有父工廠
public interface HierarchicalBeanFactory extends BeanFactory {
/**
* 獲取父級工廠
*/
BeanFactory getParentBeanFactory();
}
3.AutowireCapableBeanFactory :是工廠可以自動裝配(設定類欄位的值)
public interface AutowireCapableBeanFactory extends BeanFactory {
/**
* 按名稱裝配
*/
int AUTOWIRE_BY_NAME = 1;
/**
* 按型別裝配
*/
int AUTOWIRE_BY_TYPE = 2;
/**
* 按構造發放裝配
*/
int AUTOWIRE_CONSTRUCTOR = 3;
/**
* 首先會嘗試使用constructor進行自動裝配,如果失敗再嘗試使用byTypeegy
*/
int AUTOWIRE_AUTODETECT = 4;
/**
* 通過自動裝配例項化物件
*/
Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck)
throws BeansException;
/**
* 自動裝配存在的物件的屬性
*/
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
/**
* 初始化前執行的方法
*/
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String name)
throws BeansException;
/**
* 初始化後執行的方法
*/
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String name)
throws BeansException;
}
4.ListableBeanFactory:提供所有bean 例項的列舉,不再需要客戶端通過一個個bean name查詢.BeanFactory實現類預載入bean定義(如通過實現xml的工廠)需要實現這個介面.
public interface ListableBeanFactory extends BeanFactory {
/**
* 返回bean定義的數量
*/
int getBeanDefinitionCount();
/**
* 返回bean定義的名稱陣列
*/
String[] getBeanDefinitionNames();
/**
* 通過Class 返回bean定義名稱陣列
*/
String[] getBeanDefinitionNames(Class type);
/**
* 檢查時候存在改名稱的bean定義
*/
boolean containsBeanDefinition(String name);
/**
* 通過型別返回bean的例項
*/
Map getBeansOfType(Class type, boolean includePrototypes, boolean includeFactoryBeans)
throws BeansException;
}
5.ConfigurableBeanFactory :是工廠可以配置
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory {
/**
* 設定父級bean工廠
*/
void setParentBeanFactory(BeanFactory parentBeanFactory);
/**
* 註冊自定義屬性
*/
void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor);
/**
* 設定自動裝配忽略的Class
*/
void ignoreDependencyType(Class type);
/**
* 增強bean初始化前後的操作
*/
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
/**
* 通過名稱獲取bean的定義
*/
BeanDefinition getBeanDefinition(String beanName) throws BeansException;
/**
* 註冊bean的別名
*/
void registerAlias(String beanName, String alias) throws BeansException;
/**
* 註冊單例
*/
void registerSingleton(String beanName, Object singletonObject) throws BeansException;
/**
* 銷燬單例
*/
void destroySingletons();
}
6.ConfigurableListableBeanFactory: 集大成者,並增加預載入單例的方法
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, ConfigurableBeanFactory, AutowireCapableBeanFactory {
/**
* 預處理單例
*/
void preInstantiateSingletons();
}