天天看點

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,堅定告訴他可以!

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

有了源頭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容器的結構,接口中出現的類有些可能不認識,我們之後再一一分析。

繼續閱讀