Spring IoC容器的初始化包括 BeanDefinition的Resource定位、载入和注册 这三个基本的过程。IoC容器的初始化过程不包含Bean依赖注入的实现。Bean依赖的注入一般会发生在第一次通过getBean向容器索取Bean的时候。
先看以下代码:
ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml");Car car = (Car) context.getBean("car");System.out.println(car.getBrand());
以上是我们常用的加载IoC容器,并获得Bean的代码。直接进入ClassPathXmlApplicationContext的构造方法,它实际调用的构造方法为:
[url=][/url]
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); //调用容器的refresh,载入BeanDefinitionde的入口。 }}[url=][/url]
[url=][/url]
调用super(parent)方法为容器设置好Bean资源加载器,该方法最终会调用到AbstractApplicationContext的无参构造方法,这里会默认设置解析路径的模式为Ant-style。setConfigLocations(configLocations)设置Bean定义资源文件的定位路径。AbstractRefreshableConfigApplicationContext中的setConfigLocation(String location)说明了多个资源文件路径之间可以是用” ,
; /t/n”分隔。setConfigLocations(String… locations)说明了它还接受字符串数组。[url=][/url]
接下来看下最重要的refresh()方法。
View Code
我们重点看ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();。这句代码的作用是告诉子类启动refreshBeanFactory方法以及通过getBeanFactory获得beanFactory。
refreshBeanFactory方法在AbstractApplicationContext中被定义,且在其子类AbstractRefreshableApplicationContext中实现。代码如下:
[url=][/url]
@Overrideprotected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { //如果已经有BeanFactory,销毁bean,关闭BeanFactory destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); //创建IoC容器 beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); //启动对BeanDefinitions的载入 synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); }}[url=][/url]
通过createBeanFactory()构建了一个DefaultListableBeanFactory IoC容器提供给ApplicationContext使用。同时通过loadBeanDefinitions(beanFactory)载入Bean定义。
loadBeanDefinitions方法的具体实现是在AbstractXmlApplicationContext中。
[url=][/url]
@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容器使用该读取器读取Bean定义资源 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); //为Bean读取器设置Spring资源加载器 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); //当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制 initBeanDefinitionReader(beanDefinitionReader); //通过beanDefinitionReader加载BeanDefinitions loadBeanDefinitions(beanDefinitionReader);} |