源码分析基于spring 4.3.x
前面已经说过spring 创建bean的过程, 也强调了BeanPostProcessor这些扩展接口。
在 创建bean过程中, spring会查找用户定义的BeanPostProcessor并进行相应操作, 那么问题来了, 用户定义的BeanPostProcessor是怎样进入spring的呢?
这里就要说到spring context了。
我们先来看看spring 模块
(图片出自 Framework Modules)
Spring-core和Spring-beans模块提供了spring的框架基础,包括IoC和依赖注入功能。
Context(spring-context)模块建立在Core和Beans模块提供的可靠基础之上。Context模块增加了对国际化(例如使用资源包),事件传播,资源加载,上下文透明创建(如Servlet容器)的支持。Context模块还支持Java EE功能,如EJB,JMX和基本的远程处理。ApplicationContext接口是Context模块的焦点。
将用户定义的BeanPostProcessor加载到spring,正是spring context的工作。
回顾一下在spring加载配置中说到的测试例子, 修改为如下就可以使用到spring context了:
@Test
public void test() {
ClassPathXmlApplicationContext beanFactory = new ClassPathXmlApplicationContext("spring.xml");
Blog bean = (Blog)beanFactory.getBean("blog");
Assert.assertEquals(bean.getTitle(), "hello spring");
}
ClassPathXmlApplicationContext的继承层次很深, spring一般按功能的叠加会划分继承关系。
applicationContext.png
context可以简单分为web上下文, 非web的上下文。
这里直接看看例子中的ClassPathXmlApplicationContext
先看看构造方法
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
核心方法为refresh(),这个方法在AbstractApplicationContext中
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备刷新上下文环境
prepareRefresh();
// 初始化BeanFactory,并读取xml文件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 对beanFacotry进行配置
prepareBeanFactory(beanFactory);
try {
// 提供给子类覆盖方法做额外处理
postProcessBeanFactory(beanFactory);
// 激活BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessors
registerBeanPostProcessors(beanFactory);
initMessageSource();
// 初始化广播器,并放到上下文中
initApplicationEventMulticaster();
// 提供给子类初始化其他的Bean
onRefresh();
// 注册事件监听器
registerListeners();
// 初始化剩下的非惰性单例bean
finishBeanFactoryInitialization(beanFactory);
// 完成刷新过程,通知生命周期处理器
finishRefresh();
}
catch (BeansException ex) {
...
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
初始化BeanFactory,读取context文件
obtainFreshBeanFactory负责初始化BeanFactory,并读取context文件
初始化BeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
return beanFactory;
}
关键方法是refreshBeanFactory, getBeanFactory只是获取创建好的BeanFactory,refreshBeanFactory由AbstractRefreshableApplicationContext实现
protected final void refreshBeanFactory() throws BeansException {
// 如果BeanFactory已存在,则销毁
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 读取xml
loadBeanDefinitions(beanFactory);
// beanFactory赋值
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
前面已经说过了, spring加载配置主要就是通过DefaultListableBeanFactory。
读取context文件
在看看读取xml文件的方法loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
,该方法由AbstractXmlApplicationContext实现
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 创建XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 配置XmlBeanDefinitionReader
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 模板方法
initBeanDefinitionReader(beanDefinitionReader);
// 读取xml文件
loadBeanDefinitions(beanDefinitionReader);
}
这里的loadBeanDefinitions(XmlBeanDefinitionReader reader)
由AbstractXmlApplicationContext实现
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// getConfigResources模板方法,提供子类扩展
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
// 获取用户指定的context文件
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
这里通过XmlBeanDefinitionReader.loadBeanDefinitions读取xml文件, 并将结果加载到spring中(在spring加载配置中已经说过了)。
激活BeanFactoryPostProcessors
BeanFactoryPostProcessor也是spring提供的扩展接口,可以通过BeanFactoryPostProcessor对beanFactory进行处理,如修改其他BeanDefinition的配置。
这里会调用AbstractApplicationContext.invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
...
}
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
会找到用户定义的BeanFactoryPostProcessor,并调用它们。
注册BeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
PostProcessorRegistrationDelegate.registerBeanPostProcessors
会找到用户定义的BeanPostProcessor, 并注册到spring中, spring创建bean时会使用到它们。
初始化事件广播器
Spring事件体系包括三个组件:事件ApplicationEvent,事件监听器ApplicationListener,事件广播器ApplicationEventMulticaster。事件广播器负责管理事件监听器,并将事件广播给监听器。
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// beanFactory中包含了事件广播器
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
}
else { // 使用默认的事件广播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
注册事件监听器
事件监听器负责监听事件,并做出处理。
registerListeners将初始化事件监听器,并添加到事件广播器上。
protected void registerListeners() {
// 首先注册静态指定的侦听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 注册spring上下文中的ApplicationListener
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 发布在此之前已发生的事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
初始化非惰性单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化ConversionService
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// 初始化LoadTimeWeaverAware
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
// 初始化非惰性单例bean
beanFactory.preInstantiateSingletons();
}
finishRefresh
protected void finishRefresh() {
// 初始化LifecycleProcessor
initLifecycleProcessor();
// 触发LifecycleProcessor.onRefresh()
getLifecycleProcessor().onRefresh();
// 发布事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
LifecycleProcessor也是spring提供的扩展点, 它可以定义spring启动(start),停止(stop),或刷新(onRefresh)时的额外操作。
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
}
else { // 使用默认的LifecycleProcessor
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
}
}
这里主要讲了spring context事件传播,上下文创建, 加载扩展接口等内容,讲的比较简单,很多地方都是蜻蜓点水, 有兴趣的同学可以自行深入阅读源码。
网友评论