Spring源码阅读(四)—容器的功能拓展ApplicationContext
来源:互联网 发布:学白话大全软件 编辑:程序博客网 时间:2024/06/03 20:35
ApplicationContext和BeanFactory都用于Bean的加载,ApplicationContext包含BeanFactory的所有功能,创建的上下文环境是BeanFactory的功能拓展.
个人主页:tuzhenyu’s page
原文地址:Spring源码阅读(四)—容器的功能拓展ApplicationContext
(0) ApplicationContext和BeanFactory的区别
ApplicationContext(应用上下文)和BeanFactory(bean工厂)是Spring的两种容器,ApplicationContext是BeanFactory的功能拓展.
BeanFactroy采用的是延迟加载形式来注入依赖的,只有在调用getBean()的时候才对该Bean进行加载实例化.而ApplicationContext是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。
ApplicationContext扩展了ResourceLoader(资源加载器)接口,从而可以用来加载多个Resource,而BeanFactory是没有扩展ResourceLoader ,只能加载单个资源文件.
BeanFactory是不支持国际化功能的,因为BeanFactory没有扩展Spring中MessageResource接口。相反,由于ApplicationContext扩展了MessageResource接口提供了国际化的消息访问功能.
ApplicationContext实现了强大的事件机制(Event)
(1) ApplicationContext上下文的入口
- 初始化ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");HelloWorld helloWorld = context.getBean("hello",HelloWorld.class);
- 调用setConfigLocations()方法将配置文件加载进内存,调用refresh()方法进行上下文的初始化
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); this.setConfigLocations(configLocations); if(refresh) { this.refresh(); }}
(2) ApplicationContext上下文的初始化
上下文初始化主要步骤:
调用prepareRefresh()方法刷新上下文环境,对系统属性和环境变量的初始化进行验证;
调用obtainFreshBeanFactory()方法读取XML配置文件初始化BeanFactory,实现了BeanFactory的功能.
调用prepareBeanFactory()方法对BeanFactory进行功能拓展
实现事件机制
初始化剩下的所有单例bean,进行bean的初始化和依赖的注入
public void refresh() throws BeansException, IllegalStateException { Object var1 = this.startupShutdownMonitor; synchronized(this.startupShutdownMonitor) { this.prepareRefresh(); ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.prepareBeanFactory(beanFactory); try { this.postProcessBeanFactory(beanFactory); this.invokeBeanFactoryPostProcessors(beanFactory); this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh(); } catch (BeansException var5) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var5); this.destroyBeans(); this.cancelRefresh(var5); throw var5; } }}
1.调用obtainFreshBeanFactory()方法初始化BeanFactory
调用customizeBeanFactory()定制BeanFactory提供@Autowired支持等
调用loadBeanDefinitions()方法从XML配置文件中装载bean
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { this.refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); if(this.logger.isDebugEnabled()) { this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory); } return beanFactory;}
2.BeanFactory的功能拓展
- 调用invokeBeanFactoryPostProcessors()方法激活所有注册的BeanBeanFactoryPostProcessor后处理器(对象是BeanFactory).BeanBeanFactoryPostProcessor是在注册Bean工厂加载完所有Bean后执行,通过实现BeanFactoryPostProcessor接口进行注册.
this.invokeBeanFactoryPostProcessors(beanFactory);
- 调用registerBeanPostProcessors()方法注册BeanPostProcessor后处理器(对象是Bean).BeanPostProcessor是在bean实例化后调用,用于功能拓展.BeanPostProcessor注册的方法是实现InstantiationAwareBeanPostProcessor接口.
this.registerBeanPostProcessors(beanFactory);
- 调用initMessageSource()方法初始化Message源,进行国际化处理
this.initMessageSource();
实现事件机制
调用initApplicationMuticaster()方法初始化消息广播器,广播器用于存放监听器并在合适的时候调用监听器.
调用registerListeners()方法注册bean中的所有监听器listener
this.initApplicationEventMulticaster();this.registerListeners();
- 调用finishBeanFactoryInitialization()方法加载所有的bean实例,并进行依赖注入(区别于BeanFactory的重要一点)
调用preInstantiateSingletons()方法进行bean的实例化和依赖注入
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { if(beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) { beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class)); } String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); String[] var3 = weaverAwareNames; int var4 = weaverAwareNames.length; for(int var5 = 0; var5 < var4; ++var5) { String weaverAwareName = var3[var5]; this.getBean(weaverAwareName); } beanFactory.setTempClassLoader((ClassLoader)null); beanFactory.freezeConfiguration(); beanFactory.preInstantiateSingletons();}
(3) 总结
ApplicationContext上下文的初始化主要是进行了初始化BeanFactory,并在此基础上进行功能拓展比如事件机制,后处理器等,最后对BeanFactory中的所有bean进行实例化和依赖注入.
- Spring源码阅读(四)—容器的功能拓展ApplicationContext
- spring源码初步学习-容器的功能扩展(ApplicationContext)
- spring源码学习(八)容器功能拓展
- Spring源码之ApplicationContext(四)功能补充
- spring源码阅读(五)之ApplicationContext
- Spring源码阅读-ApplicationContext对BeanFactory的增强
- Spring源码阅读(一):IOC容器的初始化
- Spring源码阅读(二)—IOC容器初始化
- Spring源码阅读(三)—IOC容器依赖注入
- Spring核心技术(十四)——ApplicationContext的额外功能
- Spring源码深度解析(四)容器的基础XmlBeanFactory
- Spring源码深度解析(四)容器的基础XmlBeanFactory
- spring源码阅读(四)之BeanFactory
- Spring笔记——Spring容器:ApplicationContext
- Spring源码阅读 四 IOC
- 获取当前的spring容器ApplicationContext 。
- spring的ico容器 ApplicationContext.xml
- 获取当前的spring容器ApplicationContext
- Linq查找指定重复次数的键
- 本文从如何建立mysql索引以及介绍mysql的索引类型,再讲mysql索引的利与弊,以及建立索引时需要注意的地方 首先:先假设有一张表,表的数据有10W条数据,其中有一条数据是nickname='
- 修改限制端口访问wdcp后台
- 04.Spring Cloud学习笔记之客户端负载均衡组件Ribbon
- 递归和迭代
- Spring源码阅读(四)—容器的功能拓展ApplicationContext
- 自定义view 之 仿QQ侧滑菜单
- 【theano-windows】学习笔记一——theano中的变量
- windows下 安装 rabbitMQ 及操作常用命令
- J
- vm两个linux虚拟机之间互传文件
- 记一次Spring aop的所遇到的问题
- Linux下用户组、文件权限详解
- Javascript Hoisting( 变量提升)