3.25 Spring 源码分析
BeanFactory : 主要的方法就是getBean(StringbeanName),该方法从容器中返回特定名称的Bean,BeanFactory 的功能通过其他的接口得到不断扩展。
AbstractBeanFactory : 内部维护一个MAP 保存bean的定义.
PropertySupportBeanFactory 继承了 AbstractBeanFactory : 职责是解析Property
DependencyInjectionFactory :
AbstractApplicationContext :
ApplicationContext 由BeanFactory 派生而来,提供了更多面向实际应用的功能。在BeanFactory 中,很多功能需要以编程的方式实现,而在ApplicationContext 中则可以通过配置的方式实现。
WebApplicationContext 是专门为Web 应用准备的,它允许从相对于Web 根目录的路径中装载配置文件完成初始化工作。从WebApplicationContext 中可以获得ServletContext 的引用,整个Web 应用上下文对象将作为属性放置到ServletContext 中,以便Web 应用环境可以访问Spring 应用上下文(ApplicationContext)。Spring 专门为此提供一个工具类WebApplicationContextUtils,通过该类的getWebApplicationContext(ServletContext sc)方法,即可以从ServletContext 中获取WebApplicationContext 实例。
ClasspathXmlApplicationContext和FileSystemXmlApplicationContext的实现基本一致。
IOC初始化
跟踪FileSystemXmlBeanFactory类构造函数的代码上,可以看到IOC容器初始化是在AbstractApplicationContext类的refresh()方法中开始的,刷新IOC可分如下几个大步骤。
1.prepareRefresh()为初始化筹备环境,创建标准环境StandardEnviroment。
2.obtainFreshBeanFactory()刷新IOC容器,如果BeanFactory存在,则销毁,再创建DefaultListableBeanFactory容器。这里主要是BeanDefinition解析注册。
3.prepareBeanFactory()BeanFactory初始化,为BeanFactory添加初始化特性。
4.postProcessBeanFactory()为BeanFactory的BeanFactoryPostProcessor后置处理器,空方法空实现,需子类实现。
5.invokeBeanFactoryPostProcessors()调用BeanFactory的BeanFactoryPostProcessor后置处理器。
6.registerBeanPostProcessors()给BeanFactory注册BeanPostProcessor后置处理器。
7.initMessageSource()初始化消息源,即国际化。
8.initApplicationEventMulticaster()初始化应用事件多路广播实例。
9.onRefresh()初始化特殊Bean,未实现,给子类实现。
10.registerListeners()注册应用监听器。
11.finishBeanFactoryInitialization()结束BeanFactory的初始化,需要饥饿加载的单例Bean是在这里初始化加载缓存的。
12.finishRefresh()完成IOC初始化,并发布对应的事件(ContextRefreshedEvent)。
Splitter与jdk中split的比较
Splitter可以用指定的分隔符来分割给定的字符串,和Jsplit()相比,Splitter更加灵活:
1.Splitter可以支持单个字符、字符串、正则表达式或者CharMatcher实例来分割给定的字符串,而String类中的split()方法只支持用正则表达式来分割给定的字符串,用途很有限。
2.我们都知道,用正则表达式来分割字符串的效率很低,对于大量的字符串分割如果用String类中的split()方法势必影响程序的效率,建议使用Splitter类提供的方法。
3.String类中的split()方法返回的是String数组类型,而Splitter类返回的是Iterator类型的接口,可以直接用在集合中(Lists.newArrayList(Splitter.on(‘,’).split(“a
,_b,c__”));)
4.我们还可以通过Splitter类中的trimResults()方法去掉子串中的空格,以及omitEmptyStrings()方法去掉空的子串,大大简化了用户的使用。
5.Splitter类可以在结果中继续分割,比如:Map
split =
Splitter.on(‘;’).trimResults().withKeyValueSeparator(“=”).split(“a=2;b=3″);直接返回Map的键值对,这比String中的split方法强大多了,很值得用。