SpringIOC
本文研究以下几点:
1>IOC容器在启动过程中都做了什么
2>IOC如何创建单实例Bean,并如何管理;保存在哪里
(1)ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
首先使用ClassPathXmlApplicationContext构造器,ClassPathXmlApplicationContext有很多种构造器,但它们最终都会调用this的构造器。执行上述的代码,此时会将ioc.xml传入new String[]数组中,并且refresh = true, parent=null 源码如下:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
经过每一段代码的调试,发现当执行refresh()时,容器就创建了所有单实例。因此Step into refresh中,源代码如下
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//Spring解析XML配置文件,将要创建的所有Bean的配置信息保存起来
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//准备Spring容器中自己的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//初始化所有单实例的Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
(2)finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
(3)beanFactory.preInstantiateSingletons();
(4)getBean(beanName);创建Bean → doGetBean(name,null,null.false);
BeanFactory和ApplicationContext的区别
ApplicationContext是BeanFactory的子接口
BeanFactory:bean工厂接口,负责创建Bean实例。容器里面保存所有单实例Bean,因此容器本质上是一个map
ApplicationContext是容器接口,更多的是负责容器的功能实现(可以基于BeanFactory创建好的对象之上完成强大的容器)
容器可以从map中获取bean,并且AOP DI在 ApplicationContext接口下的类中。
Spring最大的模式就是工厂模式。工厂模式的理解:给一个创建的相关信息,然后交给工厂,工厂会根据提供的信息来创建符合条件的对象。