AbstractApplicationContext.refresh()
refresh方法实际上调用到了AbstractApplicationContext的refresh方法。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
复制代码
首先通过获取对象锁来保证启动及关闭的同步。该方法下面做的事情就比较多了,我们需要跟踪每个方法的内部调用来分析具体做了什么。
1. prepareRefresh
通过方法名大致也能猜测到是refresh前的准备工作。比如设置启动时间,启动标识等,还有些配置环境的占位符初始化解析及必要性校验的工作。
2. obtainFreshBeanFactory
获取beanFactory容器
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
return beanFactory;
}
复制代码
首先refreshBeanFactory方法调用到GenericApplicationContext, 设置一个refreshed标识,然后给默认的beanFactory设置一个id;然后就是返回当前beanFactory对象(DefaultListableBeanFactory)。
3. prepareBeanFactory
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
复制代码
- 设置beanFactory的classLoader为当前context的classLoader
- 设置beanFactory的表达式语言处理器,spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值。
- 为beanFactory增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具,以后再做详细分析。
- 添加了一个处理aware相关接口的beanPostProcessor扩展ApplicationContextAwareProcessor,主要是使用beanPostProcessor的postProcessBeforeInitialization()前置处理方法会在bean实例化前进行属性注入,例如实现BeanFactoryAware的Bean在初始化后,Spring容器将会注入BeanFactory的实例。相应的还有ApplicationContextAware、ResourceLoaderAware、ServletContextAware等。
- 设置了几个忽略自动装配的接口,默认只有BeanFactoryAware被忽略,其他的都要自行设置,这里设置了ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware和ApplicationContextAware。
- 设置了几个自动装配的特殊规则,如果是BeanFactory类型,则注入beanFactory对象,如果是ResourceLoader、ApplicationEventPublisher、ApplicationContext类型则注入当前对象。
接着往下看
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
复制代码
这部分判断是否定义了名为loadTimeWeaver的bean,如果定义了则添加loadTimeWeaver功能的beanPostProcessor扩展,并且创建一个临时的classLoader来让其处理真正的bean。该扩展具体是做什么的我还没深入了解,后续有时间再研究。
后面就是检查factory中是否有环境配置,系统变量等相应的bean,如果没有则注册。这里使用到了registerSingleton方法,和我们之前碰的registerBeanDefinition不一样。这里放入的直接是实例对象,不再是beanDefinition对象。
4. postProcessBeanFactory
该方法在当前类中没有具体实现,由于子类来扩展实现。按我们的环境其实现在AnnotationConfigServletWebServerApplicationContext类中。
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
if (this.basePackages != null && this.basePackages.length > 0) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
复制代码
调用父类实现
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(
new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
复制代码
首先是增加一个beanPostProcessor处理器,主要用于在bean初始化前后设置servlet相关配置。然后通过scanner, reader来注册beanDefinition,在我们的环境当中没有手动设置,这里不会做任何操作。
5. invokeBeanFactoryPostProcessors
访方法调用到了PostProcessorRegistrationDelegate的静态方法invokeBeanFactoryPostProcessors。代码较多,这里不再粘贴,大致介绍一下方法流程。
- 首先通过getBeanFactoryPostProcessors查找手动配置的beanFactory后置处理器。(在前面分析的Initializer和listener中增加)
- 判断其是否实现BeanDefinitionRegistryPostProcessor接口,如果是则先执行postProcessBeanDefinitionRegistry方法,并区分暂存到两个集合当中。BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口。
- 通过beanFactory的getBeanNamesForType方法来查找容器中BeanDefinitionRegistryPostProcessor的实现,然后按优先级及排序,非排序等分别执行。
- 把BeanDefinitionRegistryPostProcessor接口的方法都执行完成后,再分别执行其BeanFactoryPostProcessor接口的方法(这里包括手动配置及容器中查找的),并记录名字到集合。
- 同样的流程,在容器中查找BeanFactoryPostProcessor的实现,并按做优先级,排序等分别执行,这里会检验跳过上面已执行过的。
简单描述下,就是先查找BeanDefinitionRegistryPostProcessor接口实现并执行postProcessBeanDefinitionRegistry方法,然后再查找执行BeanFactoryPostProcessor接口的实现,并执行postProcessBeanFactory方法。
6. registerBeanPostProcessors
通过方法名可以理解,就是注册BeanPostProcessor实现类的。调用到PostProcessorRegistrationDelegate的方法。代码如下:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
复制代码
这里注意一下与以上一篇介绍的BeanFactoryPostProcessro接口的区别,BeanPostProcessor主要是针对bean初始化前后的扩展,具体可以自行百度下,网上资料较多。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 查找BeanPostProcessor实现的名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 添加BeanPostProcessorChecker,用于打印日志提示在BeanPostProcessor实例化期间新建bean,不能被全部的BeanPostProcessor实例处理
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 按优先级,排序,非排序等分类调用.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
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);
}
}
// 先是优先级高的
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 再是实现排序的
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
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);
// 然后是普通的
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
// 记录内部处理
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后是MergedBeanDefinitionPostProcessor的实现
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 最最后增加一个关于ApplicationListener的探测类
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
复制代码
这里registerBeanPostProcessors方法最后会调用到AbstractBeanFactory的addBeanPostProcessor方法,其实现是先删后加,所以上面MergedBeanDefinitionPostProcessor的实现不会重复添加,只是把其处理优先级放到了最后。这里又碰到那个很重要的方法getBean,关于该方法暂时不讨论了,有兴趣的要以先自行搜索查询了解下。
7. initMessageSource
初始化消息资源的默认空处理DelegatingMessageSource。
8. initApplicationEventMulticaster
初始化ApplicationListener的事件发布器简单实现
9. onRefresh
该方法主要由AbstractApplicationContext子类来扩展实现,因为我们的web服务,所以由于ServletWebServerApplicationContext实现,主要是实例化web服务,比如ServletContext上下文配置,tomcat初始化配置等。
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
复制代码
10. registerListeners
查找注册ApplicationListener实现的监听器
11. finishBeanFactoryInitialization
该方法其实就是遍历BeanFacotry当中的BeanDefinition数据,然后调用getBean方法来实例化及依赖注入等,完成容器所有bean的实例化工作。
12. finishRefresh
完成刷新工作,清除缓存;注册LifecycleProcessor的实现DefaultLifecycleProcessor并调用onRefresh方法;发布刷新事件;启动web服务等。
在整个refresh方法的最后,就是调用各种清除缓存的方法了。
备注:本章涉及三点实现较为复杂,需要着重来分析,所以后面会单章来看这几部分具体做了哪些工作
- ConfigurationClassPostProcessor类
- getBeanNamesForType方法
- getBean方法