码云地址带有上篇文章中所用的中文注释和测试类,分支my-test
Spring 是渐进式的工具,并不具有很强的侵入性,它的模块也划分得很合理,即使你的应用不是 web 应用,或者之前完全没有使用到 Spring,而你就想用 Spring 的依赖注入这个功能,其实完全是可以的,它的引入不会对其他的组件产生冲突
ApplicationContext继承结构
构建 ApplicationContext的方案有很多,先来看看大体的继承结构是怎么样的:
我们可以使用 FileSystemXmlApplicationContext 和 ClassPathXmlApplicationContext 和 AnnotationConfigApplicationContext 这三个类来构建 ApplicationContext
1、FileSystemXmlApplicationContext 的构造函数需要一个 xml 配置文件在系统中的路径,和 ClassPathXmlApplicationContext 基本上一样。
2、ClassPathXmlApplicationContext 是根据 xml 文件内容来构建 ApplicationContext,就是在 ClassPath 中寻找 xml 配置文件。
3、AnnotationConfigApplicationContext 是基于注解来使用的,它不需要配置文件,采用 java 配置类和各种注解来配置,目前主流方式。
BeanFactory继承结构
ApplicationContext 其实就是一个 BeanFactory,生产 bean 的工厂,它负责生产和管理各个 bean 实例,继承结构:
-
ApplicationContext 继承了 ListableBeanFactory,这个 Listable 的意思就是,通过这个接口,我们可以获取多个 Bean,大家看源码会发现,最顶层 BeanFactory 接口的方法都是获取单个 Bean 的。
-
ApplicationContext 继承了 HierarchicalBeanFactory,Hierarchical 单词本身已经能说明问题了,也就是说我们可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系。
-
AutowireCapableBeanFactory 用来自动装配 Bean 用的,但是仔细看上图,ApplicationContext 并没有继承它,不过不用担心,不使用继承,不代表不可以使用组合,如果你看到 ApplicationContext 接口定义中的最后一个方法 getAutowireCapableBeanFactory() 就知道了。
-
ConfigurableListableBeanFactory 也是一个特殊的接口,看图,特殊之处在于它继承了第二层所有的三个接口,而 ApplicationContext 没有。这点之后会用到。
BeanFactory、ListableBeanFactory、HierarchicalBeanFactory、AutowireCapableBeanFactory、ApplicationContext 这几个接口中的方法:
启动过程分析
public class Test {
public static void main(String[] args) {
// 实例化ApplicationContext容器对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class);
context.getBean(Z.class);
}
}
通过创建AnnotationConfigApplicationContext对象,执行构造方法里的refresh()方法(初始化容器),为什么是 refresh(),而不是 init() 这种名字的方法。因为 ApplicationContext 建立起来以后,其实我们是可以通过调用 refresh() 这个方法重建的,refresh() 会将原来的 ApplicationContext 销毁,然后再重新执行一次初始化操作
refresh() 方法里面调用的方法很多,一个一个方法来看大概做了些什么事情,首先是prepareRefresh()
prepareRefresh
这个方法主要是记录启动时间,校验 xml 配置文件,检验environment的properties是否正确,initPropertySources会调用GenericWebApplicationContext的实现,设置容器的环境,初始化容器的属性
obtainFreshBeanFactory
因为上面调用了GenericApplicationContext的实现,触发构造方法,这里将会创建 BeanFactory,也就是创建了DefaultListableBeanFactory,如下:
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
obtainFreshBeanFactory方法其实就是拿到之前创建的 beanFactory 对象,spring容器是通过 ConfigurableListableBeanFactory 这个bean工厂进行真正的bean加载。其主要做了三个动作,刷新 beanFactory,获取 beanFactory,返回 beanFactory
/**
* Tell the subclass to refresh the internal bean factory
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 刷新 BeanFactory并指定序列化id
// 调用了AtomicBoolean的compareAndSet方法,保证只刷新一次
// 如果再次调用refresh()方法,则会抛出异常
refreshBeanFactory();
// 返回刚刚创建的 BeanFactory
return getBeanFactory();
}
这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map),这里说的 Bean 还没有初始化,只是配置信息都提取出来了
prepareBeanFactory
在注册bean之前先给beanFactory配置一些属性,它们可以帮助beanFactory后期去解析、注册其他的bean
如果上述几个Aware不使用ignoreDependencyInterface会有什么问题呢?如果我们写一个实现类,然后给他默认配置ApplicationContext属性,而这个ApplicationContext是我们自己new的,这就导致了我们使用的不是spring自己生成的ApplicationContext,所以spring为了避免我们手误自己注册下这个属性,而帮我们忽略。
registerResolvableDependency就是当我们使用自动注入比如@AutoWired注入BeanFactory 类型时,他会帮我们注入目前输入的实例对象,而不会去注入他的其他实现类,这是为了避免我们使用其他的自定义的实例对象
postProcessBeanFactory
Spring中并没有具体去实现postProcessBeanFactory方法,是提供给想要实现BeanPostProcessor的三方框架使用的。谁要使用谁就去实现。其实就是向上下文中添加了一系列的Bean的后置处理器,后置处理器工作的时机是在所有的beanDefinition加载完成之后,bean实例化之前执行。简单来说Bean的后置处理器是用来修改BeanDefinition的属性信息的
invokeBeanFactoryPostProcessors
实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor),在该方法中完成IoC容器的初始化;代码较多,推荐阅读此篇文章
此方法执行完成后,我们自己创建加了注解的Bean会被put到beanDefinitionMap中,上篇文章中有讲
registerBeanPostProcessors
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取所有实现BeanPostProcessor接口的bean的名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// 加一是因为方法末尾会注册一个ApplicationListenerDetector接口的实现类
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 注册 BeanPostProcessorChecker,用于每个bean的初始化完成后,做一些简单的检查
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 缓存实现了priorityOrdered接口的bean
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 排序、注册
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 缓存实现Ordered接口的bean
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 排序、注册
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
// 缓存没有实现两个接口的bean
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 注册
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 排序注册所有的实现了MergedBeanDefinitionPostProcessor接口的bean
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 注册ApplicationListenerDetector,用来检查所有的ApplicationListener
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
这里只是注册,相当于整理所有的BeanPostProcessor,把其提出来,按执行循序放到list中,供后续调用。原来我们只知道所有的BeanPostProcessor都在IoC容器中以bean的形式存在着,但是我们不知道应该如何去执行,以什么顺序去执行。经过该方法解决了该问题
最后几个方法
// Initialize message source for this context.
// 初始化当前 ApplicationContext 的 MessageSource,主要做国际化处理
initMessageSource();
// Initialize event multicaster for this context.
// 初始化当前 ApplicationContext 的事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
// 空壳方法,类似postProcessBeanFactory()
onRefresh();
// Check for listener beans and register them.
// 注册事件监听器,监听器需要实现 ApplicationListener 接口
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化所有的 singleton beans,上篇文章已分析
//(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 最后,广播事件,ApplicationContext 初始化完成
finishRefresh();
// Destroy already created singletons to avoid dangling resources.
// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
destroyBeans();
// Reset 'active' flag.
// 设置active表示为false
cancelRefresh(ex);
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
// 清除反射的缓存
// 清除注解的相关缓存
// 清除classloader缓存
resetCommonCaches();