1. 程式人生 > >白話Spring原始碼(四):BeanFactory

白話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();

}