转自http://www.sandzhang.com/blog/2011/03/30/spring-study-notes-initialization-1/
ApplicationContext ctx = new ClassPathXmlApplicationContext( "spring-config.xml"); FooService foo = (FooService) ctx.getBean("FooService");
我们看第一行初始化了一个ClassPathXmlApplicationContext对象,
注:也可以用FileSystemXmlApplicationContext来加载,两者的区别只是查找配置文件的起始路径不同,一个以classpath为当前路径,一个是直接用文件系统的当前路径,内部没有太大区别。
注2:web工程大家都知道我们配置了ContextLoaderListener,这里暂时不做介绍,后面会有专门的分析,起始主题流程都差不多,详情请参见:从源码看Spring在web工程中的初始化。
请看下面的构造方法,参数是spring配置文件在classpath中的全路径名:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null); }
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
我们看这个构造方法的代码:
setConfigLocations代码:
很简单,主要是检验是否传入参数为空然后赋值给configLocations属性,不过其中有两个小特点可以注意一下:
public void setConfigLocations(String[] locations) { if (locations != null) { Assert.noNullElements(locations, "Config locations must not be null"); this.configLocations = new String[locations.length]; for (int i = 0; i < locations.length; i++) { this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; } }
public void refresh() throws BeansException, IllegalStateException { // 整个刷新过程是同步的 synchronized (this.startupShutdownMonitor) { // 刷新前的准备工作 prepareRefresh(); // 关闭释放旧的beanFactory创建新的beanFactory,读取配置文件等 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 对beanFactory进行一些基本的初始化 prepareBeanFactory(beanFactory); try { // 下面两行主要用户扩展,处理所有已注册的BeanFactoryPostProcessor,实现在已经加载配置但未初始化bean时对配置进行修改 postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); // 处理所有已注册的BeanPostProcessor,主要用于扩展,实现bean初始化前后的一些定制操作 registerBeanPostProcessors(beanFactory); // 初始化消息源bean initMessageSource(); // 初始化事件监听器集,也有人叫事件监听器的注册表,所有的事件监听器都在这个bean里进行管理 initApplicationEventMulticaster(); // 主要用于扩展,实现一些特殊bean的初始化,时间点是类似消息源事件监听器集等特殊bean初始化后,普通的bean初始化前 onRefresh(); // 注册监听器 registerListeners(); // 初始化其余的非延迟加载的单例bean finishBeanFactoryInitialization(beanFactory); // 刷新完成调用LifecycleProcessor的onRefresh方法,并且发布ContextRefreshedEvent事件 finishRefresh(); } catch (BeansException ex) { // 销毁已经创建的单例bean destroyBeans(); // 重新设置active标记 cancelRefresh(ex); throw ex; } } }