spring源碼解讀-BeanFactory體系結(jié)構(gòu)

一.BeanFactory

BeanFactory是Spring IOC容器的鼻祖,是IOC容器的基礎(chǔ)接口,所有的容器都是從它這里繼承實現(xiàn)而來。可見其地位。BeanFactory提供了最基本的IOC容器的功能,即所有的容器至少需要實現(xiàn)的標(biāo)準(zhǔn)庆猫。

BeanFactory體系結(jié)構(gòu)是典型的工廠方法模式,即什么樣的工廠生產(chǎn)什么樣的產(chǎn)品。BeanFactory是最基本的抽象工廠猬错,而其他的IOC容器只不過是具體的工廠倦炒,對應(yīng)著各自的Bean定義方法逢唤。但同時魔慷,其他容器也針對具體場景不同,進(jìn)行了擴(kuò)充音念,提供具體的服務(wù)沪饺。

二.BeanFacory源碼

1.java doc

首先是Java doc,現(xiàn)在閱讀源碼的習(xí)慣是一定要理解了java doc的描述,因為這里是作者的描述讥脐,沒有人比作者更明白這個類遭居,這個接口要干什么啼器。

/** 
* The root interface for accessing a Spring bean container.
 * This is the basic client view of a bean container;
 * further interfaces such as {@link ListableBeanFactory} and
 * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
 * are available for specific purposes.
 *
 * <p>This interface is implemented by objects that hold a number of bean definitions,
 * each uniquely identified by a String name. Depending on the bean definition,
 * the factory will return either an independent instance of a contained object
 * (the Prototype design pattern), or a single shared instance (a superior
 * alternative to the Singleton design pattern, in which the instance is a
 * singleton in the scope of the factory). Which type of instance will be returned
 * depends on the bean factory configuration: the API is the same. Since Spring
 * 2.0, further scopes are available depending on the concrete application
 * context (e.g. "request" and "session" scopes in a web environment).
 *
 * <p>The point of this approach is that the BeanFactory is a central registry
 * of application components, and centralizes configuration of application
 * components (no more do individual objects need to read properties files,
 * for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and
 * Development" for a discussion of the benefits of this approach.
 *
 * <p>Note that it is generally better to rely on Dependency Injection
 * ("push" configuration) to configure application objects through setters
 * or constructors, rather than use any form of "pull" configuration like a
 * BeanFactory lookup. Spring's Dependency Injection functionality is
 * implemented using this BeanFactory interface and its subinterfaces.
 *
 * <p>Normally a BeanFactory will load bean definitions stored in a configuration
 * source (such as an XML document), and use the {@code org.springframework.beans}
 * package to configure the beans. However, an implementation could simply return
 * Java objects it creates as necessary directly in Java code. There are no
 * constraints on how the definitions could be stored: LDAP, RDBMS, XML,
 * properties file, etc. Implementations are encouraged to support references
 * amongst beans (Dependency Injection).
 *
 * <p>In contrast to the methods in {@link ListableBeanFactory}, all of the
 * operations in this interface will also check parent factories if this is a
 * {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance,
 * the immediate parent factory will be asked. Beans in this factory instance
 * are supposed to override beans of the same name in any parent factory.
 *
 * <p>Bean factory implementations should support the standard bean lifecycle interfaces
 * as far as possible. The full set of initialization methods and their standard order is:<br>
 * 1\. BeanNameAware's {@code setBeanName}<br>
 * 2\. BeanClassLoaderAware's {@code setBeanClassLoader}<br>
 * 3\. BeanFactoryAware's {@code setBeanFactory}<br>
 * 4\. ResourceLoaderAware's {@code setResourceLoader}
 * (only applicable when running in an application context)<br>
 * 5\. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
 * (only applicable when running in an application context)<br>
 * 6\. MessageSourceAware's {@code setMessageSource}
 * (only applicable when running in an application context)<br>
 * 7\. ApplicationContextAware's {@code setApplicationContext}
 * (only applicable when running in an application context)<br>
 * 8\. ServletContextAware's {@code setServletContext}
 * (only applicable when running in a web application context)<br>
 * 9\. {@code postProcessBeforeInitialization} methods of BeanPostProcessors<br>
 * 10\. InitializingBean's {@code afterPropertiesSet}<br>
 * 11\. a custom init-method definition<br>
 * 12\. {@code postProcessAfterInitialization} methods of BeanPostProcessors
 *
 * <p>On shutdown of a bean factory, the following lifecycle methods apply:<br>
 * 1\. DisposableBean's {@code destroy}<br>
 * 2\. a custom destroy-method definition

概括起來:
1.BeanFactory是Spring容器的Root Interface
2.BeanFactory的作用是持有一定數(shù)量的Bean Definition,每一個都有一個獨有的String名字俱萍。BeanFactory可以返回單例或多例的對象端壳,取決于Bean定義文件。

  1. 通過setters,constructors進(jìn)行依賴注入更好枪蘑,其實這也是常用的方法
  2. BeanFactory通過載入配置源文件(XML文件)的方式损谦,來配置Bean。
  3. 最后一大段是BeanFactory支持的bean生命周期的順序岳颇。但是其實BeanFactory是沒有給出抽象方法的照捡。

2.源碼

public interface BeanFactory { 
/** 
     * Used to dereference a {@link FactoryBean} instance and distinguish it from
     * beans <i>created</i> by the FactoryBean. For example, if the bean named
     * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
     * will return the factory, not the instance returned by the factory. */
    //使用轉(zhuǎn)義符&來得到FactoryBean本身,用來區(qū)分通過容器獲得FactoryBean本身和其產(chǎn)生的對象
    String FACTORY_BEAN_PREFIX = "&"; 
//這個方法是BeanFactory的主要方法话侧,通過這個方法栗精,可以取得IOC容器管理的Bean, //Bean的取得是通過指定名字索引獲取的
    Object getBean(String name) throws BeansException; 
//根據(jù)bean的名字和Class類型來得到bean實例掂摔,增加了類型安全驗證機制
    <T> T getBean(String name, Class<T> requiredType) throws BeansException; //通過Bean類型獲取bean實例
    <T> T getBean(Class<T> requiredType) throws BeansException; 
//增加更多獲取的條件术羔,同上方法
    Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; 
//判斷容器是否含有指定名字的bean
    boolean containsBean(String name); 
//查詢指定名字的Bean是不是單例的Bean
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
 //判斷Bean是不是prototype類型的bean
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException; 
//查詢指定了名字的Bean的Class類型是否與指定類型匹配
    boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
 //獲取指定名字bean的Class類型
    Class<?> getType(String name) throws NoSuchBeanDefinitionException; 
//查詢指定了名字的bean的所有別名,這些別名都是在BeanDefinition中定義的
 String[] getAliases(String name);

}

這些接口定義勾畫出了IOC容器的基本方法特性乙漓。

三. BeanFactory 結(jié)構(gòu)體系

BeanFactory作為最頂層的一個接口類级历,它定義了IOC容器的基本功能規(guī)范,BeanFactory 有三個子類接口:ListableBeanFactory叭披、HierarchicalBeanFactory 和AutowireCapableBeanFactory寥殖,還有一個實現(xiàn)類SimpleJndiBeanFactory。

所以接下來依次分析三個最有用的子接口涩蜘。

1.AutowireCapableBeanFactory 可自動裝配的Bean工廠

值得注意的是嚼贡,這個接口并沒有被ApplicationContext繼承!同诫!這個是《Spring 技術(shù)內(nèi)幕》書里寫錯的粤策。這個接口主要是管理ApplicationContext之外的Bean。

(1)java doc

/**
 * Extension of the {@link org.springframework.beans.factory.BeanFactory}
 * interface to be implemented by bean factories that are capable of
 * autowiring, provided that they want to expose this functionality for
 * existing bean instances.
 *
 * <p>This subinterface of BeanFactory is not meant to be used in normal
 * application code: stick to {@link org.springframework.beans.factory.BeanFactory}
 * or {@link org.springframework.beans.factory.ListableBeanFactory} for
 * typical use cases.

     Note that this interface is not implemented by
 * {@link org.springframework.context.ApplicationContext} facades,
 * as it is hardly ever used by application code误窖。 */

這個工廠接口繼承自BeanFacotory叮盘,它擴(kuò)展了自動裝配的功能,根據(jù)類定義BeanDefinition裝配Bean霹俺、執(zhí)行前柔吼、后處理器等。主要用它來管理ApplicationContext所不能管理的那些Bean丙唧,比如Filter愈魏,Servlet等。主要通過ApplicationContext的getAutowireCapableBeanFactory()獲得實例。

(2)源碼

/**
     * Constant that indicates no externally defined autowiring. Note that
     * BeanFactoryAware etc and annotation-driven injection will still be applied. 
*/
    int AUTOWIRE_NO = 0; 
/** * Constant that indicates autowiring bean properties by name
     * (applying to all bean property setters).
 */
    int AUTOWIRE_BY_NAME = 1;
 /** * Constant that indicates autowiring bean properties by type
     * (applying to all bean property setters). 
*/
    int AUTOWIRE_BY_TYPE = 2; 
/** * Constant that indicates autowiring the greediest constructor that
     * can be satisfied (involves resolving the appropriate constructor).
 */
    int AUTOWIRE_CONSTRUCTOR = 3;
 /**
     * Constant that indicates determining an appropriate autowire strategy
     * through introspection of the bean class. 
*/ @Deprecated int AUTOWIRE_AUTODETECT = 4; 
//------------------------------------------------------------------------- // 
Typical methods for creating and populating external bean instances 
//-------------------------------------------------------------------------

    /** 
     * Fully create a new bean instance of the given class.
     * <p>Performs full initialization of the bean, including all applicable
     * {@link BeanPostProcessor BeanPostProcessors}.
     * <p>Note: This is intended for creating a fresh instance, populating annotated
     * fields and methods as well as applying all standard bean initialiation callbacks.
     * It does <i>not</> imply traditional by-name or by-type autowiring of properties;
     * use {@link #createBean(Class, int, boolean)} for that purposes. 
*/
    //通過指定的class創(chuàng)建一個全新的Bean實例
    <T> T createBean(Class<T> beanClass) throws BeansException; 
/** 
    * Populate the given bean instance through applying after-instantiation callbacks
     * and bean property post-processing (e.g. for annotation-driven injection).
     * <p>Note: This is essentially intended for (re-)populating annotated fields and
     * methods, either for new instances or for deserialized instances. It does
     * <i>not</i> imply traditional by-name or by-type autowiring of properties;
     * use {@link #autowireBeanProperties} for that purposes. 
*/
    //給定對象培漏,根據(jù)注釋溪厘,后處理器進(jìn)行自動裝配
    void autowireBean(Object existingBean) throws BeansException; 
/** 
     * Configure the given raw bean: autowiring bean properties, applying
     * bean property values, applying factory callbacks such as {@code setBeanName}
     * and {@code setBeanFactory}, and also applying all bean post processors
     * (including ones which might wrap the given raw bean).
     * <p>This is effectively a superset of what {@link #initializeBean} provides,
     * fully applying the configuration specified by the corresponding bean definition.
     * <b>Note: This method requires a bean definition for the given name!</b> 
*/
    //自動裝配Bean的屬性,應(yīng)用處理器等
    Object configureBean(Object existingBean, String beanName) throws BeansException; /** * Resolve the specified dependency against the beans defined in this factory. */ Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException; 
//------------------------------------------------------------------------- // 
Specialized methods for fine-grained control over the bean lifecycle 
//-------------------------------------------------------------------------

    /** 
     * Fully create a new bean instance of the given class with the specified
     * autowire strategy. All constants defined in this interface are supported here.
     * <p>Performs full initialization of the bean, including all applicable
     * {@link BeanPostProcessor BeanPostProcessors}. This is effectively a superset
     * of what {@link #autowire} provides, adding {@link #initializeBean} behavior.
     * @see #AUTOWIRE_NO
     * @see #AUTOWIRE_BY_NAME
     * @see #AUTOWIRE_BY_TYPE
     * @see #AUTOWIRE_CONSTRUCTOR */根據(jù)給定的類型北苟,指定的裝配策略桩匪,創(chuàng)建新的Bean實例
    Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; /** * Instantiate a new bean instance of the given class with the specified autowire
     * strategy. All constants defined in this interface are supported here.
     * Can also be invoked with {@code AUTOWIRE_NO} in order to just apply
     * before-instantiation callbacks (e.g. for annotation-driven injection).
     * <p>Does <i>not</i> apply standard {@link BeanPostProcessor BeanPostProcessors}
     * callbacks or perform any further initialization of the bean. This interface
     * offers distinct, fine-grained operations for those purposes, for example
     * {@link #initializeBean}. However, {@link InstantiationAwareBeanPostProcessor}
     * callbacks are applied, if applicable to the construction of the instance.
     * @param beanClass the class of the bean to instantiate
     * @param autowireMode by name or type, using the constants in this interface
     * @param dependencyCheck whether to perform a dependency check for object
     * references in the bean instance (not applicable to autowiring a constructor,
     * thus ignored there)
     * @return the new bean instance
     * @throws BeansException if instantiation or wiring failed
     * @see #AUTOWIRE_NO
     * @see #AUTOWIRE_BY_NAME
     * @see #AUTOWIRE_BY_TYPE
     * @see #AUTOWIRE_CONSTRUCTOR
     * @see #AUTOWIRE_AUTODETECT
     * @see #initializeBean
     * @see #applyBeanPostProcessorsBeforeInitialization
     * @see #applyBeanPostProcessorsAfterInitialization */
    //根據(jù)給定的策略,類型友鼻,裝配Bean屬性
    Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; /** * Autowire the bean properties of the given bean instance by name or type.
     * Can also be invoked with {@code AUTOWIRE_NO} in order to just apply
     * after-instantiation callbacks (e.g. for annotation-driven injection).
     * <p>Does <i>not</i> apply standard {@link BeanPostProcessor BeanPostProcessors}
     * callbacks or perform any further initialization of the bean. This interface
     * offers distinct, fine-grained operations for those purposes, for example
     * {@link #initializeBean}. However, {@link InstantiationAwareBeanPostProcessor}
     * callbacks are applied, if applicable to the configuration of the instance.
     * @param existingBean the existing bean instance
     * @param autowireMode by name or type, using the constants in this interface
     * @param dependencyCheck whether to perform a dependency check for object
     * references in the bean instance
     * @throws BeansException if wiring failed
     * @see #AUTOWIRE_BY_NAME
     * @see #AUTOWIRE_BY_TYPE
     * @see #AUTOWIRE_NO */
    void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException; /** * Apply the property values of the bean definition with the given name to
     * the given bean instance. The bean definition can either define a fully
     * self-contained bean, reusing its property values, or just property values
     * meant to be used for existing bean instances.
     * <p>This method does <i>not</i> autowire bean properties; it just applies
     * explicitly defined property values. Use the {@link #autowireBeanProperties}
     * method to autowire an existing bean instance.
     * <b>Note: This method requires a bean definition for the given name!</b>
     * <p>Does <i>not</i> apply standard {@link BeanPostProcessor BeanPostProcessors}
     * callbacks or perform any further initialization of the bean. This interface
     * offers distinct, fine-grained operations for those purposes, for example
     * {@link #initializeBean}. However, {@link InstantiationAwareBeanPostProcessor}
     * callbacks are applied, if applicable to the configuration of the instance.
     * @param existingBean the existing bean instance
     * @param beanName the name of the bean definition in the bean factory
     * (a bean definition of that name has to be available)
     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
     * if there is no bean definition with the given name
     * @throws BeansException if applying the property values failed
     * @see #autowireBeanProperties */
    void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException; /** * Initialize the given raw bean, applying factory callbacks
     * such as {@code setBeanName} and {@code setBeanFactory},
     * also applying all bean post processors (including ones which
     * might wrap the given raw bean).
     * <p>Note that no bean definition of the given name has to exist
     * in the bean factory. The passed-in bean name will simply be used
     * for callbacks but not checked against the registered bean definitions.
     * @param existingBean the existing bean instance
     * @param beanName the name of the bean, to be passed to it if necessary
     * (only passed to {@link BeanPostProcessor BeanPostProcessors})
     * @return the bean instance to use, either the original or a wrapped one
     * @throws BeansException if the initialization failed */ Object initializeBean(Object existingBean, String beanName) throws BeansException; /** * Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean
     * instance, invoking their {@code postProcessBeforeInitialization} methods.
     * The returned bean instance may be a wrapper around the original.
     * @param existingBean the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one
     * @throws BeansException if any post-processing failed
     * @see BeanPostProcessor#postProcessBeforeInitialization */ Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException; /** * Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean
     * instance, invoking their {@code postProcessAfterInitialization} methods.
     * The returned bean instance may be a wrapper around the original.
     * @param existingBean the new bean instance
     * @param beanName the name of the bean
     * @return the bean instance to use, either the original or a wrapped one
     * @throws BeansException if any post-processing failed
     * @see BeanPostProcessor#postProcessAfterInitialization */ Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException; /** * Destroy the given bean instance (typically coming from {@link #createBean}),
     * applying the {@link org.springframework.beans.factory.DisposableBean} contract as well as
     * registered {@link DestructionAwareBeanPostProcessor DestructionAwareBeanPostProcessors}.
     * <p>Any exception that arises during destruction should be caught
     * and logged instead of propagated to the caller of this method.
     * @param existingBean the bean instance to destroy */
    void destroyBean(Object existingBean); /** * Resolve the specified dependency against the beans defined in this factory.
     * @param descriptor the descriptor for the dependency
     * @param beanName the name of the bean which declares the present dependency
     * @param autowiredBeanNames a Set that all names of autowired beans (used for
     * resolving the present dependency) are supposed to be added to
     * @param typeConverter the TypeConverter to use for populating arrays and
     * collections
     * @return the resolved object, or {@code null} if none found
     * @throws BeansException in dependency resolution failed */ Object resolveDependency(DependencyDescriptor descriptor, String beanName,
            Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;

}      

1.首先幾個屬性傻昙,是裝配策略

AUTOWIRE_BY_NAME ,把與Bean的屬性具有相同的名字的其他Bean自動裝配到這個屬性上。舉個栗子就是:當(dāng)有一個屬性名字為person時彩扔,則自動裝配策略選擇id為person的Bean進(jìn)行裝配妆档。

AUTOWIRE_BY_TYPE,把與Bean的屬性具有相同的類型的其他Bean自動裝配到這個屬性虫碉。

AUTOWIRE_BY_CONSTRUCT贾惦,把與bean的構(gòu)造器入?yún)⒕哂邢嗤愋偷钠渌鸅ean自動裝配到Bean構(gòu)造器的對應(yīng)參數(shù)中。

2.重點關(guān)注兩類方法

Typical methods for creating and populating external bean instances敦捧,該類是用來根據(jù)典型方法默認(rèn)創(chuàng)建Bean和裝配Bean的方法须板。

Specialized methods for fine-grained control over the bean lifecycle,該類是用來根據(jù)裝配策略細(xì)化裝配兢卵,具體控制Bean生命周期的方法习瑰。

(3)繼承體系

要注意看這個實現(xiàn)類DefaultListableBeanFactory,它的出鏡率十分高秽荤。還有ConfigureableListableBeanFactory甜奄,是他的直接子接口,實際上ConfigureableListableBeanFactory都間接或直接實現(xiàn)了這三個二級子接口。

2.HierarchicalBeanFactory 可分層次Bean工廠

(1)java doc

/** 
 * Sub-interface implemented by bean factories that can be part
 * of a hierarchy.
 *
 * <p>The corresponding {@code setParentBeanFactory} method for bean
 * factories that allow setting the parent in a configurable
 * fashion can be found in the ConfigurableBeanFactory interface.

層次Bean工廠窃款,從這個接口開始课兄,BeanFactory有了雙親Factory,父Factory的概念晨继。

(2)源碼

public interface HierarchicalBeanFactory extends BeanFactory { 
/** 
* Return the parent bean factory, or {@code null} if there is none. */ BeanFactory getParentBeanFactory(); 
/** 
     * Return whether the local bean factory contains a bean of the given name,
     * ignoring beans defined in ancestor contexts.
     * <p>This is an alternative to {@code containsBean}, ignoring a bean
     * of the given name from an ancestor bean factory.
     * @param name the name of the bean to query
     * @return whether a bean with the given name is defined in the local factory
     * @see BeanFactory#containsBean */
    boolean containsLocalBean(String name);

}

這個接口只是擴(kuò)展了兩個方法烟阐,一個是可以獲取父工廠,返回值也是BeanFactory紊扬。

另外一個方法是判斷當(dāng)前Factory是否包含給定名字的Bean曲饱,要注意的是這里只是判斷當(dāng)前工廠容器,而不管父輩珠月,祖輩工廠。這也是分層思想的體現(xiàn)楔敌。

分層繼承啤挎,從此開始。

(3)繼承體系

好吧,這里又出現(xiàn)DefaultListableBeanFactory了庆聘。

直接子接口共有兩個胜臊,一個是ApplicationContext,還有一個是ConfigurableBeanFactory伙判。

3.ListableBeanFactory 可將Bean逐一列出的Bean工廠

(1)java doc

/**  
 * Extension of the {@link BeanFactory} interface to be implemented by bean factories
 * that can enumerate all their bean instances, rather than attempting bean lookup
 * by name one by one as requested by clients. BeanFactory implementations that
 * preload all their bean definitions (such as XML-based factories) may implement
 * this interface.
 *
 * <p>If this is a {@link HierarchicalBeanFactory}, the return values will <i>not</i>
 * take any BeanFactory hierarchy into account, but will relate only to the beans
 * defined in the current factory. Use the {@link BeanFactoryUtils} helper class
 * to consider beans in ancestor factories too.
 *
 * <p>The methods in this interface will just respect bean definitions of this factory.
 * They will ignore any singleton beans that have been registered by other means like
 * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}'s
 * {@code registerSingleton} method, with the exception of
 * {@code getBeanNamesOfType} and {@code getBeansOfType} which will check
 * such manually registered singletons too. Of course, BeanFactory's {@code getBean}
 * does allow transparent access to such special beans as well. However, in typical
 * scenarios, all beans will be defined by external bean definitions anyway, so most
 * applications don't need to worry about this differentiation.
 *
 * <p><b>NOTE:</b> With the exception of {@code getBeanDefinitionCount}
 * and {@code containsBeanDefinition}, the methods in this interface
 * are not designed for frequent invocation. Implementations may be slow. */

總結(jié)一下:

1.從這個工廠接口開始象对,可以枚舉列出工廠可以生產(chǎn)的所有實例。

2. 而且如果是一個層次繼承的工廠宴抚,則只會列出當(dāng)前工廠的實例勒魔,而不會列出祖先層的實例。

(2)源碼

public interface ListableBeanFactory extends BeanFactory { 
/** 
     * Check if this bean factory contains a bean definition with the given name.
     * <p>Does not consider any hierarchy this factory may participate in,
     * and ignores any singleton beans that have been registered by
     * other means than bean definitions. */
    // 對于給定的名字是否含有BeanDefinition
    boolean containsBeanDefinition(String beanName); /** * Return the number of beans defined in the factory.
     * <p>Does not consider any hierarchy this factory may participate in,
     * and ignores any singleton beans that have been registered by
     * other means than bean definitions. */
    // 返回工廠的BeanDefinition總數(shù)
    int getBeanDefinitionCount(); /** * Return the names of all beans defined in this factory.
     * <p>Does not consider any hierarchy this factory may participate in,
     * and ignores any singleton beans that have been registered by
     * other means than bean definitions.
     * @return the names of all beans defined in this factory,
     * or an empty array if none defined */
    // 返回工廠中所有BeanDefineition的名字
 String[] getBeanDefinitionNames(); /** * Return the names of beans matching the given type (including subclasses),
     * judging from either bean definitions or the value of {@code getObjectType}
     * in the case of FactoryBeans.
     * <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
     * check nested beans which might match the specified type as well.
     * <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
     * will get initialized. If the object created by the FactoryBean doesn't match,
     * the raw FactoryBean itself will be matched against the type.
     * <p>Does not consider any hierarchy this factory may participate in.
     * Use BeanFactoryUtils' {@code beanNamesForTypeIncludingAncestors}
     * to include beans in ancestor factories too.
     * <p>Note: Does <i>not</i> ignore singleton beans that have been registered
     * by other means than bean definitions.
     * <p>This version of {@code getBeanNamesForType} matches all kinds of beans,
     * be it singletons, prototypes, or FactoryBeans. In most implementations, the
     * result will be the same as for {@code getBeanNamesForType(type, true, true)}.
     * <p>Bean names returned by this method should always return bean names <i>in the
     * order of definition</i> in the backend configuration, as far as possible.
     * @param type the class or interface to match, or {@code null} for all bean names
     * @return the names of beans (or objects created by FactoryBeans) matching
     * the given object type (including subclasses), or an empty array if none
     * @see FactoryBean#getObjectType
     * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class) */
    //根據(jù)類型來返回Bean名稱菇曲,包含該層的所有Bean冠绢,包括FactoryBean
    String[] getBeanNamesForType(Class<?> type); /* * 返回指定類型的名字 includeNonSingletons為false表示只取單例Bean,true則不是
         * allowEagerInit為true表示立刻加載常潮,false表示延遲加載弟胀。 注意:FactoryBeans都是立刻加    載的。 */ String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit); //返回對應(yīng)類型的Bean實例喊式,鍵為Bean 名稱
    <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException; /** * Find all names of beans whose {@code Class} has the supplied {@link Annotation}
     * type, without creating any bean instances yet.
     * @param annotationType the type of annotation to look for
     * @return the names of all matching beans
     * @since 4.0 */
    //根據(jù)注解類型返回對應(yīng)的Bean名稱
    String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType); //根據(jù)注解返回對應(yīng)Bean 名稱孵户,Bean實例Map
    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException; /** * Find an {@link Annotation} of {@code annotationType} on the specified
     * bean, traversing its interfaces and super classes if no annotation can be
     * found on the given class itself. */
    //查找對應(yīng)Bean名稱,對應(yīng)注解類型的注解
    <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) throws NoSuchBeanDefinitionException;

} 

總結(jié):

這個Bean接口總體來看是返回一組Bean名稱岔留,或者一組Bean名稱夏哭,Bean實例的Map。同時還涉及到了返回BeanDefinition的方法贸诚。

值得注意的是BeanDefinition從這里登場了開始方庭。

(3)繼承體系

又一次看到了DefaultListableBeanFactory接口。

四.整體體系結(jié)構(gòu)

是時候看看整體圖了酱固,我當(dāng)時是直接從《Spring 技術(shù)內(nèi)幕》中看到這個圖的械念,當(dāng)時就蒙圈了。現(xiàn)在整體走一遍再看运悲,可能就好一些了龄减。

可以看到的是DefaultListBeanFactory參考

具體:

1、BeanFactory作為一個主接口不繼承任何接口班眯,暫且稱為一級接口希停。

2、有3個子接口繼承了它署隘,進(jìn)行功能上的增強宠能。這3個子接口稱為二級接口

3磁餐、ConfigurableBeanFactory可以被稱為三級接口违崇,對二級接口HierarchicalBeanFactory進(jìn)行了再次增強,它還繼承了另一個外來的接口SingletonBeanRegistry

4、ConfigurableListableBeanFactory是一個更強大的接口羞延,繼承了上述的所有接口渣淳,無所不包,稱為四級接口伴箩。

(這4級接口是BeanFactory的基本接口體系入愧。繼續(xù),下面是繼承關(guān)系的2個抽象類和2個實現(xiàn)類:)

5嗤谚、AbstractBeanFactory作為一個抽象類棺蛛,實現(xiàn)了三級接口ConfigurableBeanFactory大部分功能。

6呵恢、AbstractAutowireCapableBeanFactory同樣是抽象類鞠值,繼承自AbstractBeanFactory,并額外實現(xiàn)了二級接口AutowireCapableBeanFactory

7渗钉、DefaultListableBeanFactory繼承自AbstractAutowireCapableBeanFactory彤恶,實現(xiàn)了最強大的四級接口ConfigurableListableBeanFactory,并實現(xiàn)了一個外來接口 BeanDefinitionRegistry鳄橘,它并非抽象類声离。

8、最后是最強大的XmlBeanFactory瘫怜,繼承自DefaultListableBeanFactory术徊,重寫了一些功能,使自己更強大鲸湃。提供了Xml文件相關(guān)BeanFactory的方法赠涮。可以讀取xml定義的BeanDefinition文件暗挑。

總結(jié):XmlBeanFactory笋除,只是提供了最基本的IOC容器的功能。而且XMLBeanFactory,繼承自DefaultListableBeanFactory炸裆。DefaultListableBeanFactory實際包含了基本IOC容器所具有的所有重要功能垃它,是一個完整的IOC容器。

參考資料:
1.Spring:源碼解讀Spring IOC原理
2.Spring源碼分析——BeanFactory體系之接口詳細(xì)分析

  1. spring IOC源碼分析(1)
  2. 《Spring 技術(shù)內(nèi)幕》強烈推薦

原文:https://www.cnblogs.com/ToBeAProgrammer/p/5192837.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烹看,一起剝皮案震驚了整個濱河市国拇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惯殊,老刑警劉巖酱吝,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異土思,居然都是意外死亡务热,警方通過查閱死者的電腦和手機毕源,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來陕习,“玉大人,你說我怎么就攤上這事址愿「昧停” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵响谓,是天一觀的道長损合。 經(jīng)常有香客問我,道長娘纷,這世上最難降的妖魔是什么嫁审? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮赖晶,結(jié)果婚禮上律适,老公的妹妹穿的比我還像新娘。我一直安慰自己遏插,他們只是感情好捂贿,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胳嘲,像睡著了一般厂僧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上了牛,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天颜屠,我揣著相機與錄音,去河邊找鬼鹰祸。 笑死甫窟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的福荸。 我是一名探鬼主播蕴坪,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼敬锐!你這毒婦竟也來了背传?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤台夺,失蹤者是張志新(化名)和其女友劉穎径玖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颤介,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡梳星,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年赞赖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冤灾。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡前域,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出韵吨,到底是詐尸還是另有隱情匿垄,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布归粉,位于F島的核電站椿疗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏糠悼。R本人自食惡果不足惜届榄,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倔喂。 院中可真熱鬧铝条,春花似錦、人聲如沸滴劲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽班挖。三九已至鲁捏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間萧芙,已是汗流浹背给梅。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留双揪,地道東北人动羽。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像渔期,于是被迫代替她去往敵國和親运吓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355