0%
这是一片思考的空间 -- arthinking
Spring 重构&代码整洁之道 软件设计 JVM 并发编程 数据结构与算法 分布式 存储 网络 微服务 设计模式
Java技术栈 - 涉及Java技术体系

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方法

欢迎关注我的其它发布渠道

订阅IT宅
内功修炼
Java技术栈
Java架构杂谈是IT宅精品文章公众号,欢迎订阅:
📄 网络基础知识:两万字长文50+张趣图带你领悟网络编程的内功心法 📄 HTTP发展史:三万长文50+趣图带你领悟web编程的内功心法 📄 HTTP/1.1:可扩展,可靠性,请求应答,无状态,明文传输 📄 HTTP/1.1报文详解:Method,URI,URL,消息头,消息体,状态行 📄 HTTP常用请求头大揭秘 📄 HTTPS:网络安全攻坚战 📄 HTTP/2:网络安全传输的快车道 📄 HTTP/3:让传输效率再一次起飞 📄 高性能网络编程:图解Socket核心内幕以及五大IO模型 📄 高性能网络编程:三分钟短文快速了解信号驱动式IO 📄 高性能网络编程:彻底弄懂IO复用 - IO处理杀手锏,带您深入了解select,poll,epoll 📄 高性能网络编程:异步IO:新时代的IO处理利器 📄 高性能网络编程:网络编程范式 - 高性能服务器就这么回事 📄 高性能网络编程:性能追击 - 万字长文30+图揭秘8大主流服务器程序线程模型
📄 Java内存模型:如果有人给你撕逼Java内存模型,就把这些问题甩给他 📄 一文带你彻底理解同步和锁的本质(干货) 📄 AQS与并发包中锁的通用实现 📄 ReentrantLock介绍与使用 📄 ReentrantReadWriteLock介绍与使用 📄 ReentrantLock的Condition原理解析 📄 如何优雅的中断线程 📄 如何优雅的挂起线程 📄 图解几个好玩的并发辅助工具类 📄 图解BlockingQueue阻塞队列
📄 消息队列那么多,为什么建议深入了解下RabbitMQ? 📄 高并发异步解耦利器:RocketMQ究竟强在哪里? 📄 Kafka必知必会18问:30+图带您看透Kafka
📄 洞悉MySQL底层架构:游走在缓冲与磁盘之间 📄 SQL运行内幕:从执行原理看调优的本质 📄 洞悉Redis技术内幕:缓存,数据结构,并发,集群与算法