Spring源碼之路-DefaulListableBeanFactory
BeanFactory接口總結
- BeanFactory還是一個工廠,類似於工廠設計模式中的Factory,主要
還是創建Bean,由實現者來決定如何創建
- FactoryBean還是一個Bean,通過FactoryBean的名稱只能獲取到由
FactoryBean創建的對象,如果想獲取到FactoryBean需要在名字前面
加一個 &
- 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);
}