spring源碼--IOC容器的實現:概述

#引言
spring做爲java程序員必學的框架,從學校的課堂上,到實際工作中,都可以看到它的身影。之前看過一篇文章,說對於spring的源碼只需要瞭解架構,不需要關注具體的實現,不敢苟同。如果對於java程序員最重要的框架都不關注具體實現,那麼還有什麼代碼值得去關注呢?有人說spring讓java程序員喪失了程序設計的能力,只需要關注service,dao這些東西,那麼它給我們提供這些便利的背後到底做了什麼工作,如果能窺之一二,想想還有點小興奮呢。爲了突出主題,就不介紹spring那些相關的概念了,看到spring,就提概念,真的很煩。QAQ
#整體介紹
spring的IOC容器可以簡單的看做一個map,當然實際要複雜的多。看做map有助於幫助我們理解spring的相關接口定義,spring中最重要的一個接口BeanFactory,BeanFactory定義了spring容器最基本也是最重要的能力。這麼重要當然的分析一下。
順便說一下,這裏spring的版本是4.3.15.RELEASE,最新的spring版本已經到5.+了,但是重要的部分變化不大。

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.
	 * 
	 * 如果通過通過名稱去獲取bean,如果名稱以開頭&將獲取到FactoryBean本身而不是FactoryBean生產出的bean
	 * 順便提一句,FactoryBean是spring的一個接口,可以通過實現FactoryBean來註冊實例
	 */
	String FACTORY_BEAN_PREFIX = "&";


	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * <p>This method allows a Spring BeanFactory to be used as a replacement for the
	 * Singleton or Prototype design pattern. Callers may retain references to
	 * returned objects in the case of Singleton beans.
	 * <p>Translates aliases back to the corresponding canonical bean name.
	 * Will ask the parent factory if the bean cannot be found in this factory instance.
	 * @param name the name of the bean to retrieve
	 * @return an instance of the bean
	 * @throws NoSuchBeanDefinitionException if there is no bean definition
	 * with the specified name
	 * @throws BeansException if the bean could not be obtained
	 * 
	 */
	Object getBean(String name) throws BeansException;

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type
	 * safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the
	 * required type. This means that ClassCastException can't be thrown on casting
	 * the result correctly, as can happen with {@link #getBean(String)}.
	 * <p>Translates aliases back to the corresponding canonical bean name.
	 * Will ask the parent factory if the bean cannot be found in this factory instance.
	 * @param name the name of the bean to retrieve
	 * @param requiredType type the bean must match. Can be an interface or superclass
	 * of the actual class, or {@code null} for any match. For example, if the value
	 * is {@code Object.class}, this method will succeed whatever the class of the
	 * returned instance.
	 * @return an instance of the bean
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 * @throws BeanNotOfRequiredTypeException if the bean is not of the required type
	 * @throws BeansException if the bean could not be created
	 */
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * <p>Allows for specifying explicit constructor arguments / factory method arguments,
	 * overriding the specified default arguments (if any) in the bean definition.
	 * @param name the name of the bean to retrieve
	 * @param args arguments to use when creating a bean instance using explicit arguments
	 * (only applied when creating a new instance as opposed to retrieving an existing one)
	 * @return an instance of the bean
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 * @throws BeanDefinitionStoreException if arguments have been given but
	 * the affected bean isn't a prototype
	 * @throws BeansException if the bean could not be created
	 * @since 2.5
	 */
	Object getBean(String name, Object... args) throws BeansException;

	/**
	 * Return the bean instance that uniquely matches the given object type, if any.
	 * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
	 * but may also be translated into a conventional by-name lookup based on the name
	 * of the given type. For more extensive retrieval operations across sets of beans,
	 * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
	 * @param requiredType type the bean must match; can be an interface or superclass.
	 * {@code null} is disallowed.
	 * @return an instance of the single bean matching the required type
	 * @throws NoSuchBeanDefinitionException if no bean of the given type was found
	 * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
	 * @throws BeansException if the bean could not be created
	 * @since 3.0
	 * @see ListableBeanFactory
	 */
	<T> T getBean(Class<T> requiredType) throws BeansException;

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * <p>Allows for specifying explicit constructor arguments / factory method arguments,
	 * overriding the specified default arguments (if any) in the bean definition.
	 * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
	 * but may also be translated into a conventional by-name lookup based on the name
	 * of the given type. For more extensive retrieval operations across sets of beans,
	 * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
	 * @param requiredType type the bean must match; can be an interface or superclass.
	 * {@code null} is disallowed.
	 * @param args arguments to use when creating a bean instance using explicit arguments
	 * (only applied when creating a new instance as opposed to retrieving an existing one)
	 * @return an instance of the bean
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 * @throws BeanDefinitionStoreException if arguments have been given but
	 * the affected bean isn't a prototype
	 * @throws BeansException if the bean could not be created
	 * @since 4.1
	 */
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;


	/**
	 * Does this bean factory contain a bean definition or externally registered singleton
	 * instance with the given name?
	 * <p>If the given name is an alias, it will be translated back to the corresponding
	 * canonical bean name.
	 * <p>If this factory is hierarchical, will ask any parent factory if the bean cannot
	 * be found in this factory instance.
	 * <p>If a bean definition or singleton instance matching the given name is found,
	 * this method will return {@code true} whether the named bean definition is concrete
	 * or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true}
	 * return value from this method does not necessarily indicate that {@link #getBean}
	 * will be able to obtain an instance for the same name.
	 * @param name the name of the bean to query
	 * @return whether a bean with the given name is present
	 */
	boolean containsBean(String name);

	/**
	 * Is this bean a shared singleton? That is, will {@link #getBean} always
	 * return the same instance?
	 * <p>Note: This method returning {@code false} does not clearly indicate
	 * independent instances. It indicates non-singleton instances, which may correspond
	 * to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly
	 * check for independent instances.
	 * <p>Translates aliases back to the corresponding canonical bean name.
	 * Will ask the parent factory if the bean cannot be found in this factory instance.
	 * @param name the name of the bean to query
	 * @return whether this bean corresponds to a singleton instance
	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
	 * @see #getBean
	 * @see #isPrototype
	 */
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	/**
	 * Is this bean a prototype? That is, will {@link #getBean} always return
	 * independent instances?
	 * <p>Note: This method returning {@code false} does not clearly indicate
	 * a singleton object. It indicates non-independent instances, which may correspond
	 * to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly
	 * check for a shared singleton instance.
	 * <p>Translates aliases back to the corresponding canonical bean name.
	 * Will ask the parent factory if the bean cannot be found in this factory instance.
	 * @param name the name of the bean to query
	 * @return whether this bean will always deliver independent instances
	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
	 * @since 2.0.3
	 * @see #getBean
	 * @see #isSingleton
	 */
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	/**
	 * Check whether the bean with the given name matches the specified type.
	 * More specifically, check whether a {@link #getBean} call for the given name
	 * would return an object that is assignable to the specified target type.
	 * <p>Translates aliases back to the corresponding canonical bean name.
	 * Will ask the parent factory if the bean cannot be found in this factory instance.
	 * @param name the name of the bean to query
	 * @param typeToMatch the type to match against (as a {@code ResolvableType})
	 * @return {@code true} if the bean type matches,
	 * {@code false} if it doesn't match or cannot be determined yet
	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
	 * @since 4.2
	 * @see #getBean
	 * @see #getType
	 */
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	/**
	 * Check whether the bean with the given name matches the specified type.
	 * More specifically, check whether a {@link #getBean} call for the given name
	 * would return an object that is assignable to the specified target type.
	 * <p>Translates aliases back to the corresponding canonical bean name.
	 * Will ask the parent factory if the bean cannot be found in this factory instance.
	 * @param name the name of the bean to query
	 * @param typeToMatch the type to match against (as a {@code Class})
	 * @return {@code true} if the bean type matches,
	 * {@code false} if it doesn't match or cannot be determined yet
	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
	 * @since 2.0.1
	 * @see #getBean
	 * @see #getType
	 */
	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	/**
	 * Determine the type of the bean with the given name. More specifically,
	 * determine the type of object that {@link #getBean} would return for the given name.
	 * <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates,
	 * as exposed by {@link FactoryBean#getObjectType()}.
	 * <p>Translates aliases back to the corresponding canonical bean name.
	 * Will ask the parent factory if the bean cannot be found in this factory instance.
	 * @param name the name of the bean to query
	 * @return the type of the bean, or {@code null} if not determinable
	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
	 * @since 1.1.2
	 * @see #getBean
	 * @see #isTypeMatch
	 */
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	/**
	 * Return the aliases for the given bean name, if any.
	 * All of those aliases point to the same bean when used in a {@link #getBean} call.
	 * <p>If the given name is an alias, the corresponding original bean name
	 * and other aliases (if any) will be returned, with the original bean name
	 * being the first element in the array.
	 * <p>Will ask the parent factory if the bean cannot be found in this factory instance.
	 * @param name the bean name to check for aliases
	 * @return the aliases, or an empty array if none
	 * @see #getBean
	 */
	String[] getAliases(String name);

我也不想貼代碼的QAQ,但這個接口很是重要,以後都要圍繞它展開。如果要你給這個接口添加個實現類,是不是馬上想到一個或者幾個map就能搞定了?所以再有人問你能不能自己實現個spring,堅定告訴他可以!
這裏寫圖片描述
有了源頭BeanFactory,很自然的出現了很多“目的地”,可以看出,BeanFactory大致“流"向了兩個方向。一個是Factory方向,一個ApplicationContext方向。Factory方向關注的更多的是bean創建的加強,而applicationContext方向更多的關注的是一些額外的“裝飾”,比如國際化MessageSource,事件的分發ApplicationEventPublisher。就像程序員常常需要面對的一個問題:“往深度發展還是往廣度發展?”。程序是人寫出來的,肯定處處包含人類社會發展的規律,扯遠了…

下面先看下spring是如何對BeanFactory進行增強的:

  • HierarchicalBeanFactory
public interface HierarchicalBeanFactory extends BeanFactory {

	/**
	 * Return the parent bean factory, or {@code null} if there is none.
	 * 
	 * 獲取父容器
	 */
	BeanFactory getParentBeanFactory();

	/**
	 * 當前容器是否包含某個實例
	 */
	boolean containsLocalBean(String name);

}
  • ListableBeanFactory
public interface ListableBeanFactory extends BeanFactory {

	/**
	 * 是否包含bean的BeanDefinition
	 */
	boolean containsBeanDefinition(String beanName);

	/**
	 * 獲取bean的BeanDefinition的數量
	 */
	int getBeanDefinitionCount();

	/**
	 * 獲取BeanDefinition的names
	 */
	String[] getBeanDefinitionNames();

	/**
	 * 獲取指定類型的bean的名稱
	 */
	String[] getBeanNamesForType(ResolvableType type);

	/**
	 * 獲取指定類型bean的名稱
	 */
	String[] getBeanNamesForType(Class<?> type);

	/**
	 * 獲取指定類型bean的名稱
	 */
	String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

	/**
	* 獲取指定類型的bean的實例
	*/
	<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;

	/**
	* 獲取指定類型的bean的實例
	*/
	<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
			throws BeansException;
	/**
	* 獲取類上含有指定註解類型的類名稱
	*/
	String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

	/**
	* 獲取類上含有指定註解類型的實例
	*/
	Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
	
	/**
	* 獲取指定名稱類上的註解實例
	*/
	<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
			throws NoSuchBeanDefinitionException;

可以看出ListableBeanFactory是相當重要的一個接口,賦予了beanFactory將解析的Bean的信息存儲及獲取的能力。

  • AutowireCapableBeanFactory
public interface AutowireCapableBeanFactory extends BeanFactory {

	/**
	 * 默認值 不進行自動注入
	 */
	int AUTOWIRE_NO = 0;

	/**
	 * 根據名字自動注入
	 */
	int AUTOWIRE_BY_NAME = 1;

	/**
	 * 根據類型自動注入
	 */
	int AUTOWIRE_BY_TYPE = 2;

	/**
	 * 構造器注入
	 */
	int AUTOWIRE_CONSTRUCTOR = 3;

	@Deprecated
	int AUTOWIRE_AUTODETECT = 4;


	//-------------------------------------------------------------------------
	// Typical methods for creating and populating external bean instances
	//-------------------------------------------------------------------------

	/**
	 * 根據類型創建bean
	 */
	<T> T createBean(Class<T> beanClass) throws BeansException;

	/**
	 * 觸發指定的bean的依賴注入
	 */
	void autowireBean(Object existingBean) throws BeansException;

	/**
	 * 配置指定的bean,包括自動注入屬性,設置屬性的值,調用beanFactory的回調,例如 setBeanFactory,
	 * 執行相關後置處理器
	 */
	Object configureBean(Object existingBean, String beanName) throws BeansException;


	//-------------------------------------------------------------------------
	// Specialized methods for fine-grained control over the bean lifecycle
	//-------------------------------------------------------------------------

	/**
	 * 創建bean的實例
	 */
	Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

	/**
	 * 創建指定類型的bean實例,並進行依賴注入
	 */
	Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

	/**
	 * 設置指定bean實例的屬性
	 */
	void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
			throws BeansException;

	/**
	 * 設置指定bean實例的屬性,並不觸發依賴注入
	 */
	void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;

	/**
	 * 初始化指定bean實例,包括調用beanFactory相關回調,處理後置處理器等。
	 */
	Object initializeBean(Object existingBean, String beanName) throws BeansException;

	/**
	 * 在bean實例化之前觸發指定bean實例的處理器
	 */
	Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException;

	/**
	 * 在bean實例化之後觸發指定bean實例的處理器
	 */
	Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException;

	/**
	 * 銷燬指定bean實例
	 */
	void destroyBean(Object existingBean);


	//-------------------------------------------------------------------------
	// Delegate methods for resolving injection points
	//-------------------------------------------------------------------------

	/**
	 * 根據類型解析成爲相應的NamedBeanHolder
	 */
	<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;

	/**
	 * 根據DependencyDescriptor 解析注入的類實例
	 */
	Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException;

	/**
	 * 根據DependencyDescriptor 解析注入的類實例
	 */
	Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
			Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;

AutowireCapableBeanFactory賦予了BeanFactory依賴注入的能力。

  • ConfigurableBeanFactory
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {

	/**
	 * 單例標誌
	 */
	String SCOPE_SINGLETON = "singleton";

	/**
	 * 原型標誌
	 */
	String SCOPE_PROTOTYPE = "prototype";


	/**
	 * 設置父BeanFactory
	 */
	void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;

	/**
	 * 設置ClassLoader
	 */
	void setBeanClassLoader(ClassLoader beanClassLoader);

	/**
	 * 獲取ClassLoader
	 */
	ClassLoader getBeanClassLoader();

	/**
	 * 設置臨時的ClassLoader用作類型匹配
	 */
	void setTempClassLoader(ClassLoader tempClassLoader);

	/**
	 * 獲取臨時的ClassLoader
	 */
	ClassLoader getTempClassLoader();

	/**
	 * 設置是否緩存Bean的元數據
	 */
	void setCacheBeanMetadata(boolean cacheBeanMetadata);

	/**
	 * 獲取是否緩存Bean的元數據
	 */
	boolean isCacheBeanMetadata();

	/**
	 * 
	 * 指定bean表達式解析器,默認沒有,ApplicationContext會默認指定一個標準的策略,支持el表達式
	 */
	void setBeanExpressionResolver(BeanExpressionResolver resolver);

	/**
	 * 獲取bean表達式解析器
	 */
	BeanExpressionResolver getBeanExpressionResolver();

	/**
	 * 指定bean屬性的轉化service
	 */
	void setConversionService(ConversionService conversionService);

	/**
	 * 獲取bean屬性轉化service
	 */
	ConversionService getConversionService();

	void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);

	/**
	 * 註冊屬性Editor
	 */
	void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);

	/**
	 * Initialize the given PropertyEditorRegistry with the custom editors
	 * that have been registered with this BeanFactory.
	 * @param registry the PropertyEditorRegistry to initialize
	 */
	void copyRegisteredEditorsTo(PropertyEditorRegistry registry);

	/**
	 * 設置類型轉換器
	 */
	void setTypeConverter(TypeConverter typeConverter);

	/**
	 * 獲取類型轉換器
	 */
	TypeConverter getTypeConverter();

	/**
	 * Add a String resolver for embedded values such as annotation attributes.
	 * @param valueResolver the String resolver to apply to embedded values
	 * @since 3.0
	 */
	void addEmbeddedValueResolver(StringValueResolver valueResolver);

	/**
	 * Determine whether an embedded value resolver has been registered with this
	 * bean factory, to be applied through {@link #resolveEmbeddedValue(String)}.
	 * @since 4.3
	 */
	boolean hasEmbeddedValueResolver();

	/**
	 * Resolve the given embedded value, e.g. an annotation attribute.
	 * @param value the value to resolve
	 * @return the resolved value (may be the original value as-is)
	 * @since 3.0
	 */
	String resolveEmbeddedValue(String value);

	/**
	 * 添加bean後置處理器
	 */
	void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

	/**
	 * 獲取bean後置處理器的數量
	 */
	int getBeanPostProcessorCount();

	/**
	 * Register the given scope, backed by the given Scope implementation.
	 */
	void registerScope(String scopeName, Scope scope);

	/**
	 * Return the names of all currently registered scopes.
	 * <p>This will only return the names of explicitly registered scopes.
	 * Built-in scopes such as "singleton" and "prototype" won't be exposed.
	 */
	String[] getRegisteredScopeNames();

	/**
	 * Return the Scope implementation for the given scope name, if any.
	 * <p>This will only return explicitly registered scopes.
	 * Built-in scopes such as "singleton" and "prototype" won't be exposed.
	 */
	Scope getRegisteredScope(String scopeName);

	/**
	 * Provides a security access control context relevant to this factory.
	 */
	AccessControlContext getAccessControlContext();

	/**
	 * 從其他beanFactory複製配置值
	 */
	void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);

	/**
	 * 配置別名
	 */
	void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;

	/**
	 * 解析別名
	 */
	void resolveAliases(StringValueResolver valueResolver);

	/**
	 * Return a merged BeanDefinition for the given bean name,
	 * merging a child bean definition with its parent if necessary.
	 * Considers bean definitions in ancestor factories as well.
	 */
	BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * Determine whether the bean with the given name is a FactoryBean.
	 */
	boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;

	/**
	 * 設置指定名稱的bean是否是正在創建的狀態
	 */
	void setCurrentlyInCreation(String beanName, boolean inCreation);

	/**
	 * Determine whether the specified bean is currently in creation.
	 */
	boolean isCurrentlyInCreation(String beanName);

	/**
	 * 設置指定的bean依賴的bean的名稱
	 * 
	 */
	void registerDependentBean(String beanName, String dependentBeanName);

	/**
	 * Return the names of all beans which depend on the specified bean, if any.
	 */
	String[] getDependentBeans(String beanName);

	/**
	 * Return the names of all beans that the specified bean depends on, if any.
	 */
	String[] getDependenciesForBean(String beanName);

	/**
	 * Destroy the given bean instance (usually a prototype instance
	 * obtained from this factory) according to its bean definition.
	 * <p>Any exception that arises during destruction should be caught
	 * and logged instead of propagated to the caller of this method.
	 */
	void destroyBean(String beanName, Object beanInstance);

	/**
	 * Destroy the specified scoped bean in the current target scope, if any.
	 * <p>Any exception that arises during destruction should be caught
	 * and logged instead of propagated to the caller of this method.
	 */
	void destroyScopedBean(String beanName);

	/**
	 * Destroy all singleton beans in this factory, including inner beans that have
	 * been registered as disposable. To be called on shutdown of a factory.
	 * <p>Any exception that arises during destruction should be caught
	 * and logged instead of propagated to the caller of this method.
	 */
	void destroySingletons();

}

ConfigurableBeanFactory定義了BeanFactory的各種配置項。

  • ConfigurableListableBeanFactory
public interface ConfigurableListableBeanFactory
		extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {

	/**
	 * 需要忽略依賴注入的類型
	 */
	void ignoreDependencyType(Class<?> type);

	/**
	 * 需要忽略依賴注入的接口
	 */
	void ignoreDependencyInterface(Class<?> ifc);

	/**
	 * Register a special dependency type with corresponding autowired value.
	 * <p>This is intended for factory/context references that are supposed
	 * to be autowirable but are not defined as beans in the factory:
	 * e.g. a dependency of type ApplicationContext resolved to the
	 * ApplicationContext instance that the bean is living in.
	 * <p>Note: There are no such default types registered in a plain BeanFactory,
	 * not even for the BeanFactory interface itself.
	 * 
	 * 將指定類型和指定類型的bean的實例化對象註冊進beanFactory,爲了需要依賴注入此bean但是beanFactory並沒有此種
	 * 類型的情況下
	 */
	void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);

	/**
	 * Determine whether the specified bean qualifies as an autowire candidate,
	 * to be injected into other beans which declare a dependency of matching type.
	 * <p>This method checks ancestor factories as well.
	 */
	boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
			throws NoSuchBeanDefinitionException;

	/**
	 * 獲取值定名稱的BeanDefinition 
	 */
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	Iterator<String> getBeanNamesIterator();

	void clearMetadataCache();

	/**
	 * 凍結所有的beanDefifition
	 */
	void freezeConfiguration();

	/**
	 * Return whether this factory's bean definitions are frozen,
	 * i.e. are not supposed to be modified or post-processed any further.
	 */
	boolean isConfigurationFrozen();

	/**
	 * 初始化所有的單例bean
	 */
	void preInstantiateSingletons() throws BeansException;

}

接下來我們再看下spring是如何對beanFactory進行"裝飾"的:

  • ResourceLoader
public interface ResourceLoader {

	/** Pseudo URL prefix for loading from the class path: "classpath:" */
	String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;


	/**
	 * 獲取指定路徑的資源信息
	 */
	Resource getResource(String location);

	ClassLoader getClassLoader();

}
  • ResourcePatternResolver
public interface ResourcePatternResolver extends ResourceLoader {

	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

	/**
	 * 根據匹配表達式獲取規則
	 */
	Resource[] getResources(String locationPattern) throws IOException;

}

-EnvironmentCapable

public interface EnvironmentCapable {

	/**
	 * 獲取環境信息
	 */
	Environment getEnvironment();

}

-MessageSource

public interface MessageSource {

	/**
	 * 獲取國際化消息
	 */
	String getMessage(String code, Object[] args, String defaultMessage, Locale locale);

	/**
	 * 獲取國際化消息
	 */
	String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;

	/**
	 * 獲取國際化消息
	 */
	String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;

}
  • ApplicationEventPublisher
public interface ApplicationEventPublisher {

	/**
	 * 發佈事件
	 */
	void publishEvent(ApplicationEvent event);


	void publishEvent(Object event);

}

接下來就是重量級的接口ApplicationContext
-ApplicationContext

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

	/**
	 * 容器標識
	 */
	String getId();

	
	String getApplicationName();

	
	String getDisplayName();

	
	long getStartupDate();

	/**
	 * 獲取父類容器
	 */
	ApplicationContext getParent();

	/**
	 * 獲取BeanFactory,通過這個方法可以看出ApplicationContext的實現類不是通過繼承BeanFatory來擴展功能的,
	 * 而是通過持有BeanFatory的實例來擴展功能的。
	 */
	AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

}

  • WebApplicationContext
public interface WebApplicationContext extends ApplicationContext {

	
	String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

	/**
	 * Scope identifier for request scope: "request".
	 */
	String SCOPE_REQUEST = "request";

	/**
	 * Scope identifier for session scope: "session".
	 */
	String SCOPE_SESSION = "session";

	/**
	 * Scope identifier for global session scope: "globalSession".
	 */
	String SCOPE_GLOBAL_SESSION = "globalSession";

	/**
	 * Scope identifier for the global web application scope: "application".
	 */
	String SCOPE_APPLICATION = "application";

	/**
	 * Name of the ServletContext environment bean in the factory.
	 */
	String SERVLET_CONTEXT_BEAN_NAME = "servletContext";

	/**
	 * Name of the ServletContext/PortletContext init-params environment bean in the factory.
	 */
	String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";

	/**
	 * Name of the ServletContext/PortletContext attributes environment bean in the factory.
	 */
	String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";


	/**
	 * 獲取servlet上下文信息
	 */
	ServletContext getServletContext();

}

WebApplicationContext是對ApplicationContext的擴展

  • ConfigurableApplicationContext
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {

	/**
	 * 路徑分隔符
	 */
	String CONFIG_LOCATION_DELIMITERS = ",; \t\n";

	/**
	 * 類型轉換服務名字
	 */
	String CONVERSION_SERVICE_BEAN_NAME = "conversionService";

	/**
	 * 默認代碼織入名字
	 */
	String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";

	String ENVIRONMENT_BEAN_NAME = "environment";

	String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";

	String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";

	void setId(String id);

	void setParent(ApplicationContext parent);

	@Override
	ConfigurableEnvironment getEnvironment();

	void setEnvironment(ConfigurableEnvironment environment);

	/**
	* 添加beanFactory後置處理器
	*/
	void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor);

	/**
	 * 添加容器的監聽器
	 */
	void addApplicationListener(ApplicationListener<?> listener);

	/**
	 * 刷新容器
	 */
	void refresh() throws BeansException, IllegalStateException;

	/**
	 * 註冊jvm關閉時的鉤子函數
	 */
	void registerShutdownHook();

	/**
	 * 關閉容器
	 */
	@Override
	void close();

	/**
	 * 容器是否正在運行
	 */
	boolean isActive();

	ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
  • ConfigurableWebApplicationContext
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {

	String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":";

	String SERVLET_CONFIG_BEAN_NAME = "servletConfig";
	
	void setServletContext(ServletContext servletContext);

	void setServletConfig(ServletConfig servletConfig);

	ServletConfig getServletConfig();

	/**
	 * 設置命名空間
	 */
	void setNamespace(String namespace);

	String getNamespace();

	/**
	 * 設置配置文件的路徑
	 */
	void setConfigLocation(String configLocation);

	void setConfigLocations(String... configLocations);

	String[] getConfigLocations();

}

通過分析接口我們大概可以看出整個spring容器的結構,接口中出現的類有些可能不認識,我們之後再一一分析。

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