2.Spring源碼之路-DefaulListableBeanFactory - BeanFactory

Spring源碼之路-DefaulListableBeanFactory

BeanFactory接口總結

  1. BeanFactory還是一個工廠,類似於工廠設計模式中的Factory,主要
    還是創建Bean,由實現者來決定如何創建
  2. FactoryBean還是一個Bean,通過FactoryBean的名稱只能獲取到由
    FactoryBean創建的對象,如果想獲取到FactoryBean需要在名字前面
    加一個 &
  3. BeanFactory的接口歸類如下:
    • 獲取Bean實例的方法
      • Object getBean(String name)
      • T getBean(String name, Class requiredType)
      • Object getBean(String name, Object… args)
      • T getBean(Class requiredType)
      • T getBean(Class requiredType, Object… args)
    • 獲取Bean的Provider(具體什麼時候會被實例化,由調用方掌控)
      • ObjectProvider getBeanProvider(Class requiredType)
      • ObjectProvider getBeanProvider(ResolvableType requiredType)
    • 會導致Bean初始化的檢查方法
      • boolean containsBean(String name)
      • boolean isTypeMatch(String name, ResolvableType typeToMatch)
      • boolean isTypeMatch(String name, Class<?> typeToMatch)
      • Class<?> getType(String name)
      • Class<?> getType(String name, boolean allowFactoryBeanInit)
    • 不會導致Bean初始化的檢查方法
      • boolean isSingleton(String name)
      • boolean isPrototype(String name)
      • String[] getAliases(String name);

源碼註釋的大概翻譯

/**
 * 此接口由包含多個bean定義的對象實現,每個定義均由String名稱唯一標識。根
 * 據bean的定義,工廠將返回一個所包含對象的獨立實例,可能是原型實例的Bean,
 * 也可能是單例實例的Bean,至於返回哪種實例的Bean,取決於Bean的配置。
 * 
 * 這種方法的重點是BeanFactory是應用程序組件的中央註冊表並集中了應用程序
 * 組件的配置(例如,不再需要單個對象讀取屬性文件)
 * 有關此方法的好處的討論,請參見“Expert One-on-One J2EE Design and
 * Development”的第4章和第11章。 
 * 
 * 請注意,通常最好依賴於依賴注入(“push”配置)通過設置器或構造函數配置應
 * 用程序對象,而不是使用任何形式的“pull”配置(例如BeanFactory查找)。
 * 使用此BeanFactory接口及其子接口可以實現Spring的依賴注入功能。
 * 
 * 通常,BeanFactory將加載存儲在配置源(例如XML文檔)中的bean定義,並使
 * 用{@code org.springframework.beans} 包來配置bean。但是,實現可以根據需
 * 要直接在Java代碼中直接返回創建的Java對象。定義的存儲方式沒有任何限制:
 * LDAP,RDBMS,XML,屬性文件等。鼓勵實現在bean之間支持引用(依賴注
 * 入)。 
 * 與{@link ListableBeanFactory}中的方法相反,此接口中的所有操作還將檢查父
 * 工廠,如果這是一個{@link HierarchicalBeanFactory}。如果在此工廠實例中未
 * 找到bean,則將詢問直接的父工廠。該工廠實例中的Bean應該覆蓋任何父工廠
 * 中同名的Bean。 
 * Bean工廠實現應儘可能支持標準Bean生命週期接口。全套初始化方法及其標
 * 準順序爲:
 * 僅在應用程序上下文中運行時起作用
 * BeanNameAware的{@code setBeanName} 
 * BeanClassLoaderAware的{@code setBeanClassLoader} 
 * BeanFactoryAware的{@code setBeanFactory} 
 * EnvironmentAware的{@code setEnvironment} 
 * EmbeddedValueResolverAware的{@code setEmbeddedValueResolver} 
 * ResourceLoaderAware的{@code setResourceLoader} 
 * ApplicationEventPublisherAware的{@code setApplicationEventPublisher} 
 * MessageSourceAware的{@code setMessageSource} 
 * ApplicationContextAware的{@code setApplicationContext} 
 * 
 * 僅適用於在Web應用程序上下文中運行
 * ServletContextAware的{@code setServletContext} 
 * 
 * 僅對Bean進行實例化的時候會觸發的接口
 * BeanPostProcessors的 {@ code postProcessBeforeInitialization}
 * InitializingBean的{@code afterPropertiesSet} 
 * 自定義的初始化方法
 * BeanPostProcessors的 {@ code postProcessAfterInitialization}
 * 
 * 在關閉bean工廠時,適用以下生命週期方法:
 * DestructionAwareBeanPostProcessor的{@ code postProcessBeforeDestruction}
 * DisposableBean的{@code destroy}
 * 自定義的銷燬方法
 */
public interface BeanFactory {

	/**
	* 用於引用{@link FactoryBean}實例,並將其與由FactoryBean創建的bean區別開來。
	* 例如,如果名爲{@code myJndiObject}的bean是FactoryBean,則獲取
	* {@code&myJndiObject} 將返回工廠,而不是工廠返回的實例。 
	 */
	String FACTORY_BEAN_PREFIX = "&";


	/**
	 * 返回一個實例,該實例可以是指定bean的共享或獨立的。
	 * 此方法允許使用Spring BeanFactory替代Singleton或Prototype設計模式。
	 * 對於Singleton Bean,調用者可以保留對返回對象的引用。 
	 * 
	 * 將別名轉換回相應的規範bean名稱。 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * 
	 * @param 要檢索的bean的名稱
	 * @return bean的實例
	 * @throws NoSuchBeanDefinitionException如果沒有指定名稱的bean 
	 * @throws BeansException如果無法獲得bean 
	 */
	Object getBean(String name) throws BeansException;

	/**
	 * 返回一個實例,該實例可以是指定bean的共享或獨立的。 
	 * 與{@link #getBean(String)}的行爲相同,但是如果Bean不是requiredType類型,
	 * 則拋出BeanNotOfRequiredTypeException來提供類型安全性的度量
	 * 這意味着無法正確映射結果
	 * 如{@link #getBean(String)}可能會拋出ClassCastException。
	 * 
	 * 將別名轉換回相應的規範bean名稱。 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * 
	 * @param name 要檢索的bean的名稱
	 * @param requiredType bean必須匹配的類型;可以是接口或超類
	 * @return bean的實例
	 * @throws NoSuchBeanDefinitionException 如果沒有這樣的bean定義
	 * @throws BeanNotOfRequiredTypeException 如果bean不是requiredType類型
	 * @throws BeansException如果不能創建bean 
	 */
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	/**
	 * 返回一個實例,該實例可以是指定bean的共享或獨立的。
	 * 允許指定顯式構造函數參數/工廠方法參數,如果有參數的話覆蓋Bean定義中
	 * 指定的默認參數。
	 * @param name 要檢索的bean的名稱
	 * @param args 使用顯式參數創建bean實例時使用的args參數
	 * (僅在創建新實例而不是檢索現有實例時才應用)
	 * @return bean的實例
	 * @throws NoSuchBeanDefinitionException 如果沒有這樣的bean定義
	 * @throws BeanDefinitionStoreException 如果已給出參數但受影響的bean不是prototype
	 * @throws BeansException 如果無法創建bean
	 * @since 2.5
	 */
	Object getBean(String name, Object... args) throws BeansException;

	/**
	 * 如果有的話,返回與給定對象類型唯一匹配的bean實例
	 * 
	 * 此方法進入{@link ListableBeanFactory}按類型查找區域但也可以根據給定類型的名稱,
	 * 轉換爲常規的按名稱查找 對於檢索bean的更廣泛的操作,
	 * 請使用{@link ListableBeanFactory} 或{@link BeanFactoryUtils}。 
	 * @param bean必須匹配的類型;可以是接口或超類
	 * @return 與所需類型匹配的單個bean的實例
	 * @throws NoSuchBeanDefinitionException 如果沒有找到給定類型的bean 
	 * @throws NoUniqueBeanDefinitionException 如果找到了給定類型的多個bean 
	 * @throws BeansException 如果無法創建bean
	 * @since 3.0
	 * @see ListableBeanFactory
	 */
	<T> T getBean(Class<T> requiredType) throws BeansException;

	/**
	 * 返回一個實例,該實例可以是指定bean的共享或獨立的。 
	 * 允許指定顯式構造函數參數/工廠方法參數,如果有的話,覆蓋Bean定義中指定的默認
	 * 參數
	 * 
	 * 此方法進入{@link ListableBeanFactory}按類型查找區域但也可以根據給定類型的名稱,
	 * 轉換爲常規的按名稱查找 對於檢索bean的更廣泛的操作,
	 * 請使用{@link ListableBeanFactory} 或{@link BeanFactoryUtils}。 
	 * @param requiredType bean必須匹配的類型;可以是接口或超類
	 * @param args 使用顯式參數創建bean實例時使用的參數
	 * (僅在創建新實例而不是檢索現有實例時才應用)
	 * @return bean的實例
	 * @throws NoSuchBeanDefinitionException 如果沒有這樣的bean定義
	 * @throws BeanDefinitionStoreException 如果給出了參數,但是受影響的bean不是prototype
	 * @throws BeansException 如果無法創建bean 
	 * @since 4.1
	 */
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

	/**
	 * 返回指定bean的提供程序,允許對實例進行延遲的按需檢索,包括可用性和唯一性選項。
	 * @param bean必須匹配的類型;可以是接口或超類
	 * @return 相應的提供程序句柄
	 * @since 5.1
	 * @see #getBeanProvider(ResolvableType)
	 */
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	/**
	 * 返回指定bean的提供程序,允許對實例進行延遲的按需檢索,包括可用性和唯一性選項。
	 * @param requiredType bean必須匹配的類型;可以是通用類型聲明。 
	 * 請注意,與反射注入點相比,此處不支持收集類型。要以編程方式檢索與特定類型匹配的
	 * bean列表,請在此處指定實際bean類型作爲參數,然後使用
	 * {@link ObjectProvider#orderedStream()}或它的延遲流/迭代選項。 
	 * @return 相應的提供程序句柄
	 * @since 5.1
	 * @see ObjectProvider#iterator()
	 * @see ObjectProvider#stream()
	 * @see ObjectProvider#orderedStream()
	 */
	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

	/**
	 * 此bean工廠是否包含具有給定名稱的bean定義或外部註冊的singleton實例
	 * 如果給定名稱是別名,它將被轉換回相應的規範bean名稱。
	 * 
	 * 如果該工廠是分層工廠,如果在該工廠實例中找不到bean,將詢問任何父工廠。
	 * 如果找到與給定名稱匹配的beanDefinition或單例實例,則無論命名的bean定義
	 * 是具體的還是抽象的,惰性加載的或直接加載的,此方法都將返回{@code true}。
	 * 因此,請注意,此方法的{@code true}返回值不一定表示{@link #getBean} 將能
	 * 夠獲得具有相同名稱的實例。 
	 * @param name 要查詢的bean的名稱
	 * @return 是否存在具有給定名稱的bean 
	 */
	boolean containsBean(String name);

	/**
	 * 這個bean是共享單身嗎?也就是說,{@ link #getBean}是否總是返回相同的實例? 
	 * 注意:此返回{@code false}的方法不能清楚地表明獨立實例。
	 * 它表示非單個實例,也可能對應於作用域bean。使用{@link #isPrototype}操作來
	 * 顯式檢查獨立實例。
	 * 
	 * 將別名轉換回相應的規範bean名稱。 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * @param name 要查詢的bean的名稱
	 * @return 此bean是否對應於一個單例實例
	 * @throws NoSuchBeanDefinitionException 如果沒有給定名稱的bean
	 * @see #getBean
	 * @see #isPrototype
	 */
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	/**
	 * 這個bean是原型嗎?也就是說,{@ link #getBean}將始終返回獨立實例嗎? 
	 * 注意:此返回{@code false}的方法不能清楚地表明*一個單例對象。它指示
	 * 非獨立實例,也可能對應於*作用域bean。使用{@link #isSingleton}操作來
	 * 顯式檢查共享的單例實例。 
	 * 
	 * 將別名轉換回相應的規範bean名稱。 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * @param name 要查詢的bean的名稱
	 * @return 此bean是否將始終提供獨立的實例
	 * @throws NoSuchBeanDefinitionException 如果沒有給定名稱的bean 
	 * @since 2.0.3
	 * @see #getBean
	 * @see #isSingleton
	 */
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	/**
	 * 檢查具有給定名稱的bean是否與指定的類型匹配。 更具體地說,檢查對給
	 * 定名稱的{@link #getBean}調用是否會返回可分配給指定目標類型的對象。
	 * 
	 * 將別名轉換回相應的規範bean名稱。 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * @param 要查詢的bean的名稱
	 * @param typeToMatch 要匹配的類型(作爲{@code ResolvableType})
	 * @return 如果bean類型匹配{@code true},如果它不匹配或尚未確定{@code false}
	 * @throws NoSuchBeanDefinitionException 如果沒有給定名稱的bean
	 * @since 4.2
	 * @see #getBean
	 * @see #getType
	 */
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	/**
	 * 檢查具有給定名稱的bean是否與指定的類型匹配。更具體地說,檢查對給定
	 * 名稱的{@link #getBean}調用是否會返回可分配給指定目標類型的對象。 
	 * 
	 * 將別名轉換回相應的規範bean名稱。 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * @param name 要查詢的bean的名稱
	 * @param typeToMatch 要匹配的類型(as a {@code Class})
	 * @return 如果bean類型匹配{@code true},如果它不匹配或尚不能確定{@code false}
	 * {@code false} if it doesn't match or cannot be determined yet
	 * @throws NoSuchBeanDefinitionException 如果沒有給定名稱的bean 
	 * @since 2.0.1
	 * @see #getBean
	 * @see #getType
	 */
	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	/**
	 * 確定具有給定名稱的bean的類型。更具體地說,
	 * 確定給定名稱的{@link #getBean}返回的對象的類型。 
	 * 對於{@link FactoryBean},返回由{@link FactoryBean#getObjectType()}
	 * 公開的FactoryBean創建的對象的類型。這可能導致先前未初始化的
	 * {@code FactoryBean}的初始化(請參閱{@link #getType(String,boolean)})。 
	 * 
	 * 將別名轉換回相應的規範bean名稱。 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * @param 要查詢的bean的名稱
	 * @return bean的類型,如果不確定,則返回{@code null} 
	 * @throws NoSuchBeanDefinitionException 如果沒有給定名稱的bean
	 * @since 1.1.2
	 * @see #getBean
	 * @see #isTypeMatch
	 */
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	/**
	 * 確定具有給定名稱的bean的類型。更具體地說,
	 * 確定給定名稱的{@link #getBean}返回的對象的類型。 
	 * 對於{@link FactoryBean},返回由{@link FactoryBean#getObjectType()}
	 * 公開的FactoryBean創建的對象的類型。如果沒有早期類型信息,則取決於
	 * {@code allowFactoryBeanInit}標誌,這可能導致先前未初始化的
	 * {@code FactoryBean}的初始化。 
	 * 
	 * 將別名轉換回相應的規範bean名稱。 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * @param name 要查詢的bean的名稱
	 * @param allowFactoryBeanInit 是否可以初始化{@code FactoryBean} 僅用於確定其對象類型
	 * just for the purpose of determining its object type
	 * @return 如果不是可確定的{@code null},否則返回bean的類型
	 * @throws NoSuchBeanDefinitionException 如果沒有給定名稱的bean 
	 * @since 5.2
	 * @see #getBean
	 * @see #isTypeMatch
	 */
	@Nullable
	Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

	/**
	 * 如果有別名,返回給定bean名稱的別名
	 * 在{@link #getBean}調用中使用時,所有這些別名都指向同一個bean。 
	 * 如果給定名稱是別名,則將返回相應的原始bean名稱和其他別名,原始bean名稱
	 * 是數組中的第一個元素。 
	 * 
	 * 將詢問父工廠是否在該工廠實例中找不到該bean。 
	 * @param name 要檢查別名的bean名稱
	 * @return 如果沒有別名則返回一個空數組,如果有返回別名
	 * @see #getBean
	 */
	String[] getAliases(String name);

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章