Spring学习笔记
- 源码阅读篇
-
- 自定义手写Spring框架
- Spring重要接口详解
-
- BeanFactory继承体系
-
- 体系结构图
-
- 四级接口继承体系
- 继承关系的2个抽象类和2个实现类
- BeanFactory
- ListableBeanFactory
- HierarchicalBeanFactory
- AutowireCapableBeanFactory
- ConfigurableBeanFactory
- ConfigurableListableBeanFactory
- BeanDefinitionRegistry
- BeanDefinition继承体系
- ApplicationContext继承体系
- Spring IOC源码分析
-
- 主流程源码分析
-
- 找入口
- 流程解析
- 创建BeanFactory流程源码分析
-
- 找入口
- 流程解析
- 加载BeanDefinition流程分析
-
- 找入口
- 流程图
- 流程相关类说明
- 流程解析
- Bean实例化流程分析
-
- 找入口
- 流程解析
源码阅读篇
自定义手写Spring框架
- github地址:https://github.com/shouwangyw/ssm/tree/main/spring-framework-custom
Spring重要接口详解
BeanFactory继承体系
体系结构图

四级接口继承体系
-
作为一个主接口不继承任何接口,暂且称为一级接口。BeanFactory
-
、AutowireCapableBeanFactory
、HierarchicalBeanFactory
3个子接口继承了它,进行功能上的增强,这3个接口称为二级接口ListableBeanFactory
-
可以称为三级接口,对二级接口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程序入口
- 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的
方法:用于创建一个新的IoC容器,这个IoC容器就是DefaultListableBeanFactory对象obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 主要是通过该方法完成IoC容器的刷新
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
- AbstractRefreshableApplicationContext的
方法:销毁以前的容器,创建新的IoC容器、加载BeanDefinition对象注册到IoC容器中。refreshBeanFactory
@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:主要用来对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执行