2013/13/3
/** Map of bean definition objects, keyed by bean name */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
看到这里,思路已经很明确了。bean工厂的初始化其实就是往这个map中填充东西。只要我们把xml中定义的bean都填充到这里,这个工厂就可以工作了。
那么问题来了:那么从现在来看,我们需要什么才能把Map填充呢?也就是初始化bean工厂呢,或者说建立IOC容器。我首先列出来以下几步。
1.需要一个File指向我们的XML文件(本文的配置文件都已XML为例,因为这是我们最熟悉的),专业点可以叫资源定位,简单点可以说我们需要一些工具来完成找到XML文件的所在位置。
2.需要一个Reader来读取我们的XML文件,专业点叫DOM解析,简单点说,就是把XML文件的各种定义都给拿出来。
3.需要将读出来的数据都设置到Map当中。
public class TestDefaultListableBeanFactory {
publicstaticvoid main(String[] args) {
ClassPathResource classPathResource = new ClassPathResource("beans.xml");
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions(classPathResource);
System.out.println("numbers: " + defaultListableBeanFactory.getBeanDefinitionCount());
((Person)defaultListableBeanFactory.getBean("person")).work();
}
}
public class TestApplicationContext {
publicstaticvoid main(String[] args) {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:beans.xml");
System.out.println("numbers: " + applicationContext.getBeanDefinitionCount());
((Person)applicationContext.getBean("person")).work();
}
}
接下来我们看下FileSystemXmlApplicationContext这个类
最终构造函数调用:
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
其中refresh()便是ioc容器的入口 refresh方法位于AbstractApplicationContext中,这是一个抽象类,初步实现了ApplicationContext的一般功能,refresh()方法列出了ioc容器的初始化的一些步骤,主要来看第二步,obtainFreshBeanFactory 这个方法步,它是用来告诉子类刷新内部的bean工厂
/** * Tell the subclass to refresh the internal bean factory. * @return the fresh BeanFactory instance * @see #refreshBeanFactory() * @see #getBeanFactory() */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if ( logger.isDebugEnabled()) { logger.debug( "Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
这里使用了模板模式,给以后要实现的子类提供了统一的模板,refreshBeanFactory,getBeanFactory都是抽象方法
先来看下refreshBeanFactory()具体实现
@Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } }catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " +getDisplayName(), ex); } }
spring ioc的源码简单介绍,布布扣,bubuko.com
原文:http://www.cnblogs.com/zhenglu204/p/3583470.html