1 SpringIOC 初始化总结

发布于 2022年 02月 09日 04:22

1 IOC容器的初始化步骤

  • Resource资源定位
    • 定位Bean的资源
  • BeanDefinition的载入和解析
    • BeanDeginitionReader 对Resource资源的读取和解析,也就是将用户定义的Bean 表示成IOC容器内部数据结构,BeanDefinition 在IOC容器内维护这一个BeanDefinition Map的数据结构
  • BeanDefinition的注册
    • 向IOC容器注册在第二部解析好的BeanDefinition, 通过BeanDefinitionRegistery 接口实现,IOC容器通过一个HashMap来装载第二步中解析得到的BeanDefinition,但是此时并没有完成依赖注入,而是在第一次调用getBean()的时候

实际代码

ClassPathResource resource = new ClassPathResource("bean.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);

这几行代码都是什么意义呢

  • ClassPathResource resource = new ClassPathResource("bean.xml"); 根据xml文件创建Resource资源对象,其中ClassPathResource是Resource的子类
  • DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); 创建一个BeanFactory, DefaultListableBeanFactory 是BeanFactory的一个子类,是IOC的始祖

* XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); 创建一个读取器,用于载入BeanDefinition * reader.loadBeanDefinitions(resource);开始载入和注册bean,完成后放入IOC容器中

3 Resource定位

为了解决资源定位的问题,Spring提供了2个接口

  • Resource ,spring的统一资源抽象接口
  • ResourceLoader, spring的 资源加载的统一抽象

需要注意的是 Resource 和 ResourceLoader 需要配合使用,比如上面那段代码是合适初始化ResourceLoader呢?我们看看XmlBeanDefinitionReader的 构造方法

  public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
        super(registry);
    }

发现是调用父类的构造方法,继续追踪到 AbstractBeanDefinitionReader

protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        this.registry = registry;

        // Determine ResourceLoader to use.
        if (this.registry instanceof ResourceLoader) {
            this.resourceLoader = (ResourceLoader) this.registry;
        }
        else {
            this.resourceLoader = new PathMatchingResourcePatternResolver();
        }

        // Inherit Environment if possible
        if (this.registry instanceof EnvironmentCapable) {
            this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
        }
        else {
            this.environment = new StandardEnvironment();
        }
    }

如果设置了ResourceLoader,就使用设置的,否则使用PathMathingResourcePatternResolver

4 BeanDefinition的载入和解析

推荐文章