ApplicationContext和BeanFactory都是用于加载Bean的,该接口用于扩展BeanFactory功能,比BeanFactory更强大。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//准备工作,对系统变量准备及验证
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//完成bean的解析,读取xml文件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//支持@Qualifier和@Autowried注解,属性填充
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 激活各种beanFactory处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//注册各种bean处理器,只是注册,真正调用在getBean时
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//初始化Message源,即对不同语言的消息体进行国际化处理
initMessageSource();
// Initialize event multicaster for this context.
//初始化应用消息广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//留给子类来初始化其他bean
onRefresh();
// Check for listener beans and register them.
// 查找listener bean注册到消息广播器中。
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化非惰性的 单例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
prepareRefresh方法
作用是准备系统环境变量
obtainFreshBeanFactory方法
1.refreshBeanFactory
2.getBeanFactory
prepareBeanFactory方法
对ApplicationContext进行功能扩展
这个resolver解析器是在什么时候调用的呢?上篇文章提到过,回顾下。
在调用getBean方法时,先通过beanDefinition和beanName创建实例对象(通过参数决定哪个构造函数,并查看是否有覆盖方法,来决定使用反射构建还是CGlib构建),然后暴露ObjectFactory(用于单例),并调用populateBean
方法注入属性(根据type或name来注入),然后调用哪些初始化bean的方法(例如beanPostProcessor、init方法等)。
解答:这个解析器的调用当然是在populateBean方法中,可以记得有这样一个方法applyPropertyValues
方法(注入属性的)。通过valueReslver来进行属性值的的解析。
除了设置当前classloader、语言解析器,还注册了beanPostProcessor。然后还忽略了一些依赖,用于在依赖注入时忽略这些bean。
再来回顾一下beanPostProcessor的流程吧~
首先先执行beanPostProcessor的before方法、然后是afterProperties方法、接着init指定方法、最后是bpp的after方法。忘记的看我之前的文章。
看看这个ApplicationContextAware吧
我当时看到代码中有
@Autowried
ApplicationContext applicationcontext;
这也就解释了为什么能注入进去了。
BeanFactoryPostProcessor和bpp类似,可以在容器实际实例化任何其他bean之前读取配置元数据,并可能修改它。beanFactoryPostProcessor作用范围是容器级别的,它仅仅对容器bean进行后置处理。只和你所使用的容器有关。bfpp不会对定义在另一个容器中的bean进行后置处理。典型应用是PropertyPlaceholderConfigurer。
例如这样的配置:
<!-- 配置dbcp数据源 -->
<bean id="dataSourceDefault" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
它会将这些value从配置文件中替换成正确的内容。当然我们也可以自己定义一些bfpp来实现我们想要的功能。比如说,去除属性值是敏感词的。
invokeBeanFactoryPostProcessors方法
有三种记录后处理器的List
1.registryPostProcessors:通过硬编码方式注册的BeanDefinitionRegistryPostProcessor
2.regularPostProcessor:记录通过硬编码方式注册的BeanFactoryPostProcessor类型的处理器。
3.registryPostProcessorBeans:记录通过配置方式注册的BeanDefinitionRegistryPostProcessor类型的处理器。
紧接着会对所有记录的后处理器统一调用postProcessBeanDefinitionRegistry、postProcessBeanFactory方法。
registerBeanPostProcessors方法
这里看名字就知道是注册bpp的地方。bpp的处理中并没有加入硬编码方式,是因为bpp并不需要立即被调用。可以在开发时想想,我这个定制化是在什么时候才需要执行的。
对于beanFactory的注册,不是直接注册的。在Spring中支持对bpp的排序,比如根据PriorityOrdered排序,根据Ordered排序或无序方式。这样激活顺序就需要考虑到。
initMessageSource方法
它是用来初始化消息资源的方法。用于国际化。(我是感觉只要做了国际化,那么这个系统就废了)
initApplicationEventMulticaster方法
用于注册事件广播器
看一下SimpleApplicationEventMulticaster是如何将事件交给事件监听器
registerListeners方法
该方法用于注册监听器
finishBeanFactoryInitialization方法
完成beanFactory初始化工作,包括ConversionService设置、配置冻结以及非延迟加载bean的初始化工作。
1.ConversionService的使用
Spring数据转换(一)–ConversionService
2.配置冻结意味着bean定义将不被修改或者进行任何一步处理。
3.preInstantiateSingletons实例化单例bean
finishRefresh方法