spring源码学习之二 XmlWebApplicationContext类结构概述
2016-02-02 10:26
746 查看
先来看下XmlWebApplicationContext类UML图
从上图可以看出,XmlWebApplicationContext实现了ConfigurableApplicationContext接口和WebApplicationContext接口.
在上一篇文章中说到通过XmlWebApplicationContext.refresh()方法来完成Spring上下文初始化配置工作,而refresh()方法是在ConfigurableApplicationContext接口中定义的.
addApplicationListener 添加应用监听器
addBeanFactoryPostProcessor 添加bean工厂处理器
close() 重新定义了Closeable中的close()方法定义
setId(String) 对当前ApplicationContext指定一个ID
registerShutdownHook()对JVM Runtime注册一个关闭钩子线程,当JVM正常关闭时会先执行该线程然后再关闭JVM,可以查看AbstractApplicationContext中的实现方法,代码如下:
上面代码功能主要是在JVM关闭时调用doClose()方法来完成Spring清理工作,可以查看close()方法,里面工作也是调用doClose()来完成Spring清理工作
在close()方法中,首先调用doClose()来完成清理工作,在清理完成后删除之前注册的shutdownHook,如果该处不移除钩子则在JVM关闭时会再执行一次清理工作.
getBeanFactory() 该方法用来获取内部BeanFactory,具体实现是在AbstractRefreshableApplicationContext中来完成,从AbstractRefreshableApplicationContext源代码可以看出,getBeanFactory()其实返回的是一个DefaultListableBeanFactory对象.另外通过该方法注释可以看出getBeanFactory()仅仅只能在isActive()返回true的时候调用,否则会抛出异常,也就是说在refresh()和close()之间调用,在refresh()之前和close()后调用都会抛出异常.
下面主要看下该类的refresh()实现方法,代码如下:
refresh()方法是线程安全的.
prepareRefresh()方法主要初始化属性资源并验证系统环境中的属性配置.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();这里创建了内置BeanFactory, obtainFreshBeanFactory()源码如下:
在obtainFreshBeanFactory()方法内部首先调用refreshBeanFactory()方法来初始化配置BeanFactory,该方法在AbstractApplicationContext类中定义为抽象方法,就像注释说明一样该方法在子类中实现.而实现该方法的类为AbstractRefreshableApplicationContext,同样该类实现了上面提到的ConfigurableApplicationContext接口中定义的getBeanFactory()方法,getBeanFactory()返回的既是refreshBeanFactory()方法创建的DefaultListableBeanFactory对象.refreshBeanFactory()方法源代码如下:
在该方法中,首先判断当前beanFactory是否存在,如果存在则将之前对象销毁,然后调用createBeanFactory()创建DefaultListableBeanFactory,创建完成之后将当前ApplicationContext的ID赋给该DefaultListableBeanFactory,同时调用loadBeanDefinitions(DefaultListableBeanFactory beanFactory)方法开始真正初始化配置工作,而loadBeanDefinitions方法在AbstractRefreshableApplicationContext类中定义为抽象方法,具体是在XmlWebApplicationContext中实现.
下面返回AbstractApplicationContext类的refresh()方法:
prepareBeanFactory(beanFactory);该方法主要用来完成BeanFactory预处理工作.比如设置BeanClassLoader,以及设置BeanExpressionResolver来完成SPEL表达式的处理(即处理bean中的”#{…}”表达式).
从上图可以看出,XmlWebApplicationContext实现了ConfigurableApplicationContext接口和WebApplicationContext接口.
在上一篇文章中说到通过XmlWebApplicationContext.refresh()方法来完成Spring上下文初始化配置工作,而refresh()方法是在ConfigurableApplicationContext接口中定义的.
/** * Load or refresh the persistent representation of the configuration, * which might an XML file, properties file, or relational database schema. * <p>As this is a startup method, it should destroy already created singletons * if it fails, to avoid dangling resources. In other words, after invocation * of that method, either all or no singletons at all should be instantiated. * @throws BeansException if the bean factory could not be initialized * @throws IllegalStateException if already initialized and multiple refresh * attempts are not supported */ void refresh() throws BeansException, IllegalStateException;
ConfigurableApplicationContext
该接口扩展了ApplicationContext接口同时扩展了Lifecycle, Closeable两个接口,对应实现方法在AbsctractApplicationContext抽象类中完成.addApplicationListener 添加应用监听器
addBeanFactoryPostProcessor 添加bean工厂处理器
close() 重新定义了Closeable中的close()方法定义
setId(String) 对当前ApplicationContext指定一个ID
registerShutdownHook()对JVM Runtime注册一个关闭钩子线程,当JVM正常关闭时会先执行该线程然后再关闭JVM,可以查看AbstractApplicationContext中的实现方法,代码如下:
/** * Register a shutdown hook with the JVM runtime, closing this context * on JVM shutdown unless it has already been closed at that time. * <p>Delegates to {@code doClose()} for the actual closing procedure. * @see Runtime#addShutdownHook * @see #close() * @see #doClose() */ @Override public void registerShutdownHook() { if (this.shutdownHook == null) { // No shutdown hook registered yet. this.shutdownHook = new Thread() { @Override public void run() { synchronized (startupShutdownMonitor) { doClose(); } } }; Runtime.getRuntime().addShutdownHook(this.shutdownHook); } }
上面代码功能主要是在JVM关闭时调用doClose()方法来完成Spring清理工作,可以查看close()方法,里面工作也是调用doClose()来完成Spring清理工作
/** * Close this application context, destroying all beans in its bean factory. * <p>Delegates to {@code doClose()} for the actual closing procedure. * Also removes a JVM shutdown hook, if registered, as it's not needed anymore. * @see #doClose() * @see #registerShutdownHook() */ @Override public void close() { synchronized (this.startupShutdownMonitor) { doClose(); // If we registered a JVM shutdown hook, we don't need it anymore now: // We've already explicitly closed the context. if (this.shutdownHook != null) { try { Runtime.getRuntime().removeShutdownHook(this.shutdownHook); } catch (IllegalStateException ex) { // ignore - VM is already shutting down } } } }
在close()方法中,首先调用doClose()来完成清理工作,在清理完成后删除之前注册的shutdownHook,如果该处不移除钩子则在JVM关闭时会再执行一次清理工作.
getBeanFactory() 该方法用来获取内部BeanFactory,具体实现是在AbstractRefreshableApplicationContext中来完成,从AbstractRefreshableApplicationContext源代码可以看出,getBeanFactory()其实返回的是一个DefaultListableBeanFactory对象.另外通过该方法注释可以看出getBeanFactory()仅仅只能在isActive()返回true的时候调用,否则会抛出异常,也就是说在refresh()和close()之间调用,在refresh()之前和close()后调用都会抛出异常.
AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean
下面主要看下该类的refresh()实现方法,代码如下:
@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. 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(bean 4000 Factory); // 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) { 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(); } } }
refresh()方法是线程安全的.
prepareRefresh()方法主要初始化属性资源并验证系统环境中的属性配置.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();这里创建了内置BeanFactory, obtainFreshBeanFactory()源码如下:
/** * Tell the subclass to refresh the internal bean factory. * @return the fresh BeanFactory instance * @see #refreshBeanFactory() * @see #getBeanFactory() */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
在obtainFreshBeanFactory()方法内部首先调用refreshBeanFactory()方法来初始化配置BeanFactory,该方法在AbstractApplicationContext类中定义为抽象方法,就像注释说明一样该方法在子类中实现.而实现该方法的类为AbstractRefreshableApplicationContext,同样该类实现了上面提到的ConfigurableApplicationContext接口中定义的getBeanFactory()方法,getBeanFactory()返回的既是refreshBeanFactory()方法创建的DefaultListableBeanFactory对象.refreshBeanFactory()方法源代码如下:
/** * This implementation performs an actual refresh of this context's underlying * bean factory, shutting down the previous bean factory (if any) and * initializing a fresh bean factory for the next phase of the context's lifecycle. */ @Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
在该方法中,首先判断当前beanFactory是否存在,如果存在则将之前对象销毁,然后调用createBeanFactory()创建DefaultListableBeanFactory,创建完成之后将当前ApplicationContext的ID赋给该DefaultListableBeanFactory,同时调用loadBeanDefinitions(DefaultListableBeanFactory beanFactory)方法开始真正初始化配置工作,而loadBeanDefinitions方法在AbstractRefreshableApplicationContext类中定义为抽象方法,具体是在XmlWebApplicationContext中实现.
下面返回AbstractApplicationContext类的refresh()方法:
prepareBeanFactory(beanFactory);该方法主要用来完成BeanFactory预处理工作.比如设置BeanClassLoader,以及设置BeanExpressionResolver来完成SPEL表达式的处理(即处理bean中的”#{…}”表达式).
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 模拟Spring的简单实现
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
- struts2 spring整合fieldError问题
- spring的jdbctemplate的crud的基类dao
- 读取spring配置文件的方法(spring读取资源文件)
- Spring Bean基本管理实例详解
- java实现简单美女拼图游戏
- 详解Java的Spring框架中的事务管理方式
- 解析Java的Spring框架的BeanPostProcessor发布处理器
- Java开发框架spring实现自定义缓存标签
- java基本教程之线程休眠 java多线程教程
- JSP开发中在spring mvc项目中实现登录账号单浏览器登录
- spring boot实战之内嵌容器tomcat配置