IOC容器基本分成BeanFactory和ApplicationContext两类
BeanFactory是基本,ApplicationContext多用在框架
继承结构如图:
这里写图片描述

BeanFactory接口方法

/*
* 根据bean的名字获取Bean
*/
Object getBean(String name) throws BeansException;

/*
* 根据bean的名字获取Bean
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;

/*
* 根据bean的名字获取Bean
*/
<T> T getBean(Class<T> requiredType) throws BeansException;

/*
* 根据bean的名字获取Bean
*/
Object getBean(String name, Object... args) throws BeansException;

/*
* 根据bean的名字获取Bean
*/
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

/*
* 根据bean的名字判断是否含有指定的bean
*/
boolean containsBean(String name);

/*
* 根据bean的名字判断是否是SingleTon的bean,在BeanDefinition中指定
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

/*
* 根据bean的名字判断是否是SingleTon的bean,在BeanDefinition中指定
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

/*
* 根据bean的名字查询Bean是否是特定的Class类型
*/
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

/*
* 根据bean的名字查询Bean是否是特定的Class类型
*/
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

/*
* 根据bean的名字查询Bean的类型
*/
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

/*
* 根据bean的名字查询指定名字Bean的所有别名,在BeanDefinition中指定
*/
String[] getAliases(String name);

BeanFactory读取配置过程

1、创建Resource类,这个就是读取配置文件的类
2、创建BeanFactory
3、创建BeanDefinition的读取器,比如XmlBeanDefinitionReader,创建一个回调给BeanFactory
4、利用读取器的方法读取配置,比如loadBeanDefinitions
XmlBeanFactory :

public class XmlBeanFactory extends DefaultListableBeanFactory {

    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);
    }
}

ApplicationContext设计原理

作为一个应用上下文,只需实现两个功能:
1、实例化这个上下文的支持,同时启动IOC容器的refresh方法
FileSystemXmlApplicationContext中:

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {

    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

2、如何加载Xml的Bean定义资源
FileSystemXmlApplicationContext中:

@Override
protected Resource getResourceByPath(String path) {
    if (path != null && path.startsWith("/")) {
        path = path.substring(1);
    }
    return new FileSystemResource(path);
}

这里写图片描述

IOC容器的初始化

1、Resource定位
找到配置文件,类路径:ClassPathResource;文件系统:FileSystemResource
2、BeanDefinition载入
把用户定义好Bean表示成IOC内部数据结构,BeanDefinition
3、向IOC容器中注册BeanDefinition
通过BeanDefinitionRegistory将BeanDefinition注入到一个HashMap中,IOC容器通过HashMap持有这些Bean

如果Bean的LazyInit属性是True,那么容器初始化就是Bean的依赖注入

BeanDefinition定位

需要一个Resource来定位容器使用的BeanDefinition
Spring 通过 BeanDefinitionReader读取Resource
ClassPathXmlApplicationContext可以从classPath中读取配置
XmlWebApplicationContext可以从web容器中载入配置
FileSystemXmlApplicationContext可以从文件系统中载入Resource

准备精通下Spring源码和设计思想

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐