JavaEE 企业级分布式高级架构师(三)Spring学习笔记(3)

源码阅读篇

自定义手写Spring框架

Spring重要接口详解

BeanFactory继承体系

体系结构图

在这里插入图片描述

四级接口继承体系
  • BeanFactory 作为一个主接口不继承任何接口,暂且称为一级接口。
  • AutowireCapableBeanFactoryHierarchicalBeanFactoryListableBeanFactory3个子接口继承了它,进行功能上的增强,这3个接口称为二级接口
  • ConfigurableBeanFactory可以称为三级接口,对二级接口HierarchicalBeanFactory进行了再次增强,它还继承了另一个外来的接口SingletonBeanRegistry
  • ConfigurableListableBeanFactory是一个更加强大的接口,继承了上述所有的接口,无所不能,称为四级接口。

总结:
| – BeanFactory:是Spring Bean容器的根接口,提供获取Bean、是否包含Bean、是否单例与原型、获取bean类型、bean别名的API
| – – AutowireCapableBeanFactory:提供工厂的装配功能
| – – HierarchicalBeanFactory:提供父容器的访问功能
| – – ListableBeanFactory:提供容器内Bean实例的枚举功能,这边不会考虑父容器内的实例
| – – – ConfigurableBeanFactory:提供Factory的配置功能,眼花缭乱好多API
| – – – – ConfigurableListableBeanFactory:集大成者,提供解析,修改Bean的定义,并初始化单例
设计模式原则里的:接口隔离原则

继承关系的2个抽象类和2个实现类
  • AbstractBeanFactory:作为一个抽象类,实现了三级接口ConfigurableBeanFactory大部分功能。
  • AbstractAutowireCapableBeanFactory:同样是抽象类,继承自AbstractBeanFactory,并额为实现了二级接口AutowireCapableBeanFactory
  • DefaultListableBeanFactory继承自AbstractAutowireCapableBeanFactory,实现了最强大的四级接口ConfigurableListableBeanFactory,并实现了一个外来接口BeanDefinitionRegistry,它并非抽象类
  • 最后是最强大的XmlBeanFactory,继承自DefaultListableBeanFactory,重写了一些功能,使自己更加强大。

总结
BeanFactory的类体系结构看似繁杂混乱,实际上由上而下仅仅有条,非常容易理解。

BeanFactory
public interface BeanFactory {
	// 用来引用一个实例,或把它和工厂产生的Bean区分开
	// 就是说,如果一个FactoryBean的名称为a,那么@a会得到那个Factory
	String FACTORY_BEAN_PREFIX = "&";
	
	// 四种不同形式的getBean的方法,获取实例
	Object getBean(String name) throws BeansException;
	<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
	Object getBean(String name, Object... args) throws BeansException;
	<T> T getBean(Class<T> requiredType) throws BeansException;
	// 是否存在
	boolean containsBean(String name);
	// 是否为单实例
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	// 是否为原型(多实例)
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
	// 名称、类型是否匹配
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
	boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
	// 获取类型
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;
	// 根据实例的名字获取实例的别名
	String[] getAliases(String name);
}
  • 源码说明:
* 4个获取实例的方法:getBean的重载方法
* 5个判断方法:判断是否存在,是否为单例、原型,名称类型是否匹配(2个)
* 1个获取类型的方法、一个获取别名的方法,根据名称获取类型、根据名称获取别名。一目了然
  • 总结:这11个方法,很明显这是一个典型的工厂模式的工厂接口
ListableBeanFactory

可将Bean逐一列出的工厂

public interface ListableBeanFactory extends BeanFactory {
	// 对于给定的名称是都含有
	boolean containsBeanDefinition(String beanName);
	// 返回工厂的BeanDefinition总数
	int getBeanDefinitionCount();
	// 返回工厂中所有Bean的名字
	String[] getBeanDefinitionNames();
	// 返回对于指定类型Bean(包括子类)的所有名字
	String[] getBeanNamesForType(ResolvableType type);
	String[] getBeanNamesForType(@Nullable Class<?> type);
	/*
	 * 返回指定类型的名字
	 * includeNonSingletons:为false表示只取单例Bean,true则不是
	 * allowEagerInit:为true表示立刻加载,false表示延迟加载
	 * 注意:FactoryBeans都是立刻加载的
	 */ 
	String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
	// 根据类型(包括子类)返回指定Bean名和Bean的Map
	<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
	<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;
	// 返回指定注解类型的名字
	String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
	// 根据注解类型,查找所有有这个注解的Bean名和Bean的Map
	Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
	// 根据指定Bean名和注解类型查找指定的Bean
	@Nullable
	<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
			throws NoSuchBeanDefinitionException;
}
  • 源码说明:
* 3个跟BeanDefinition有关的总体操作。包括BeanDefinition的总数、名字的集合、指定类型的名字的集合(这里指出:BeanDefinition是Spring中非常重要的类,每个BeanDefinition实例都包含一个类在Spring工厂中所有的属性)
* 3个getBeanNamesForType重载方法,根据指定类型(包括子类)获取其对应的所有Bean名字
* 2个getBeansOfType重载方法,根据类型(包括子类)返回指定Bean名和Bean的Map
* 3个跟注解查找相关的方法,根据注解类型,查找Bean名和Bean的Map,以及根据指定Bean名和注解类型查找指定的Bean。
  • 总结:正如这个工厂接口的名字,这个工厂最大的特点就是可以列出工厂可以生产的所有实例。当然,工厂并没有直接提供返回所有实例的方法,也没有必要。它可以返回指定类型的所有实例, 而且你可以通过getBeanDefinitionNames()得到工厂所有Bean名字,然后根据这个名字得到Bean。这个工厂接口扩展了BeanFactory的功能,作为上文指出的BeanFactory二级接口,有11个独立的方法,扩展了跟BeanDefinition的功能,提供了BeanDefinition、BeanName、注解有关的各种操作。它可以根据条件返回Bean的集合,这就是它名字的由来——ListableBeanFactory。
HierarchicalBeanFactory
  • 分层的Bean工厂
public interface HierarchicalBeanFactory extends BeanFactory {
	// 返回本Bean工厂的父工厂,实现了工厂的分层
	@Nullable
	BeanFactory getParentBeanFactory();
	// 判断本地工厂是否包含这个Bean(忽略其他所有的父工厂),这就是分层思想的体现
	boolean containsLocalBean(String name);
}
  • 总结:这个工厂的接口非常简单,实现了Bean工厂的分层,这个工厂接口也是继承自BeanFactory,也是一个二级接口,相对于父接口,它只扩展了一个重要的功能——工厂分层。
AutowireCapableBeanFactory
  • 自动装配的Bean工厂
public interface AutowireCapableBeanFactory extends BeanFactory {
	// 表明工厂没有自动装配的Bean
	int AUTOWIRE_NO = 0;
	// 表明根据名称自动装配
	int AUTOWIRE_BY_NAME = 1;
	// 表明根据类型自动装配
	int AUTOWIRE_BY_TYPE = 2;
	// 表明根据构造函数方法快速装配
	int AUTOWIRE_CONSTRUCTOR = 3;
	// 表明通过Bean的class内部来自动装配(Spring3.0 被弃用)
	@Deprecated
	int AUTOWIRE_AUTODETECT = 4;
	// 根据指定Class创建一个全新的Bean实例
	<T> T createBean(Class<T> beanClass) throws BeansException;
	// 给定对象,根据注解、后处理器等,进行自动装配
	void autowireBean(Object existingBean) throws BeansException;
	// 根据Bean的BeanDefinition装配这个未加工的Object,执行回调和各种后处理器
	Object configureBean(Object existingBean, String beanName) throws BeansException;
	// 根据给定的类型和指定的装配策略,创建一个新的Bean实例
	Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
	// 与上面类似,实现稍有不同
	Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
	// 根据名称或者类型自动装配
	void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException;
	// 也是自动装配
	void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
	// 初始化一个Bean
	Object initializeBean(Object existingBean, String beanName) throws BeansException;
	// 初始化之前执行BeanPostProcessors
	Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException;
	// 初始化之后执行BeanAfterProcessors
	Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException;
	// 销毁Bean
	void destroyBean(Object existingBean);
	// 分解Bean
	<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
	// 分解Bean在工厂总定义的这个指定的依赖descriptor
	@Nullable
	Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
	// 分解指定的依赖
	@Nullable
	Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
}
  • 源码说明
* 总共5个不可变常量来指明装配策略,其中一个常量被Spring3.0废弃,一个常量表示没有自动装配,另外3个常量指明不同的装配策略——根据名称、根据类型、根据构造方法
* 8个自动装配有关的方法
* 一个Bean前置处理器方法,一个Bean后置处理方法
* 一个销毁Bean方法和3个分解指定依赖的方法
  • 总结:这个工厂接口继承自BeanFactory,它扩展了自动装配的功能,根据 BeanDefinition 装配Bean,执行前后处理器等。
ConfigurableBeanFactory
  • 复杂的配置Bean工厂
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
	String SCOPE_SINGLETON = "singleton"; // 单例
	String SCOPE_PROTOTYPE = "prototype"; // 原型
	// 搭配HierarchicalBeanFactory接口的getParentBeanFactory方法
	void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
	// 设置工厂的类加载器
	void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
	// 返回工厂的类加载器
	@Nullable
	ClassLoader getBeanClassLoader();
	// 设置一个临时的类加载器
	void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
	// 返回一个临时的类加载器
	@Nullable
	ClassLoader getTempClassLoader();
	// 设置是否缓存元数据,如果为false,那么每次请求实例,都会从类加载器重新加载(热加载)
	void setCacheBeanMetadata(boolean cacheBeanMetadata);
	// 是否缓存元数据
	boolean isCacheBeanMetadata();
	// 设置Bean表达式分解器
	void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
	// 获取Bean表达式分解器
	@Nullable
	BeanExpressionResolver getBeanExpressionResolver();
	// 设置一个转换服务
	void setConversionService(@Nullable ConversionService conversionService);
	// 返回一个转换服务
	@Nullable
	ConversionService getConversionService();
	// 设置属性编辑登记员
	void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
	// 注册常用属性编辑器
	void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
	// 用工厂中注册的通用编辑器初始化指定的属性编辑注册器
	void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
	// 设置一个类型转换器
	void setTypeConverter(TypeConverter typeConverter);
	// 返回一个类型转换器
	TypeConverter getTypeConverter();
	// 增加一个嵌入式的StringValueResolver
	void addEmbeddedValueResolver(StringValueResolver valueResolver);
	// 判断是否有一个嵌入式的StringValueResolver
	boolean hasEmbeddedValueResolver();
	// 分解指定的嵌入式的值
	@Nullable
	String resolveEmbeddedValue(String value);
	// 设置一个Bean后置处理器
	void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
	// 返回Bean后置处理器的数量
	int getBeanPostProcessorCount();
	// 注册范围
	void registerScope(String scopeName, Scope scope);
	// 返回注册的范围名
	String[] getRegisteredScopeNames();
	// 返回指定的范围
	@Nullable
	Scope getRegisteredScope(String scopeName);
	// 返回本工厂的一个安全访问上下文
	AccessControlContext getAccessControlContext();
	// 从其他工厂复制相关的所有配置
	void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
	// 给指定的Bean注册别名
	void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
	// 根据指定的valueResolver移除所有别名
	void resolveAliases(StringValueResolver valueResolver);
	// 返回指定Bean合并后的Bean定义
	BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	// 判断指定的Bean是否为一个工厂Bean
	boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
	// 设置一个Bean是否正在创建
	void setCurrentlyInCreation(String beanName, boolean inCreation);
	// 返回指定Bean是否已经成功创建
	boolean isCurrentlyInCreation(String beanName);
	// 注册一个依赖于指定bean的Bean
	void registerDependentBean(String beanName, String dependentBeanName);
	// 返回依赖于指定bean的所有Bean名称
	String[] getDependentBeans(String beanName);
	// 返回指定Bean依赖的所有Bean名称
	String[] getDependenciesForBean(String beanName);
	// 销毁指定的Bean
	void destroyBean(String beanName, Object beanInstance);
	// 销毁指定范围的bean
	void destroyScopedBean(String beanName);
	// 销毁所有的单例类
	void destroySingletons();
}
ConfigurableListableBeanFactory
  • BeanFactory的集大成者
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
	// 忽略自动装配的依赖类型
	void ignoreDependencyType(Class<?> type);
	// 忽略自动装配的接口
	void ignoreDependencyInterface(Class<?> ifc);
	// 注册一个可分解的依赖
	void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
	// 判断指定的Bean是否有资格作为自动装配的候选者
	boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException;
	// 返回注册的Bean定义
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	// 返回Bean名称迭代器
	Iterator<String> getBeanNamesIterator();
	// 清除元数据缓存
	void clearMetadataCache();
	// 暂时冻结所有的Bean配置
	void freezeConfiguration();
	// 判断本工厂配置是否被冻结
	boolean isConfigurationFrozen();
	// 使所有非延迟加载的单例类都实例化
	void preInstantiateSingletons() throws BeansException;
}
  • 源码说明
* 2个忽略自动装配的方法
* 1个注册可分解依赖的方法
* 1个判断指定的Bean是否有资格作为自动装配的候选者的方法
* 1个根据指定Bean名,返回注册的Bean定义的方法
* 1个返回Bean名称迭代器的方法
* 1个清除元数据缓存的方法
* 2个冻结所有Bean配置的相关方法
* 1个使所有非延迟加载的单例类都实例化的方法
  • 总结:工厂接口ConfigurableListableBeanFactory同时继承了3个接口,ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory,扩展后加上自有的10个方法。
BeanDefinitionRegistry
  • 额外的接口,这个接口基本用来操作定义在工厂内部的BeanDefinition的。
public interface BeanDefinitionRegistry extends AliasRegistry {
	// 给定Bean名称,注册一个新的Bean定义
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
	// 根据指定Bean名称移除对应的Bean定义
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	// 根据指定的Bean名称得到对应的Bean定义
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	// 查找指定的Bean名是否包含Bean的定义
	boolean containsBeanDefinition(String beanName);
	// 返回本容器内所有注册的Bean定义名称
	String[] getBeanDefinitionNames();
	// 返回本容器内所有注册的Bean定义数目
	int getBeanDefinitionCount();
	// 指定Bean名称是否被注册过
	boolean isBeanNameInUse(String beanName);
}

BeanDefinition继承体系

  • Spring IOC容器管理了我们定义的各种Bean对象及其相互关系,Bean对象在Spring实现中是以BeanDefinition来描述的,其继承体系如下:

在这里插入图片描述

ApplicationContext继承体系

在这里插入图片描述

在这里插入图片描述

Spring IOC源码分析

在这里插入图片描述

主流程源码分析

找入口
  • java程序入口
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
  • Web程序入口
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>

不管上面那种方式,最终都会调AbstractApplicationContext的refresh方法,而这个方法才是我们真正的入口

在这里插入图片描述

流程解析
  • AbstractApplicationContext 的 refresh 方法
// 完成IoC容器的创建及初始化工作
@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
        // STEP 1: 刷新预处理
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
        // STEP 2:
        // 		a) 创建IoC容器(DefaultListableBeanFactory)
        //		b) 加载解析XML文件(最终存储到Document对象中)
        //		c) 读取Document对象,并完成BeanDefinition的加载和注册工作
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
        // STEP 3: 对IoC容器进行一些预处理(设置一些公共属性)
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
            // STEP 4: 
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			// STEP 5: 调用BeanFactoryPostProcessor后置处理器对BeanDefinition处理
            invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			// STEP 6: 注册BeanPostProcessor后置处理器
            registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			// STEP 7: 初始化一些消息源(比如处理国际化的i18n等消息源)
            initMessageSource();

			// Initialize event multicaster for this context.
			// STEP 8: 初始化应用事件广播器
            initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// STEP 9: 初始化一些特殊的bean
            onRefresh();

			// Check for listener beans and register them.
			// STEP 10: 注册一些监听器
            registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// STEP 11: 实例化剩余的单例bean(非懒加载方式)
            // 注意事项:Bean的IoC、DI和AOP都是发生在此步骤
            finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// STEP 12: 完成刷新时,需要发布对应的事件
            finishRefresh();
		}
		// 略...
	}
}

创建BeanFactory流程源码分析

找入口
  • AbstractApplicationContext 类的 refresh方法:
// Tell the subclass to refresh the internal bean factory.
// STEP 2:
// 		a) 创建IoC容器(DefaultListableBeanFactory)
//		b) 加载解析XML文件(最终存储到Document对象中)
//		c) 读取Document对象,并完成BeanDefinition的加载和注册工作
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
流程解析
  • AbstractApplicationContext的obtainFreshBeanFactory 方法:用于创建一个新的IoC容器,这个IoC容器就是DefaultListableBeanFactory对象
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	// 主要是通过该方法完成IoC容器的刷新
	refreshBeanFactory();
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (logger.isDebugEnabled()) {
		logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
	}
	return beanFactory;
}
  • AbstractRefreshableApplicationContext的refreshBeanFactory方法:销毁以前的容器,创建新的IoC容器、加载BeanDefinition对象注册到IoC容器中。
@Override
protected final void refreshBeanFactory() throws BeansException {
	// 如果之前有IoC容器,则销毁
   	if (hasBeanFactory()) {
		destroyBeans();
		closeBeanFactory();
	}
	try {
   		// 创建IoC容器,也就是DefaultListableBeanFactory
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		beanFactory.setSerializationId(getId());
		// 设置工厂的属性:是否允许BeanDefinition覆盖和是否允许循环依赖
		customizeBeanFactory(beanFactory);
        // 调用载入BeanDefinition的方法,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
		loadBeanDefinitions(beanFactory);
		synchronized (this.beanFactoryMonitor) {
			this.beanFactory = beanFactory;
		}
	}
	catch (IOException ex) {
		throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
	}
}
  • 进入AbstractRefreshableApplicationContext的createBeanFactory方法
protected DefaultListableBeanFactory createBeanFactory() {
	return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

加载BeanDefinition流程分析

找入口

AbstractRefreshableApplicationContext的refreshBeanFactory方法中的第13行代码

// 加载BeanDefinition对象,并注册到IoC容器中(重点)
loadBeanDefinitions(beanFactory);
流程图
AbstractRefreshableApplicationContext AbstractXmlApplicationContext AbstractBeanDefinitionReader XmlBeanDefinitionReader DefaultBeanDefinitionDocumentReader BeanDefinitionParserDelegate loadBeanDefinitions loadBeanDefinitions loadBeanDefinitions loadBeanDefinitions loadBeanDefinitions BeanDefinition解析的核心类 AbstractRefreshableApplicationContext AbstractXmlApplicationContext AbstractBeanDefinitionReader XmlBeanDefinitionReader DefaultBeanDefinitionDocumentReader BeanDefinitionParserDelegate

在这里插入图片描述

流程相关类说明
  • AbstractRefreshableApplicationContext:主要用来对BeanFactory提供 refresh功能,包括BeanFactory的创建和BeanDefinition的定义、解析、注册等操作。
  • AbstractXmlApplicationContext:主要提供对于XML资源的加载功能,包括从Resource资源对象和资源路径中加载XML文件。
  • AbstractBeanDefinitionReader:主要提供对于BeanDefinition对象的读取功能,具体读取工作交给子类实现。
  • XmlBeanDefinitionReader:主要通过 DOM4J 对于XML资源的读取、解析功能,并提供对于BeanDefinition的注册功能。
  • DefaultBeanDefinitionDocumentReader
  • BeanDefinitionParserDelegate
流程解析
  • AbstractXmlApplicationContext的loadBeanDefinitions方法:
    • 创建一个BeanDefinition阅读器,通过阅读XML文件,真正完成BeanDefinition的加载和注册;
    • 配置XmlBeanDefinitionReader并进行初始化;
    • 委托XmlBeanDefinitionReader去加载BeanDefinition。
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	// Create a new XmlBeanDefinitionReader for the given BeanFactory.
	// 创建一个BeanDefinition阅读器,通过阅读XML文件,真正完成BeanDefinition的加载和注册
	XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

	// Configure the bean definition reader with this context's
	// resource loading environment.
	beanDefinitionReader.setEnvironment(this.getEnvironment());
	beanDefinitionReader.setResourceLoader(this);
	beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

	// Allow a subclass to provide custom initialization of the reader,
	// then proceed with actually loading the bean definitions.
	initBeanDefinitionReader(beanDefinitionReader);

	// 委托给BeanDefinition阅读器去加载BeanDefinition
	loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
	// 获取资源的定位
	// 这里getConfigResources是一个空实现,真正实现是调用子类的获取资源定位的方法
	// 比如:ClassPathXmlApplicationContext中进行了实现
	// 		而FileSystemXmlApplicationContext没有使用该方法
	Resource[] configResources = getConfigResources();
	if (configResources != null) {
		// XML Bean读取器调用其父类AbstractBeanDefinitionReader读取定位的资源
		reader.loadBeanDefinitions(configResources);
	}
	// 如果子类中获取的资源定位为空,则获取FileSystemXmlApplicationContext构造方法中setConfigLocations方法设置的资源
	String[] configLocations = getConfigLocations();
	if (configLocations != null) {
		// XML Bean读取器调用其父类AbstractBeanDefinitionReader读取定位的资源
		reader.loadBeanDefinitions(configLocations);
	}
}
  • loadBeanDefinitions方法经过一路的兜兜转转,最终来到了XmlBeanDefinitionReader的doLoadBeanDefinitions方法:
    • 一个是对XML文件进行DOM解析;
    • 一个是完成BeanDefinition对象的加载与注册。
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
		try {
			// 通过DOM4J加载解析XML文件,最终形成Document对象
			Document doc = doLoadDocument(inputSource, resource);
			// 通过对Document对象的操作,完成BeanDefinition的加载和注册工作
            return registerBeanDefinitions(doc, resource);
		}
		// 省略一些catch语句
	}
  • 此处我们暂不分析DOM4J加载解析XML的流程,我们重点分析BeanDefinition的加载注册流程,进入XmlBeanDefinitionReader的registerBeanDefinitions方法:
    • 创建DefaultBeanDefinitionDocumentReader用来解析Document对象;
    • 获得容器中已注册的BeanDefinition数量;
    • 委托给DefaultBeanDefinitionDocumentReader来完成BeanDefinition的加载、注册工作;
    • 统计新注册的BeanDefinition数量。
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
	// 创建BeanDefinitionDocumentReader来解析Document对象,完成BeanDefinition解析
	BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
	// 获得容器中已经注册的BeanDefinition数量
	int countBefore = getRegistry().getBeanDefinitionCount();
	// 解析过程入口,BeanDefinitionDocumentReader只是个接口,具体的实现过程在DefaultBeanDefinitionDocumentReader完成
	documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
	// 统计新的的BeanDefinition数量
	return getRegistry().getBeanDefinitionCount() - countBefore;
}
  • 进入DefaultBeanDefinitionDocumentReader的registerBeanDefinitions方法:
    • 获得Document的根元素标签;
    • 真正实现BeanDefinition解析和注册工作。
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
	this.readerContext = readerContext;
	logger.debug("Loading bean definitions");
	// 获得Document的根元素<beans>标签
	Element root = doc.getDocumentElement();
	// 真正实现BeanDefinition解析和注册工作
	doRegisterBeanDefinitions(root);
}
  • 进入DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions方法:
    • 这里使用了委托模式,将具体的BeanDefinition解析工作交给BeanDefinitionParserDelegate去完成;
    • 在解析Bean定义之前,进行自定义的解析,增强解析过程的可扩展性;
    • 委托给BeanDefinitionParserDelegate,从Document的根元素开始进行BeanDefinition的解析;
    • 在解析Bean定义后,进行自定义的解析,增强解析过程的扩展性。
protected void doRegisterBeanDefinitions(Element root) {
	// Any nested <beans> elements will cause recursion in this method. In
	// order to propagate and preserve <beans> default-* attributes correctly,
	// keep track of the current (parent) delegate, which may be null. Create
	// the new (child) delegate with a reference to the parent for fallback purposes,
	// then ultimately reset this.delegate back to its original (parent) reference.
	// this behavior emulates a stack of delegates without actually necessitating one.
	
	// 这里使用了委托模式,将具体的BeanDefinition解析工作交给了BeanDefinitionParserDelegate去完成
	BeanDefinitionParserDelegate parent = this.delegate;
	this.delegate = createDelegate(getReaderContext(), root, parent);

	// 判断该根标签是否包含http://www.springframework.org/schema/beans默认命名空间
	if (this.delegate.isDefaultNamespace(root)) {
		String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
		if (StringUtils.hasText(profileSpec)) {
			String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
					profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
				if (logger.isInfoEnabled()) {
					logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
							"] not matching: " + getReaderContext().getResource());
				}
				return;
			}
		}
	}
	// 在解析Bean定义之前,进行自定义的解析,增强解析过程的可扩展性
	preProcessXml(root);
	// 委托给BeanDefinitionParserDelegate,从Document的根元素开始进行BeanDefinition的解析
	parseBeanDefinitions(root, this.delegate);
	// 在解析Bean定义之后,进行自定义的解析,增加解析过程的可扩展性
	postProcessXml(root);

	this.delegate = parent;
}
  • 记笔记:
AbstractXmlApplicationContext#loadBeanDefinitions
  |--XmlBeanDefinitionReader#loadBeanDefinitions
    |--AbstractBeanDefinitionReader#loadBeanDefinitions
      |--XmlBeanDefinitionReader#loadBeanDefinitions
        |--XmlBeanDefinitionReader#doLoadBeanDefinitions:真正干活的
          |--XmlBeanDefinitionReader#doLoadDocument:解析XML为Document
            |--XmlBeanDefinitionReader#registerBeanDefinitions
              |--DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
                |--DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
				  |--DefaultBeanDefinitionDocumentReader#parseDefaultElement
					|--DefaultBeanDefinitionDocumentReader#processBeanDefinition:解析bean标签
 					  |--BeanDefinitionParserDelegate#parseBeanDefinitionElement:将Bean标签解析之后,封装到GenericBeanDefinition对象中
  • 总结:将XML中的Bean标签解析成 GenericBeanDefinition 对象之后,然后注册到BeanDefinitionRegistry(DefaultListableBeanFactory)的Map中,其中key为Bean name,value就是 BeanDefinition 对象。

Bean实例化流程分析

找入口
  • AbstractApplicationContext类的refresh方法:
// Instantiate all remaining (non-lazy-init) singletons.
// STEP 11: 实例化剩余的单例bean(非懒加载方式)
// 注意事项:Bean的IoC、DI和AOP都是发生在此步骤
finishBeanFactoryInitialization(beanFactory);
流程解析
AbstractApplicationContext#finishBeanFactoryInitialization
	|--DefaultListableBeanFactory#preInstantiateSingletons
		|--AbstractAutowireCapableBeanFactory#doCreateBean:完成Bean的实例化、填充属性、初始化
			|--createBeanInstance:Bean的实例化
				|--instantiateBean
					|--SimpleInstantiationStrategy#instantiate
						|--BeanUtils#instantiateClass:通过构造参数,反射创建Bean实例
			|--populateBean:Bean的属性填充
				|--applyPropertyValues
					|--AbstractPropertyAccessor#setPropertyValues
						|--AbstractNestablePrpertyAccessor#setPropertyValue
							|--processLocalProperty
								|--PropertyHandler#setValue:完成简单属性和Bean实例的填充
									|--BeanPropertyHandler#setValue:通过JDK内省技术set注入
									|--FieldPropertyHandler#setValue:通过反射set方法完成注入
			|--initializeBean:Bean的初始化
				|--applyBeanPostProcessorsBeforeInitialization:
				|--invokeInitMethods:调用initMethod指定的方法或者afterPropertiesSet方法
				|--applyBeanPostProcessorsAfterInitialization:AOP执行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讲文明的喜羊羊拒绝pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值