Spring IoC Q&A

Q:说说@Autowired@Resource的区别

  • @Resource:该注解会优先通过bean的名称而不是类型来寻找依赖。如果你趋向于使用bean名称来配置基于注解驱动的注入,请尽量不要使用@Autowired,虽然可通过@Qualifier来指定bean的名称,你应该尝试使用@Resource。
  • @Autowired:@Autowired应用于属性、构造函数以及多参函数,配合@Qualifier一起使用可以定位bean;而@Resource只支持属性、单参数的属性setter方法。所以如果你的配置目标是构造函数或者多参方法,请使用@Autowired和@Qualifier。

Q:IoC容器的Bean生命周期

image-20191116162720255

Q:介绍下IoC容器初始化流程

IoC容器的初始化过程,主要就体现在AbstractApplicationContextrefresh()方法中,如下:

image-20191117200601820

Q:说说IoC容器的架构设计

以FileSystemXmlApplicationContext为例子说明:

image-20191103175710896

  • BeanFactory:定义了基本的IoC容器规范,包含containsBean, getBean, getBeanProvider, isPrototype, isSingleton等基本的IoC容器方法;

    • AutowireCapableBeanFactory:在BeanFactory基础上实现了对存在实例的管理.可以使用这个接口集成其它框架,捆绑并填充并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用;一般应用开发者不会使用这个接口,所以像ApplicationContext这样的外观实现类不会实现这个接口,如果真想使用,可以通过ApplicationContextgetAutowireCapableBeanFactory接口获取;
    • HierarchicalBeanFactory:提供父容器的访问功能;至于父容器的设置,需要ConfigurableBeanFactory的setParentBeanFactory;
    • ListableBeanFactory:提供容器中bean迭代的功能,不再需要一个个bean地查找;
    • ConfigurableBeanFactory:同时继承了HierarchicalBeanFactory 和 SingletonBeanRegistry 这两个接口,BeanFactory的配置接口,被大部分BeanFactory实现,包含了配置BeanFactory的各种工具方法;
    • ConfigurableListableBeanFactory:接口的集大成者,同时继承了3个接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,同时提供了解析和修改bean definitions的方法,以及预实例化singletons;
    • DefaultListableBeanFactory:作为一个默认的功能完整的IoC容器来使用,是接口ConfigurableListableBeanFactory和BeanDefinitionRegistry的默认实现。工厂中的Bean都是基于元数据定义的 bean 和通过post-processors扩展的bean;
  • Resource是Spring用来封装I/O操作的类;

  • ApplicationContext是一个高级形态意义的IoC容器:

    • 支持不同的信息源:继承接口Messagesource;
    • 访问资源:继承接口ResourceLoader;
    • 支持应用事件:继承接口ApplicationEventPublisher;
    • 在ApplicationContext中提供附加功能;
  • ConfigurableApplicationContext:一个SPI接口,大部分ApplicationContext都实现了这个接口,提供了配置ApplicationContext的方法。其中容器启动过程调用的refresh方法就在这个接口定义;

  • AbstractApplicationContext:其中refresh()方法的具体实现在这个抽象类中,这个refresh()方法会涉及到IoC容器启动的一系列负载操作,针对不同的容器实现,这些操作都是类似的。

  • AbstractXmlApplicationContext:在AbstractXmlApplicationContext中做的操作就是对applicationContext.xml的解析操作,主要是由两个函数loadBeanDefinitions(DefaultListableBeanFactory beanFactory)loadBeanDefinitions(XmlBeanDefinitionReader reader)中实现;

  • FileSystemXmlApplicationContext:指定了获取Resource的方式,通过以下方法:

    • 1
      2
      3
      4
      5
      6
      7
      @Override
      protected Resource getResourceByPath(String path) {
      if (path.startsWith("/")) {
      path = path.substring(1);
      }
      return new FileSystemResource(path);
      }

      可以发现,这里依赖于FileSystemResource这个类。

Q:Spring IoC容器中提现了哪些设计模式,或者软件设计思想

1、实例化Bean使用了策略模式

与传统的策略模式不太一样,SimpleInstantiationStrategy.instantiate()为实例化入口,如果是接口实现,则调用子类的实例化方法CglibSubclassingInstantiationStrategy.instantiateWithMethodInjection

image-20191103160552022

2、接口隔离原则

客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上

清晰地定义了如下的体系:

  根接口BeanFactory(基础容器)

  第二层: 第三方集成 AutowireCapableBeanFactory ,继承体系 HierarchicalBeanFactory ,遍历bean ListableBeanFactory

  第三层: 配置功能 ConfigurableBeanFactory

  第四层: 配置+迭代 ConfigurableListableBeanFactory

3、事件驱动架构

IoC架构设计图里面,我们重点关注ApplicationEventPublisher以及事件发布机制相关的类:

image-20191113222101561

这里采用了事件驱动架构。关于具体的时间驱动模型以及Spring的事件驱动实现原理参考:事件驱动模型与观察者模式

4、模板方法模式

Spring的容器启动流程涉及的refresh方法使用了模板方法模式。

References

Spring源码解析 - BeanFactory接口体系解读

Spring源码学习–AutowireCapableBeanFactory接口

Spring源码学习–HierarchicalBeanFactory接口

Spring源码学习–ListableBeanFactory接口

Spring源码学习–ConfigurableBeanFactory接口

深入理解SPI机制

Spring源码学习–AbstractXmlApplicationContext抽象类

Spring IoC:invokeBeanFactoryPostProcessors 详解

spring4.2.9 java项目环境下ioc源码分析 (十三)——refresh之initApplicationEventMulticaster方法

arthinking wechat
欢迎关注itzhai公众号
  • 本文作者: arthinking
  • 本文链接: spring-ioc-q-a.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!