文章目录
-
-
- 1.spring IOC核心体系结构
- 2.IOC容器初始化
-
- 2.1 XmlBeanFactory(屌丝IOC)流程
- 2.2 FileSystemXmlApplicationContext的IOC容器流程
-
- 2.2.1 高富帅版IOC解剖
- 2.2.2 设置资源加载器和资源定位
- 2.2.3 AbstractApplicationContext的refresh函数载入Bean定义过程
- 2.2.4 AbstractApplicationContext的obtainFreshBeanFactory()
- 2.2.5 AbstractRefreshableApplicationContext子类的loadBeanDefinitions方法
- 2.2.6 AbstractBeanDefinitionReader的loadBeanDefinitions方法
- 2.2.7 DefaultResourceLoader的getResource方法
- 2.2.8 XmlBeanDefinitionReader的loadBeanDefinitions
- 2.2.9 DocumentLoader的loadDocument方法
- 2.2.10 XmlBeanDefinitionReader的registerBeanDefinitions方法
-
1.spring IOC核心体系结构
1.1 BeanFactory
Spring Bean的创建典型是工厂模式,这些Bean工厂(IOC容器)为管理对象间的依赖关系提供了便利和基础服务,Spring有许多IOC容器实现,相互关系如下:
>最顶层接口类BeanFactory,定义IOC容器的基本功能规范。
它有三个子类:ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory。
上图最终的默认实现类是DefaultListableBeanFactory,它实现了所有接口。为何定义这么多层次的接口?每个接口都有使用场合,为区分Spring内对象的传递和转化过程中,对对象的数据访问所做的限制。
eg.ListableBeanFactory接口:可列表,HierarchicalBeanFactory:有继承关系(每个Bean有可能有父Bean),AutowireCapableBeanFactory:自动装配规则。这四接口定义了Bean的集合、Bean之间的关系、以及Bean行为。
- 最基本的IOC容器接口BeanFactory
//org.springframework.beans.factory.BeanFactory
public interface BeanFactory {
/**使用转义符&来得到FactoryBean本身,用来区分通过容器获得FactoryBean本身和其产生的对象**/
String FACTORY_BEAN_PREFIX = "&";
//通过name来获取IOC容器指定的bean
Object getBean(String name) throws BeansException;
//根据名字和类型来得到bean实例,增加了类型安全验证机制
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
//通过类型获取bean实例
<T> T getBean(Class<T> requiredType) throws BeansException;
//增加更多获取的条件,同上方法
Object getBean(String name, Object... args) throws BeansException;
//判断IOC容器是否含有指定名字的bean
boolean containsBean(String name);
//查询指定名字的Bean是不是单例的Bean
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//判断Bean是不是prototype类型的bean
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
//查询指定了名字的Bean的Class类型是否与指定类型匹配
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
//获取指定名字bean的Class类型
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
//查询指定了名字的bean的所有别名,这些别名都是在BeanDefinition中定义的
String[] getAliases(String name);
}
只定义IOC容器的基本行为,不关心Bean如何定义、加载。(类比我们只关心工厂产品,不关心生产流程)
工厂如何产生对象?看具体IOC容器实现——eg.XmlBeanFactory,ClasspathXmlApplicationContext等。
XmlBeanFactory实现最基本的IOC容器(可读取XML文件定义的BeanDefinition(XML文件中对bean的描述))。
- 类比:XmlBeanFactory——容器中的屌丝,ApplicationContext——容器中的高帅富。
ApplicationContext一个高级IOC容器,除了提供IOC容器的基本功能外,还提供如下附加服务:
1.支持信息源,可实现国际化(MessageSource);
2.访问资源(ResourcePatternResolver);
3.支持应用事件(ApplicationEventPublisher)。
1.2 BeanDefinition
IOC容器管理各种Bean对象及其相互关系,Bean对象以BeanDefinition描述,其继承体系如下:
Bean解析过程非常复杂,功能很细,需被扩展很多,必须保证足够的灵活性。Bean的解析主要是对配置文件的解析。这个解析过程主要通过下图中的类完成:
2.IOC容器初始化
IOC容器初始化:BeanDefinition的资源定位、载入和注册。以ApplicationContext为例(XmlWebApplicationContext、ClasspathXmlApplicationContext等皆属该继承体系):
ApplicationContext允许上下文嵌套,通过保持父上下文可维持一个上下文体系。Bean可在上下文体系中查找:①检查当前上下文;②父上下文,逐级向上(为不同的Spring应用提供共享的Bean环境)。
2.1 XmlBeanFactory(屌丝IOC)流程
// org.springframework.beans.factory.xml.XmlBeanFactory
public class XmlBeanFactory extends DefaultListableBeanFactory {
// this传的是factory对象
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
- 直观表达源码意图:定位、载入、注册的全过程
// 根据xml文件,创建resource资源对象(包含BeanDefinition信息)
ClassPathResource resource = new ClassPathResource("applicantion-context.xml");
// 创造DefaultListableBeanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 创建读取器,用于载入BeanDefinition
// 需要BeanDefinition做为参数——会将读取的信息回调配置给factory
// XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this)中的this传的是factory
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
// 执行载入的BeanDefinition方法,最后完成bean的载入和注册
// 完成后bean成功放置到IOC容器中
reader.loadBeanDefinitions(resource);
2.2 FileSystemXmlApplicationContext的IOC容器流程
2.2.1 高富帅版IOC解剖
// org.springframework.context.support.FileSystemXmlApplicationContext
public FileSystemXmlApplicationContext(String... configLocations) throws BeansException {
this(configLocations, true, null);
}
// 实际调用构造函数
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
2.2.2 设置资源加载器和资源定位
创建FileSystemXmlApplicationContext容器时,构造方法做两项重要工作:
①调用父类容器的构造方法(super(parent)方法)为容器设置好Bean资源加载器;
②调用父类AbstractRefreshableConfigApplicationContext的setConfigLocations(configLocations)方法设置Bean定义资源文件的定位路径。
通过追踪FileSystemXmlApplicationContext的继承体系,发现其父类的父类AbstractApplicationContext中初始化IOC容器所做的主要源码如下:
// org.springframework.context.support.AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
// 静态初始化块,在整个容器创建过程中只执行一次
static {
// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
// 为了避免应用程序在Weblogic8.1关闭时出现类加载异常加载问题,加载IOC容器关闭事件(ContextClosedEvent)类
ContextClosedEvent.class.getName();
}
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
// FileSystemXmlApp