加载
来源:互联网 发布:最准的掐指算法桃花 编辑:程序博客网 时间:2024/04/28 12:44
Spring IoC容器将载入的Bean定义资源文件转换为Document对象
refresh
FileSystemXmlApplicationContext通过调用其父类AbstractApplicationContext的refresh()函数启动整个IoC容器对Bean定义的载入过程:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识 prepareRefresh(); //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从 //子类的refreshBeanFactory()方法启动 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //为BeanFactory配置容器特性,例如类加载器、事件处理器等 prepareBeanFactory(beanFactory); try { //为容器的某些子类指定特殊的BeanPost事件处理器 postProcessBeanFactory(beanFactory); //调用所有注册的BeanFactoryPostProcessor的Bean invokeBeanFactoryPostProcessors(beanFactory); //为BeanFactory注册BeanPost事件处理器. //BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件 registerBeanPostProcessors(beanFactory); //初始化信息源,和国际化相关. initMessageSource(); //初始化容器事件传播器. initApplicationEventMulticaster(); //调用子类的某些特殊Bean初始化方法 onRefresh(); //为事件传播器注册事件监听器. registerListeners(); //初始化所有剩余的单态Bean. finishBeanFactoryInitialization(beanFactory); //初始化容器的生命周期事件处理器,并发布容器的生命周期事件 finishRefresh(); } catch (BeansException ex) { //销毁以创建的单态Bean destroyBeans(); //取消refresh操作,重置容器的同步标识. cancelRefresh(ex); throw ex; } } }
AbstractApplicationContext的obtainFreshBeanFactory()方法调用子类容器的refreshBeanFactory()方法,启动容器载入Bean定义资源文件的过程,代码如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //这里使用了委派设计模式,父类定义了抽象的refreshBeanFactory()方法,具体实现调用子类容器的refreshBeanFactory()方法 refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
AbstractApplicationContext子类的refreshBeanFactory()方法:
AbstractApplicationContext类中只抽象定义了refreshBeanFactory()方法,容器真正调用的是其子类AbstractRefreshableApplicationContext实现的 refreshBeanFactory()方法,方法的源码如下:
protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) {//如果已经有容器,销毁容器中的bean,关闭容器 destroyBeans(); closeBeanFactory(); } try { //创建IoC容器 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等 customizeBeanFactory(beanFactory); //调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
refresh()方法的作用是:在创建IoC容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,以保证在refresh之后使用的是新建立起来的IoC容器。refresh的作用类似于对IoC容器的重启,在新建立好的容器中对容器进行初始化,对Bean定义资源进行载入
loadBeanDefinitions
AbstractRefreshableApplicationContext中只定义了抽象的loadBeanDefinitions方法,容器真正调用的是其子类AbstractXmlApplicationContext对该方法的实现,AbstractXmlApplicationContext的主要源码如下:
loadBeanDefinitions方法同样是抽象方法,是由其子类实现的,也即在AbstractXmlApplicationContext中。
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext { …… //实现父类抽象的载入Bean定义方法 @Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容 器使用该读取器读取Bean定义资源 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的 //祖先父类AbstractApplicationContext继承DefaultResourceLoader,因此,容器本身也是一个资源加载器 beanDefinitionReader.setResourceLoader(this); //为Bean读取器设置SAX xml解析器 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); //当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制 initBeanDefinitionReader(beanDefinitionReader); //Bean读取器真正实现加载的方法 loadBeanDefinitions(beanDefinitionReader); } //Xml Bean读取器加载Bean定义资源 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { //获取Bean定义资源的定位 Resource[] configResources = getConfigResources(); if (configResources != null) { //Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位 //的Bean定义资源 reader.loadBeanDefinitions(configResources); } //如果子类中获取的Bean定义资源定位为空,则获取FileSystemXmlApplicationContext构造方法中setConfigLocations方法设置的资源 String[] configLocations = getConfigLocations(); if (configLocations != null) { //Xml Bean读取器调用其父类AbstractBeanDefinitionReader读取定位 //的Bean定义资源 reader.loadBeanDefinitions(configLocations); } } //这里又使用了一个委托模式,调用子类的获取Bean定义资源定位的方法 //该方法在ClassPathXmlApplicationContext中进行实现,对于我们 //举例分析源码的FileSystemXmlApplicationContext没有使用该方法 protected Resource[] getConfigResources() { return null; } …… 41}
- 加载
- 加载
- 加载
- 加载
- 加载
- 加载
- 加载
- 动态加载加载FLASH.
- 延迟加载--懒加载
- 懒加载(延迟加载)
- 图片加载---预加载
- 延时加载 懒加载
- 延时加载|懒加载
- 类加载过程---加载
- 加载、类加载、类加载器
- 同步加载、异步加载、延迟加载
- 同步加载,异步加载,延迟加载
- 同步加载、异步加载和延迟加载
- Ubuntu14.04下opencv3和opencv2共存和使用方法
- H5基础(2)-HTML5新的结构元素
- fork之后,子进程从父进程那继承了什么
- 长沙理工大学第十二届ACM大赛 C 安卓图案解锁
- java用DefaultHandler解析XML格式数据
- 加载
- 评估指标
- [持续更新]appium + java 真机测试遇到的问题
- lvs-dr中的arp内核参数
- 455. Assign Cookies
- 99%的人理解错 HTTP 中 GET 与 POST 的区别
- Bubble Cup X
- 在ubuntu16.04下载&编译android源代码
- Java如何配置安装jdk环境变量