分类 标签 存档 社区 博客 友链 GitHub 订阅 搜索

Spring IOC

280 浏览

ZERO

    持续更新 请关注:https://zorkelvll.cn/blogs/zorkelvll/articles/2018/11/18/1542542741019

背景

     本文主要是记录在学习 Spring IOC 容器过程中的一些知识点总结!

关键词:工厂方法模式、反射机制

一、Spring

   Spring 是一个开源的、轻量级的 J2EE 开发框架,核心思想是 IOC 实现松耦合,利用 AOP 将应用的业务逻辑与系统服务分离。

二、Spring IOC

      实现原理:工厂模式 + 反射机制

      把 IOC 容器的工作模式看做是工厂模式的升华,可以把 IOC 容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言提供的反射机制,根据配置文件中给出的类名生成相应的对象。从实现来看,IOC 是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。

     IOC 控制反转:就是应用本身不负责所依赖对象的创建和维护,而是由外部容器对依赖对象进行创建和维护,这种对依赖对象的控制权转移到了外部容器,称之为控制反转;(-> 也就是说一个对象依赖的其他对象会通过被动的方式传递进来,而不是这个对象自己创建或查找依赖对象;;可以理解 IOC 与 JNII 相反,不是对象从容器中查找依赖,而是容器在对象初始化时不等到对象请求时就主动将依赖传递给它)

    DI 依赖注入:与 IOC 相应地会出现一个依赖注入的概念,指在应用程序运行期间,由外部容器动态地将依赖对象注入到组件中,一般通过构造函数或 setter 传递或接口传递

    Spring IOC 容器原理:就是 spring 在启动时,会读取应用程序所提供的 Bean 配置信息,并在 Spring 容器中对应生成一份 Bean 配置注册表,然后根据该注册表实例化 Bean,和装配好 Bean 之间的依赖关系;然后将 Bean 实例放到 Spring 容器的 Bean 缓存池(HashMap 实现)中,最终支撑上层应用的运行!

简言之,就是 Spring 在启动的时候,通过一个配置文件描述 Bean 和 Bean 之间的依赖关系,并生成相应的配置注册表,然后利用 java 语言的反射机制实例化 Bean 及建立 Bean 之间的依赖关系

    反射是 Java 语言的一个特性,它允许程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作

IOC 容器初始化过程

     定位 Resource 资源:由 ResourceLoader 通过统一的 Resource 接口完成对 Resource 外部资源的定位,也即 BeanDefinition 的资源定位

    载入 BeanDefinition:由 BeanDefinitionReader 读取、解析定位的 Resource 资源,也即将用户定义好的 Bean 表示成 IOC 容器的内部数据结构 BeanDefinition

   注册:通过 BeanDefinitionRegistry 接口,向 IOC 容器注册上一步中载入的 BeanDefinition(其实是一个 HashMap 进行管理的),IOC 容器通过 HashMap 数据结构对 BeanDefinition 进行维护管理

   依赖注入:是发生在在应用第一次调用 getBean(BeanFactory 接口的方法)时向容器获取 Bean 时进行依赖注入的,若某个 Bean 设置 lazyinit 属性,则该 Bean 在容器初始化时就会被依赖注入

Spring 容器 - Spring 容器分为两类

    BeanFactory:最常用的 BeanFactory 实现就是 XmlBeanFactory 类,它根据 XML 文件中的定义加载 beans,该容器从 XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用,BeanFactory 是 Spring 框架的基础设施面向 Spring 本身;
    ApplicationContext 应用上下文:基于 BeanFactory 之上构建,并提供面向应用(Spring 框架的开发者)的服务

    关系:ApplicationContext 由 BeanFactory 派生,通过该类很多功能可以直接通过配置方式实现(而在 BeanFactory 中则需要以编程方式实现)

SpringIOC 容器中重要的实现类

    BeanDefinition:Spring配置文件中每一个节点元素均对应容器中国的一个 BeanDefinition 对象,描述 Bean 的配置信息;

    BeanDefinitionRegistry:该接口提供向容器手动注册 BeanDefinition 对象的方法;

    ListableBeanFactory:该接口定义了访问容器中 Bean 基本信息的若干方法,如 Bean 个数、某一类型 Bean 的配置名、是否包含某一 Bean 等;

    HierarchicalBeanFactory:该接口提供子容器可访问父容器中 Bean的功能,也即通过该接口 SpringIOC 容器可以建立父子级联的容器体系(如 SpringMVC 中表现层 Bean 位于一个子容器中,业务层和持久层位于父容器中,因此表现层 Bean 可以引用业务层和持久层的 Bean,而业务层和持久层不能使用表现层 Bean);

    ConfigurableBeanFactory:该接口用于增强 Ioc 容器的可定制性,提供设置类装载器、属性编辑器、容器初始化后置处理器等方法;

    AutowireCapableBeanFactory:该接口定义了可将容器中 Bean 按照某种规则(如名字匹配、类型匹配)进行自动装配的方法;

    SingletonBeanRegistry:该接口提供运行期间向容器注册单例实例 Bean的方法;

三、SpringMVC - WebApplicationContext

     WebApplicationContext 是专门为 Web 应用准备的(必须在拥有 web 容器的前提下才能完成启动工作),允许从相对于 Web 根目录的路径中装载配置文件完成初始化工作。

     启动过程:

    web 容器如 tomcat -> web.xml(配置自启动的 Servlet 或定义 Web 容器监听器) -> Servlet 如 ContextLoaderServlet,也即在 tomcat 中创建一个 ServletContext 实例(用于启动 WebApplicationContext) -> WebApplicationContext 中引用 ServletContext 并将整个应用的 Spring 上下对象 WebApplicationContext 作为属性(以 ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 为键)放在 ServletContext 中 -> 因而 web 容器可以通过 ServletContext 实例获取到 Spring 上下文对象

    Spring 中分别提供了用于启动 WebApplicationContext 的 Servlet 或 web 容器监听器:

    org.springframework.web.context.ContextLoaderServlet

    org.springframework.web.context.ContextLoaderListener   

参考:

1、SpringIOC 原理总结

评论  
留下你的脚步
推荐阅读